Welcome to William(Hao) Chen's world!

A geek with Electronics & Electrical Engineering and Computing & ICT academic background

Test Driven Development

An efficient software development process for software developers is crucial, it determines the development is a painful struggle, or joy progressive. Some of the recent rise of the software development process-related technology to provide some of the more efficient and practical process of software development methods. The one of the worthiest of attention is Test Driven Development.

So in this article, I will introduce what the TDD is,  comparison with other methodology, TDD’s process, TDD’s advantage and disadvantage and why we use TDD.

I hope to give an overview of exactly what test-driven development is and the conception of the test-driven development.

What is TDD

TDD is test-driven development (Test-Driven Development) abbreviation, it created by Kent Beck, with having developed or ‘rediscovered’ (L. Williams, October) the technique, is agile development of a core practices and technologies, but also a design methodology. TDD principle is prior to the development of functional code to write unit test code, test code to determine what products need to write code. Although TDD is the core practice of Agile methods, but are not suitable for XP (Extreme Programming), it can also be applied to other development methods and processes.

The basic idea is to pass the test TDD to drive the entire development proceeds, but the test-driven development is not just a simple testing, but the requirements analysis , design, quality control quantization process.

TDD is not only an important purpose test software, testing to ensure the quality of the code is only part of it, but also help customers and programmers need to remove ambiguities in the development process. TDD first consider the demand for the use (objects, functions, processes, interfaces, etc.), mainly to write test framework for process design and interface functions, and test framework can continue to be verified.

 

Traditional and Test Driven Development Compared

 

tdd

(Ambysoft, 2003)

At the following diagram shows the biggest differences between traditional and test driven development processes.

As the above diagrams show, the key difference between the two approaches is simply the test first nature of TDD. In the traditional process, you do not write your tests until after completing the full implementation. Thus, testing is primarily a verification that the code works as intended; it does not help the developer in their work. Since TDD starts with testing and incorporates testing as a part of the development process, the tests actually help the developer and will generally improve the quality and design of the code.

TDD is a programming technique originally, it indirectly makes sure your code can be unit tested thoroughly checked. However, it can do more than this. You still need to refer to some of the traditional testing such as functional testing, user acceptance testing, system integration testing, and so on.

The process of TDD

At following, I would like to describe how TDD actually works, how does a developer accept and begin to start TDD process in their work.

Step one: Write a failing test

A TDD professionals began by extracted from system requires a specific function. Once when a particular function is determined, the developers will write an automated test, for the test it will test a specific function. Developers need to create and test, after that, they will write a short code to test the code simply run. Of course, since the actual function has not been developed, the test will initial fail. The test of the initial fault is an important aspect of TDD; this is the beginning of each TDD test.

Step two: Write the code so the test passes

After a failing automated test is completed, the developer will write the code to carry out the function. When the developer works on the code, the good things is, they can implement the automated test at any time to check if their code is working. This gives the developer immediate feedback, when test failure developers have a very good opportunity to debug, they can quickly find errors and repair it. The developer continues to test their code until their automated test is passing. When the test is passing which means the code is correct, we have to say TDD is very efficient, and when the function operation successful, the developers will be more confidence at the following work.

Step three: Refactor

Refactoring is all tests have to undergo the steps; the developer had already created the code and the code needs to be refactored. To be honest, refactor not always a required; however, sometimes people always make a few mistakes more or less, after all, who can guarantee that his every decision is right. In order to prevent that mistake occurrence, so once the test is passed, the developer should go back and use a good design to properly implement the reconstruction of their code. Throughout refactoring process, developers can run and run automated tests many times to make sure they do not destroy the required functionality.

Step four: Repeat

Once the programmer has a test that is passing and they have clean and refactored code, they can then move on to the next function and proceed in the same manner. As the programmer progresses through all the required functions of the application, they will ultimately develop the actual working application. A real benefit of TDD comes with this, as they will simultaneously be completing a full test suite for the application with complete test coverage. It is very rare that a programmer will go back to their code and write tests for everything after having a fully implemented application. Complete test suite code coverage is simply a natural by-product of the TDD process and it is one that should not be underestimated.

Benefits of TDD

The benefits of using TDD are wide reaching and very compelling. In the paper Test driven development: empirical body of evidence, the following is stated, (Boehm, 1981)“TDD may help to improve software quality significantly, in terms of decreased fault rates, when employed in an industrial context.” As this article collects and summarizing 13 empirical research from industry, which is backed by facts quite a dramatic conclusion.

In an article entitled, Does Test-Driven Development Really Improve Software Design Quality, (Saiedian, 2008) the authors document how TDD contributes to better code. The article shows that code produced through TDD is generally better organized into smaller and well-designed units that are better tested. Such code not only is better from its initial release, but it is easier and less costly to maintain and adapt in the future.

