Lab&Assignment10 UnitTesting
Lab&Assignment10 UnitTesting
1. SUBMISSION GUIDELINE
When you want to submit your individual work of in-class tasks for the Case
Study, you have to push your work to your individual GitHub repository,
complied with the naming convention “TeamName-StudentID.StudentName” (e.g.
TKXDPM.KHMT.20231.20192012.HoangNghiaPhu or TKXDPM.VP.20231-
20192122.LuongHongHai).
2. IN-CLASS ASSIGNMENT
In this section, we will get familiar with the software construction process and try
ourselves with unit testing for the Case Study.
The first three subsections would give you an overview about unit testing, test-
driven development, and JUNIT. After that, you will practice them in the last
subsection 2.4. You would need Excel (to design test cases), JUNIT5 (already
included in Eclipse IDE), Oracle JDK 11, and then import the given sample
project1.
You are asked to work individually for this section, and then put all your design of
unit test (Excel file) to a directory, namely “UnitTest”, and put the codes in
“Programming” directiory. After that, push your commit to your individual
repository before the announced deadline.
Thus, unit testing is neither suitable for testing complicated user interface nor the
interaction among great modules/subsystems.
In the article TDD - What it is and what it is not 4, Andrea Koutifaris describes this
cycle:
Red phase: You write an automated test for a behavior that you're about to
implement. Based on the user requirement, you decide how you can write a
test that uses a piece of code as if it were implemented. This is a good
opportunity to think about the externals of the code, without getting
distracted by actually filling in the implementation. Think about what the
3
https://www.ibm.com/garage/method/practices/code/practice_test_driven_development/
4
https://medium.freecodecamp.org/test-driven-development-what-it-is-and-what-it-is-not-
41fa6bca02a2
HANDS-ON LAB GUIDELINES
© SOICT – HUST
ITSS SOFTWARE DEVELOPMENT – IT4945E
3
5
http://web.mit.edu/6.031/www/sp17/classes/03-testing/#automated_unit_testing_with_junit
HANDS-ON LAB GUIDELINES
© SOICT – HUST
ITSS SOFTWARE DEVELOPMENT – IT4945E
4
}
@Test
public void testBothEqual() {
assertEquals(9, Math.max(9, 9));
}
@Test
public void testAGreaterThanB() {
assertEquals(-5. Math.max(-5, -6));
}
Note that the order of the parameters to assertEquals is important. The first
parameter should be the expected result, usually a constant, that the test wants to
see. The second parameter is the actual result, what the code actually does. If you
switch them around, then JUnit will produce a confusing error message when the
test fails. All the assertions supported by JUnit follow this order consistently:
expected first, actual second.
If an assertion in a test method fails, then that test method returns immediately,
and JUnit records a failure for that test. A test class can contain any number of
@Test methods, which are run independently when you run the test class with
JUnit. Even if one test method fails, the others will still be run.
2.3.2. Documenting Your Testing Strategy6
Let consider a function that reverses the end of a string.
/**
* Reverses the end of a string.
*
* For example:
* reverseEnd("Hello, world", 5)
* returns "Hellodlrow ,"
*
* With start == 0, reverses the entire text.
* With start == text.length(), reverses nothing.
*
* @param text non-null String that will have
* its end reversed
* @param start the index at which the
* remainder of the input is
* reversed, requires 0 <=
* start <= text.length()
* @return input text with the substring from
* start to the end of the string
* reversed
6
http://web.mit.edu/6.031/www/sp17/classes/03-testing/#automated_unit_testing_with_junit
HANDS-ON LAB GUIDELINES
© SOICT – HUST
ITSS SOFTWARE DEVELOPMENT – IT4945E
5
*/
static String reverseEnd(String text, int start)
For example, at the top of the class, we can document the testing strategy we
worked on in the partitioning exercises above. The strategy also addresses some
boundary values we did not consider before.
/*
* Testing strategy
*
* Partition the inputs as follows:
* text.length(): 0, 1, > 1
* start: 0, 1, 1 < start < text.length(),
* text.length() - 1, text.length()
* text.length()-start: 0, 1, even > 1, odd > 1
*
* Include even- and odd-length reversals because
* only odd has a middle element that doesn't move.
*
* Exhaustive Cartesian coverage of partitions.
*/
Each test method should also need a comment above it saying how its test case
was chosen, i.e. which parts of the partitions it covers:
// covers test.length() = 0,
// start = 0 = text.length(),
// text.length()-start = 0
@Test public void testEmpty() {
assertEquals("", reverseEnd("", 0));
}
JUnit 5 Description
The annotated (static) method will be executed once before any @Test method
@BeforeAll in the current class.
The annotated method will be executed before each @Test method in the
@BeforeEach current class.
The annotated method will be executed after each @Test method in the
@AfterEach current class.
@AfterAll The annotated (static) method will be executed once after all @Test methods
7
https://developer.ibm.com/tutorials/j-introducing-junit5-part1-jupiter-api/
HANDS-ON LAB GUIDELINES
© SOICT – HUST
ITSS SOFTWARE DEVELOPMENT – IT4945E
6
JUnit 5 Description
The annotated method will not be executed (it will be skipped), but reported as
@Disabled such.
Figure 2-Important Annotations in JUNIT5
Based on SRS and SDD, we design unit tests and develop the method
validateDeliveryInfo() by applying TDD.
We divide the method validateDeliveryInfo() into 3 three methods:
validateAdress(), validateName() ,and validatePhoneNumber().
Initially, all these methods are empty.
Obviously, if we run the test now, the test will be failed since we have not
implemented anything yet.
You can see that there is a failed test case: the one with the input-output pair
"1234567890,false". We need to go back to the method and add the validation
codes for the phone number which must start with 0. At last, we have all passed
test cases.
In another hand, these three test cases could make a test suite. A test suite is a
collection of test cases related to the same test work.
Right click on the project -> New -> Test Suite
Add all classes that we need to test in the test suite into class AllTest and then
run.