Overall, you can find many articles and reports that list the many purported benefits of using a TDD process in your software development. Some of these benefits are as follows:

  • Less software defects: since TDD produces code that is much more highly tested, the resulting software is normally low rate to defects.
  • Fast feedback to the programmer: the feedback gave to the software developers during the TDD process in short cycle so they can respond and change the error quickly. All a developer needs to do in order to find out if their code works is just run the tests.
  • Increased developers confidence: Since all the code is covered by tests that, ensure it works as expected; developers have more confidence in their own code.
  • Enables refactoring: since total test coverage is needed to refactor code, by doing TDD you are creating code that can easily be refactored.
  • Cleaner and simpler designs: the code produced by TDD has been shown to be generally cleaner and simpler than code produced through a more traditional method. This ultimately produces code that is easier and less expensive to maintain.
  • Reduced debugging time: Test-driven development offers more than just simple validation of correctness, but can also drive the design of a program. By focusing on the test cases first, one must imagine how clients (in the first case, the test cases) will use the functionality. Therefore, the programmer is only concerned with the interface and not the implementation.

Overall, these quite substantial benefits should at the very least pique the interest of developers. Embracing a TDD process does require quite a radical shift in the thinking of developers but these benefits show that the effort required to do so is likely worth it.

Disadvantage of TDD

  1. Test-driven development does not perform in need all functional testing, to determine the success or failure, because of the extensive use of the unit test cases fully test. These examples are user interface, with database and some working procedure depends on the specific network configuration. TDD encourages developers to code for the minimum amount of such modules, and maximize the logic is in the test library code.
  2. Management support is essential. If not the entire organization think test-driven development is to improve product, management may feel that take time to write tests was wasted.
  3. High digital unit tests could lead to false sense of security, so as to reduce the additional software testing activities, such as integration testing and conformance testing.
  4. Tests as part of a project maintenance overhead. Write bad tests, such as those including hard coding error string or itself is prone to failure, are maintenance is expensive. This is especially the case with fragile test. Yes, test on a regular basis to produce false failure will be ignored, therefore, when a fault occurs, the real risk it may not be able to be detected. Possible by mistake the reuse of the string to write as low, easy to maintain test, for example, it should be in the above code-refactoring phase of the target.

TDD and ATDD

bdd

TDD and ATDD

Compere with TDD, Acceptance Test Driven Development (ATDD) is a practice in which the whole team cooperation discusses acceptance criteria, with examples, and then distils them into a set of concrete acceptance tests before development begins. It is the best way to ensure that all developer have the same shared understanding of what it is their actually building. It is also the best way to ensure we have a shared definition of done.

TDD and BDD

bdtd

TDD and BDD

BDD refers Behavior Drive Development, that is, behavior-driven development. Here B is not referring to the Business, in fact, BDD can be seen as a supplement to the TDD, of course, you can also see it as a branch of TDD. Because in the TDD, we can not guarantee based on design written test is the user desired function. BDD this part is simple and naturalization, using natural language to describe, let the development, testing, BA and customers can reach agreement on this basis. Because the concept is not everyone can accept the test-first, some people may feel that the system is too complex and difficult to test, some people think that what does not exist can not be tested. So, here we are trying to convert an idea, and that is to consider its behavior, that is how it should be run, and can reach a consensus abstract norms.

TDD DEVELOPMENT STYLE

With all aspects of using test-driven development. By focusing on writing only need to pass the test code, it can be designed using other methods to realize more clearly than usual, more clearly. (Beck, 2003 )

Implement some advanced design concepts, such as design, test, design will be generated. The code may still simpler than the target schema, but still by all of the required tests. This may be unsettling for the first time, but it allows developers to focus on what is important

Writing tests first. The function of the test should be tested before being written to. It is claimed that has two benefits. It helps to ensure that the application of testability, because developers must consider how to test the application from the start, rather than worry about later. It also ensures that for each functional test will be written to. When writing a function of the first code, there is a tendency by the developers and development organisation developer on the next function, ignore the test completely.

Test-driven development of advanced practice, may lead to the acceptance test driven Development (ATTD), in which the conditions specified by the customer is automatic acceptance testing, and then drive the traditional Unit Test Driven Development (UTDD) course. This process ensures that the customer has an automated mechanism to determine whether the software meets the requirement of them. As the ATDD, development team now has a specific target, in order to satisfy, acceptance testing, which makes them constantly focus on the customer from the user’s real story.

TDD use Case

xUnit

Developers can use computer aided testing framework, developers can use the xUnit framework provides assertions, type test and the ability to report the results. Because they get rid of the post-processing of independent activities are included in the burden of a test to perform these functions to perform validation is the key to automation. The execution of the test framework provides a framework allowing all system test cases automatically or subset, along with other functions. (Meszaros, 2016)

pyUnit

PyUnit is an easy way to create unit testing programs and UnitTests with Python.

Here is an example

yunit

PYUnit

Test-driven development (TDD) before adding a new code to make your test code wrong kind of development technologies. TDD soon Agile developers use to application source code development, will soon be agile DBA for database development. TDD can be used as complementary methods (AMDD) agile model-driven development and both can be used together. TDD can not replace the traditional test, on the contrary it is to define a way to ensure the effectiveness of the verification unit testing. Another effect of TDD is to test the code as a code example, it can provide coding standard for us. In my experience, TDD in the actual development of the excellent performance of hard to believe that many agile developers consider it.

 

Reference

Ambysoft. (2003). Introduction to Test Driven Development (TDD). Retrieved from Agile Data: http://agiledata.org/essays/tdd.html

Beck, K. (2003 ). “Test-Driven Development by Example”,. Addison Wesley.

Boehm, B. W. (1981). “Software Engineering Economics”. Prentice-Hall: Englewood Cliffs.

  1. Williams, E. M. (October, 1996 11). “Test-Driven Development. Proceedings of International Symposium on Software Reliability Engineering, pp. 66-75.

Meszaros, G. (2016, August 31). xUnit. Retrieved from Wikipedia: https://en.wikipedia.org/wiki/XUnit

Saiedian, D. S. (2008, March/April ). Does Test-Driven Development Really Improve Software Design Quality? I E E E S o f t w a r E, p. 77~83.

A good Agile Team

Agile methodology and scrum ideas are very popular nowadays. How to measure the agility of the team is being an important issue for IT managers and high-level executives.

images  “Shu Ha Ri” (Skip, 2011).

“Shu Ha Ri” are the basic learning methodology and rules for Japanese kendo learners to learn and measure skills levels in Kendo learning and practice. In the following years, this methodology is also applied to other martial arts learning process and team management activities. Similarly, “Shu Ha Ri” would be applied to agile team performance measurements. The details are as follows:

“Shu” means behave well according to the rules or principles those are known. From this point of view, we would observe whether the team could follow the scrum process to realize real agility. First, we would identify the three main roles in the team. Second, we would check whether the team could run agile activities (planning, daily meeting, review, etc.) on time.

“Ha” means break through. We would evaluate whether the team could break through some of the agile rules and add more valuable activities or process to the existing principle. Those rules or activities (such as code inspection) are all following the agile manifesto.

“Ri” means change. We have already followed the main agile activities and rules and the team has good understanding of the process and valuable experience. The team could be more agile to change the process or rules according to their own situation and needs. There are no limitation for team to behave. Agile member is becoming one with spirit alone without clinging to forms. It is more natural. All the changes about the agile process should follow the agile manifesto.

Now, let us use management knowledge to explain the idea into details.

  1. Is the team self-organized?

This standard would be the primary standard to evaluate the agility of the team. Here are the several questions to pay attention: Could the team hold the meeting on time and benefit from the meeting without the guide from scrum master or team leader? Are there any other team members paying attention to the quality of the product or the process without the reminding of scrum master or team leader? Are there any members be able to remind and correct the team activities if the team is going into the wrong way?

  1. Is the team improved continuously?

Here are the questions we can ask ourselves to identify the ability of self-continuous-improvement: 1.Is the number of bugs decreasing gradually? 2. Have we increased the testing coverage gradually? 3. Did we have more efficient meeting than before? 4. Did we add more techniques (automation deployment, automation testing) to help us improve working efficiency?

  1. Does the team have the ability to release on time? (daily, weekly or anytime)

It doesn’t mean the team has to release very often. The timeline would different
due to the specification of different projects and different organizational management strategy. However, if customer requires, the team should be able to handle the change to release rapidly under the company’s permission.

  1. Are the team members’ skills improved?

Agile means more efficient, not busier. If the team could work more efficient, the team members’ learning skills and working skills are improved. The problem-solving ability should be improved. The difficulties should be overcome quickly.

  1. Did our team members handle multiple problems at the same time?

In some situations, team members need to focus on certain task. In this way, the task could be finished quickly and the quality would be assured.

 

Reference

Skip. A. (May, 2011). Scrum from student to master. Retrieved from: https://www.scrumalliance.org/community/articles/2011/may/scrum-from-student-to-master

 

Unit Testing with JUnit

Nowadays, many programmers in IT industry may have many excuses for not writing Unit Tests. Some of them don’t know the way to write tests and some of them will assign the testing tasks to testers. Even some of them would not admit that their code are not perfect. No matter for developer or tester, doing unit testing is very significant to ensure the quality of the software during whole SDLC process. First, Unit Testing could reduce bugs in both new and existing features in early coding stage which means reducing the risks of the product release. Second, Unit tests could help the company reduce the cost of change. A well tested code could be used in the following stages, there will not be so much changes to fix the code. What is more, Unit tests are good documentation for reusing and API development example (Eric M. & Brian M, 2003) . Also, Unit testing could help developers improve design and development. TDD is very helpful for developers to develop product with good quality and requirements satisfaction. Therefore, Unit Testing would be great choice for IT heroes. Automation tools are available for Unit Testing under different IDE environment. The main advantage of automation unit test is to test and integrate the test issues quickly and efficiently. In the article, a sample java code is provided and JUnit would be used as the tool under Eclipse environment to do the Unit Testing. Findings of the Unit Testing would be discussed and future development suggestions would be provided for Q&A in the future.

Unit Testing

Unit testing is to test the basic component of the software. Function, method or class could be considered as the unit of the program. The unit could be considered as the smallest component of software development process. Unit testing process has two main procedures: static review and dynamic execution tracing.

Static review is the first procedure. In the process, the algorithm logics of the code would be checked. Testers would ensure the correctness, clarity, standardization and efficiency of the algorithm. The more defects discovered in the code, the lower the risks for the whole SDLC.

Executing the testing program to test the unit would be the second procedure. According to the test cases, looking for the defects by tracing and comparing the actual and expectable results.

Review:

(1) Verifying the correctness of the algorithm’s logic: Check whether the code could make the unit function well according to the requirements.

(2) Verifying the correctness of the module’s interface: Check whether the data structure, parameters and sequence are defined in the correct way. Make sure the return value is in the correct value and data type.

(3) Make sure whether the inputting data is checked: If the data is not checked, identify whether the data needs to be check. Check the data if it needs to be.

(4) Bugs processing: Identify the conditions for producing the bugs and find out the solutions to deal with the defects.

(5) Verify the correctness of the statement for code: Make sure all the mistakes of the logics and syntax would be discovered. Ensure the reliability of the code. Optimize the code and make it easier to understand.

(6) Check the use of different variables: Make sure to use the different variables with different data types and values in the correct way.

(7) Make sure the definition of the statement is standardized: The name of variables should be meaningful. Too long, too short and non-understandable names would make people confused. The names should be identified with related functionality. The meaning of names should not be duplicated or mixed.

(8) Make sure the coding style is standardized: Format and statement should be identified.

(9) Identify whether the algorithm could be optimized and reduce redundancy of the code.

(10) Check whether the code is easy to understand and make the code not too complicated.

(11) Check whether the comments of the methods are complete: Check whether the comments are clear and simplified. Make sure the reader could understand the functionality of the unit or module. Correct the wrong comments and delete the unnecessary comments if available.

Dynamic execution tracing:

Several issues should be taken into consideration for Unit Testing execution: (1) Test each independent path inside the module. (2) Test each logic decision making statement for all situation considerations, especially for Boolean logic. (3) Execute loop under the boundary value.

Purpose of Unit testing:

It is aimed to find internal defects in the module. Verify whether the code could meet the specification of the requirements. Tracing the defects of the designing requirements documentation. Looking for mistakes made during coding process and find solutions to improve coding quality and efficiency.

Scope

The documentation is used for introducing Unit Testing methodology and recording the Unit Testing findings for the given java sample code (methods: sorting increase, find maximum, and find average). Code analysis, test cases, automation code, testing results and optimization suggestions would be covered.

Objective

The main purpose for making the documentation are: 1.To have better understanding of Unit Testing. 2. Practice Junit with Eclipse java to test java sample code. 3. Help to record the defects and fix the bugs.

Module Description

An array A of N integer elements are provided, the functions need to realize are as followed as below:

1- sort the elements in an ascending order

2- find the maximum value

3- find the average of the elements

N is an integer in the range of [0 .. 100]

A elements are integers in the range [-1000 .. 1000]

Program Diagrams

Sorting

1

Selection sort. (Baidu, 2011).

Find Max

2

Finding the Largest Number in an Unsorted List of Numbers. (RFF Electronics, 2010).

Find Ave

3

Example flowchart 1: Find the result of addition of three numbers. What about their average? (Anik’s Codepen, 2011).

 

Code Inspection

public class OriginalCode {
/**
* User selection sort algorithm
*/
public int[] sortArr(int[] A, int N) {
int[] sA = A;
int swap;
for (int i = 0; i < N; i++) {
for (int j = i + 1; j < N; j++) {
if (sA[j] < sA[i]) {
swap = sA[j];
sA[j] = sA[i];
sA[j] = swap;
}
}
}
return sA;
}

According to the diagram, the sorting method might have logic statement errors.

public int findMax(int[] A, int N) {
int max = A[0];
for (int i = 0; i < N – 1; i++) {
if (max < A[i])
max = A[i];
}
return max;
}

public int findAvg(int[] A, int N) {
int sum = 0;
int avg = 0;
for (int i = 0; i < N; i++) {
sum = +A[i];
}
avg = sum / N;
return avg;
}

public static void main(String[] args) {
OriginalCode tProj = new OriginalCode();
int[] A = { 22, 3, 55, 4, 5, 88 };
int N = A.length;
?????????????

}
}

According to the diagram, findmax method might have errors in loop statement, findavg might have strange statement and the main method is not completed.

Automation Testing With JUnit

Refine the format of the code

Generally speaking, developing code under specific IDE environment would be great choice because the IDE would offer convenient functions for developers to transfer the code into formal standard format. Adding spaces properly in the code could be achieved by pressing “Ctrl+Shift+F” under Eclipse environment. In this way, the code would be more readable for each reviewer

Locate and get the methods embedded in the main method of the program which would be tested

Most of the functions would be achieved by the methods of the program. However, in the code, it is really inconvenient to test the existing methods by adding more inputting information and displaying possible results or returned information in the original code. It is not wise to rewrite the inputting information. In this situation, extracting the methods from the code would be implemented to show the logic independently in another file. In the new method, tester would be able to re-input different parameters to test the functionality of the logic without concerning any other issues.

Rewrite the process of testing method’s logic in Unit-test format

Repeating verifying the output of each method after changing the testing data and rerunning the testing process of the methods would be time-inefficient. By creating Junit-test case, automation of verification would be easily and efficiently implemented. Class for testing different components or modules would be built. Different sub-testing methods with different inputting data would be developed.

Converting the test cases into automation unit testing code

According to the test cases those have been developed before, sub-testing methods for specific components would be extended. Different “Assertion” statement would be used for different kinds of data structure and logics.

Integrating the test cases

The reuse of code and module would be very common issue for developers and testers. It is necessary to integrate the typical automated test cases for reusing. Integrated test cases would be easier and quicker to execute. Furthermore, integrated test cases would be significant for future sanity testing and regression testing consideration. In this way, Junit test suites would be created.

Test Cases

Sorting

Test Case ID Description Input Expected Output Actual Output Pass/Fail
S-1 The component will not sort with empty array {} {} {} P
S-2 The component will not sort with array contains one element {42} {42} {42} P
S-3 The component will sort correctly with array contains two elements {1,2} {1,2} {1,2} P
S-4 The component will sort with array contains two elements into inverse order {2,1} {1,2} {2,1} F
S-5 The component will sort correctly with array contains two same elements {2,2} {2,2} {2,2} P
S-6 The component will sort correctly with array contains three elements {1,2,3} {1,2,3} {1,2,3} P
S-7 The component will sort correctly(1st and 2nd swaped) with array contains three elements {2,1,3} {1,2,3} {2,1,3} F
S-8 The component will sort correctly(3rd and 2nd swaped) with array contains three elements {1,3,2} {1,2,3} {1,3,2} F
S-9 The component will sort with array contains three elements into inverse order {3,2,1} {1,2,3} {3,2,1} F
S-10 The component will sort correctly with array(contains elements with correct order) contains random elements {-3,0,1,5,9} {-3,0,1,5,9} {-3,0,1,5,9} P
S-11 The component will sort correctly with array(contains elements with incorrect order) contains random elements {9,-3,5,0,1} {-3,0,1,5,9} {9,-3,5,0,1} F

Unit Testing Code:

package testcases;

import org.junit.After;

import org.junit.AfterClass;

import org.junit.Assert;

import org.junit.Before;

import org.junit.BeforeClass;

import org.junit.Test;

import Code.TestingProj;

import static org.junit.Assert.assertArrayEquals;

import java.util.Arrays;

public class SortingTest {

@BeforeClass

public static void setUpBeforeClass() throws Exception {

System.out.println(“before sortingtest class”);

}

@Before

public void setUp() throws Exception {

System.out.println(“before test”);

}

@Test

public void shouldDoNothingWithEmptyArray() {

System.out.println(“test case should do nothing with empty array”);

int[] values = {};

int N = values.length;

TestingProj test = new TestingProj();

test.sortArr(values, N);

assertArrayEquals(new int[] {}, values);

}

@Test

public void shouldDoNothingWithOneElementArray() {

System.out.println(“test case should do nothing with one element array”);

int[] values = { 42 };

int N = values.length;

TestingProj test = new TestingProj();

test.sortArr(values, N);

assertArrayEquals(new int[] { 42 }, values);

}

@Test

public void sortCorrectOrderWithTwoElementArray() {

System.out.println(“test case sort correct order with two element array”);

TestingProj test = new TestingProj();

Assert.assertTrue(

Arrays.equals(new int[] { 1, 2 }, test.sortArr(new int[] { 1, 2 }, new int[] { 1, 2 }.length)));

}

@Test

public void sortInverseOrderWithTwoElementArray() {

System.out.println(“test case sort inverse order with two element array”);

TestingProj test = new TestingProj();

Assert.assertTrue(

Arrays.equals(new int[] { 1, 2 }, test.sortArr(new int[] { 2, 1 }, new int[] { 2, 1 }.length)));

}

@Test

public void sortCorrectOrderWithTwoSameElementArray() {

System.out.println(“test case sort correct order with two same element array”);

TestingProj test = new TestingProj();

Assert.assertTrue(

Arrays.equals(new int[] { 2, 2 }, test.sortArr(new int[] { 2, 2 }, new int[] { 2, 2 }.length)));

}

@Test

public void sortCorrectOrderWithThreeElementArray() {

System.out.println(“test case sort correct order with three element array”);

int[] values = { 1, 2, 3 };

int N = values.length;

TestingProj test = new TestingProj();

Assert.assertTrue(Arrays.equals(new int[] { 1, 2, 3 }, test.sortArr(values, N)));

}

@Test

public void sortFirstTwoSwapedWithThreeElementArray() {

System.out.println(“test sort first two swaped with three element array”);

int[] values = { 2, 1, 3 };

int N = values.length;

TestingProj test = new TestingProj();

Assert.assertTrue(Arrays.equals(new int[] { 1, 2, 3 }, test.sortArr(values, N)));

}

@Test

public void sortLastTwoSwapedWithThreeElementArray() {

System.out.println(“test sort last two swaped with three element array”);

int[] values = { 1, 3, 2 };

int N = values.length;

TestingProj test = new TestingProj();

Assert.assertTrue(Arrays.equals(new int[] { 1, 2, 3 }, test.sortArr(values, N)));

}

@Test

public void sortInversedOrderWithThreeElementArray() {

System.out.println(“test sort inversed order with three element array”);

int[] values = { 3, 2, 1 };

int N = values.length;

TestingProj test = new TestingProj();

Assert.assertTrue(Arrays.equals(new int[] { 1, 2, 3 }, test.sortArr(values, N)));

}

@Test

public void shouldSortValuesWithCorrectOrderRandomArray() {

System.out.println(“test sort correct order with any element array with any size”);

int[] values = { -3, 0, 1, 5, 9 };

int[] expectedOrder = { -3, 0, 1, 5, 9 };

int N = values.length;

TestingProj test = new TestingProj();

test.sortArr(values, N);

assertArrayEquals(expectedOrder, values);

}

@Test

public void shouldSortValuesWithIncorrectOrderRandomArray() {

System.out.println(“test sort incorrect order with any element array with any size”);

int[] values = { 9, -3, 5, 0, 1 };

int[] expectedOrder = { -3, 0, 1, 5, 9 };

int N = values.length;

TestingProj test = new TestingProj();

test.sortArr(values, N);

assertArrayEquals(expectedOrder, values);

}

@After

public void tearDown() throws Exception {

System.out.println(“after test”);

}

@AfterClass

public static void tearDownAfterClass() throws Exception {

System.out.println(“after sorttest class”);

}

}

Find Max

Test Case ID Description Input Expected Output Actual Output Pass/Fail
FM-1 The component will not work with array contains one element {2} 2 2 P
FM -2 The component will not work with array contains two equal elements {2,2} 2 2 P
FM -3 The component will find the max with array contains two unequal elements(1st is small) {1,2} 2 1 F
FM -4 The component will find the max with array contains two unequal elements(2nd is small) {2,1} 2 2 P
FM -5 The component will not work with array contains three equal elements {2,2,2} 2 2 P
FM -6 The component will find the max with array contains three unequal elements(1st large) {3,1,2} 3 3 P
FM -7 The component will find the max with array contains three unequal elements(2nd large) {1,3,2} 3 3 P
FM -8 The component will find the max with array contains three unequal elements(3rd large) {1,2,3} 3 2 F
FM -9 The component will find the max with array contains four elements(3rd large) {1,2,3,2} 3 3 P
FM -10 The component will find the max with array contains four elements(4th large) {1,2,3,8} 8 3 F

Unit Testing Code:

package testcases;

import static org.junit.Assert.*;

import org.junit.After;

import org.junit.AfterClass;

import org.junit.Before;

import org.junit.BeforeClass;

import org.junit.Test;

import Code.TestingProj;

public class Findmaxtest {

@BeforeClass

public static void setUpBeforeClass() throws Exception {

System.out.println(“before Findmaxtest class”);

}

@Before

public void setUp() throws Exception {

System.out.println(“before test”);

}

@Test

public void shouldDoNothingWithArrayWithSingleElement() {

System.out.println(“test case single element  array”);

int[] values = { 2 };

int N = values.length;

TestingProj test = new TestingProj();

int result = test.findMax(values, N);

assertTrue(Integer.valueOf(2) == result);

}

@Test

public void shouldDoNothingWithArrayWithTwoEqualElements() {

System.out.println(“test case double equal elements array”);

int[] values = { 2, 2 };

int N = values.length;

TestingProj test = new TestingProj();

int result = test.findMax(values, N);

assertTrue(Integer.valueOf(2) == result);

}

@Test

public void findMaxWithArrayWithTwoUnequalElementsFirstSmall() {

System.out.println(“test case double unequal elements array first small”);

int[] values = { 1, 2 };

int N = values.length;

TestingProj test = new TestingProj();

int result = test.findMax(values, N);

assertTrue(Integer.valueOf(2) == result);

}

@Test

public void findMaxWithArrayWithTwoUnequalElementsSecondSmall() {

System.out.println(“test case double unequal elements array second small”);

int[] values = { 2, 1 };

int N = values.length;

TestingProj test = new TestingProj();

int result = test.findMax(values, N);

assertTrue(Integer.valueOf(2) == result);

}

@Test

public void findMaxWithArrayWithThreeEqualElements() {

System.out.println(“test case three equal elements array “);

int[] values = { 2, 2, 2 };

int N = values.length;

TestingProj test = new TestingProj();

int result = test.findMax(values, N);

assertTrue(Integer.valueOf(2) == result);

}

@Test

public void findMaxWithArrayWithThreeElementsFirstLarge() {

System.out.println(“test case three elements array first large”);

int[] values = { 3, 1, 2 };

int N = values.length;

TestingProj test = new TestingProj();

int result = test.findMax(values, N);

assertTrue(Integer.valueOf(3) == result);

}

@Test

public void findMaxWithArrayWithThreeElementsSecondLarge() {

System.out.println(“test case three elements array second large”);

int[] values = { 1, 3, 2 };

int N = values.length;

TestingProj test = new TestingProj();

int result = test.findMax(values, N);

assertTrue(Integer.valueOf(3) == result);

}

@Test

public void findMaxWithArrayWithThreeElementsThirdLarge() {

System.out.println(“test case three elements array third large”);

int[] values = { 1, 2, 3 };

int N = values.length;

TestingProj test = new TestingProj();

int result = test.findMax(values, N);

assertTrue(Integer.valueOf(3) == result);

}

@Test

public void findMaxWithArrayWithFourElementsThirdLarge() {

System.out.println(“test case four elements array third large”);

int[] values = { 1, 2, 3, 2 };

int N = values.length;

TestingProj test = new TestingProj();

int result = test.findMax(values, N);

assertTrue(Integer.valueOf(3) == result);

}

@Test

public void findMaxWithArrayWithFourElementsForthLarge() {

System.out.println(“test case four elements array forth large”);

int[] values = { 1, 2, 3, 8 };

int N = values.length;

TestingProj test = new TestingProj();

int result = test.findMax(values, N);

assertTrue(Integer.valueOf(8) == result);

}

@After

public void tearDown() throws Exception {

System.out.println(“after test”);

}

@AfterClass

public static void tearDownAfterClass() throws Exception {

System.out.println(“after findmax test class”);

}

}

Find Avg

Test Case ID Description Input Expected Output Actual Output Pass/Fail
FA-1 The component will not work with array contains one element {22} 22 22 P
FA-2 The component will find average with array contains two unequal element {22,88} 55 44 F
FA-3 The component will find average with array contains three unequal element {22,88,66} 58 22 F

Unit Testing Code:

package testcases;

import static org.junit.Assert.assertTrue;

import org.junit.After;

import org.junit.AfterClass;

import org.junit.Before;

import org.junit.BeforeClass;

import org.junit.Test;

import Code.TestingProj;

public class Findavetest {

@BeforeClass

public static void setUpBeforeClass() throws Exception {

System.out.println(“before Findavetest class”);

}

@Before

public void setUp() throws Exception {

System.out.println(“before test”);

}

@Test

public void shouldDoNothingWithArrayWithSingleElement() {

System.out.println(“test case single element  array”);

int[] values = { 22 };

int N = values.length;

TestingProj test = new TestingProj();

double result = test.findAvg(values, N);

assertTrue(Integer.valueOf(22) == result);

}

@Test

public void shouldFindavgWithArrayWithDoubleElement() {

System.out.println(“test case double elements  array”);

int[] values = { 22, 88 };

int N = values.length;

TestingProj test = new TestingProj();

double result = test.findAvg(values, N);

assertTrue(Integer.valueOf(55) == result);

}

@Test

public void shouldFindavgWithArrayWithThreeElement() {

System.out.println(“test case three elements  array”);

int[] values = { 22, 88, 66 };

int N = values.length;

TestingProj test = new TestingProj();

double result = test.findAvg(values, N);

assertTrue(Integer.valueOf(58) == result);

}

@After

public void tearDown() throws Exception {

System.out.println(“after test”);

}

@AfterClass

public static void tearDownAfterClass() throws Exception {

System.out.println(“after findavetest class”);

}

}

Code for test suites:

package testcases;

import org.junit.runner.RunWith;

import org.junit.runners.Suite;

import org.junit.runners.Suite.SuiteClasses;

@RunWith(Suite.class)

@SuiteClasses({ Findavetest.class, Findmaxtest.class, SortingTest.class })

public class JunitTestSuite {

}

According to the actual result, we infer that:

  1. The sort method could not do the sorting and swapping the elements at all.
  2. The find max method could not scan the capturing and comparing with the last index element, and the algorithm finishes before capturing the last index element.
  3. The find avg method could not sum all elements, and the algorithm just return the last index element and divide the number of the size.

Fixing Bugs

From the test result, we can infer the possible defects. Those defects are exactly the defects we found during review stage. Now, go back to the code and fix the bugs.

package Code;

import java.util.Arrays;

public class TestingProj {

public int[] sortArr(int[] A, int N) {

int[] sA = A;
int swap;
for (int i = 0; i < N; i++) {
System.out.print((i + 1) + “round” + “sorting:”);
for (int j = i + 1; j < N; j++) {
if (sA[j] < sA[i]) {
swap = sA[j];
sA[j] = sA[i];
sA[i] = swap;
}

}
System.out.println(Arrays.toString(sA));

}

return sA;

}

public int findMax(int[] A, int N) {
int max = A[0];
for (int i = 0; i < N; i++) {
System.out.print((i + 1) + “time” + “find:”);
if (max < A[i])
max = A[i];
System.out.println(max);
}

return max;
}

public double findAvg(int[] A, int N) {
int sum = 0;
double avg = 0;
for (int i = 0; i < N; i++) {
System.out.print((i + 1) + “time” + “add:”);
sum += A[i];
System.out.println(sum);
}
avg = sum / N;
System.out.println(avg);
return avg;
}

public static void main(String[] args) {
{

// Initialize the class TestingProj
TestingProj test = new TestingProj();
// Assign value(array) to the parameters
int[] A = { 22, 3, 55, 4, 5, 88 };
// Define the size of the array
int N = A.length;

// Display the sorted array elements
System.out.println(Arrays.toString(test.sortArr(A, N)));
// Display the maximum value of array elements
System.out.println(test.findMax(A, N));
// Display the average value of array elements
System.out.println(test.findAvg(A, N));
}
}

}

Now, run the JUnit test suites.

8

We fix the bugs and all the unit test cases pass.

By doing the Unit Testing for the given java code. Defects of the three main methods are discovered. For the sorting method, the swap value should be assigned to A[i]. This way, the method could swap the values and get the maximum to the right position. For find max method, the i<N and the method could compare the last element and will not miss any element. For find avg method, the + should be put to the right side of =, if it is on the right side, it will not do anything and the value would be assigned from right to the left. Another issue is that TDD would be good way to help developers to avoid making such small mistakes during the development process.

 

Reference

Anik’s Codepen. (2011). Example flowchart 1: Find the result of addition of three numbers. What about their average? Retrieved from https://www.anikdas.com/blog/category/java/flowchart/

Eric M. & Brian M. (2003). Top 12 Reasons to Write Unit Tests. Retrieved from
http://www.onjava.com/pub/a/onjava/2003/04/02/javaxpckbk.html

RFF Electronics. (2010). Finding the Largest Number in an Unsorted List of Numbers. Retrieved from http://www.rff.com/find-largest-number.htm

Selection sort. (2011). In Baidu. Retrieved September 4, 2016, from http://baike.baidu.com/link?url=Nb4fyAk5K_g_ILMrrdXBTm5b-CuM_5kbBaV2G08Tg1is98z26EAkbOk3lHmOLf0yXt8QT3GZgCpYzhFET66BM