CS410J: Advanced Java Programming Testing: - Constant Feedback From The Customer Ensures
CS410J: Advanced Java Programming Testing: - Constant Feedback From The Customer Ensures
• Using JUnit • Don’t wait until you think your code is finished to
write tests
• Advanced assertions with Hamcrest
• Write tests as you code
Copyright
c 2001-2017 by David M. Whitlock. Permission to make digital or hard • Every new piece of functionality should have a test
copies of part or all of this work for personal or classroom use is granted without (“unit test”)
fee provided that copies are not made or distributed for profit or commercial
advantage and that copies bear this notice and full citation on the first page. To
copy otherwise, to republish, to post on servers, or to redistribute to lists, requires
prior specific permission and/or fee. Request permission to publish from • Run your tests every time you recompile
[email protected]. Last updated May 7, 2017.
1 2
Starting in the mid-1990s, Kent Beck and friends began Extreme Programming works very well when developing
evangelizing the concept of “extreme programming” Object-Oriented software
• Software needs to be developed quickly and needs • Classes are extended to add functionality
to evolve even faster
• New tests are added for the new functionality
• Software engineers should develop together: “Pair
Programming”
• The old tests for the old functionality still work
• Testing code should be developed along with the
code being tested Just like “documenting as you code”, “testing as you
code” has many benefits
• It takes a village to write software: architect,
programmer, manager, and customer • You can feel confident that you code works
– Constant feedback from the customer ensures
that the customer always gets what he wants • You find bugs in your code before someone else
does!
• The software must function, and function correctly, at
all times, even if the functionality is limited • You become a consumer of your own code (Is it easy
to use?)
• Extreme Programming emphasizes simplicity and
elegance in software engineering
• If you run all of your tests every time you build, you
– Get things working, then optimize know that your changes haven’t broken anything
3 4
JUnit Configuring tests with annotations
Kent Beck and Erich Gamma (of Design Patterns fame) JUnit was very successful, but some things in the
developed a unit testing framework for Java programs framework were awkward
called JUnit
• Subclassing TestCase meant that your test couldn’t
http://www.junit.org subclass any other class
5 6
To demonstrate writing unit tests, we are going to develop The below class tests that adding a Student increases
some classes for modeling Students that are enrolled in the enrollment by one
a Section of a Course
package edu.pdx.cs410J.junit;
* * *
Course Section Student
int term String id import org.junit.Test;
String department import static org.junit.Assert.assertEquals;
int number int year Map grades
import static org.junit.Assert.fail;
int credits addStudent(Student)
dropStudent(Student) public class SectionTest {
double averageGrade()
int getClassSize() @Test
public void testAddStudent() {
Student student = new Student("123-45-6789");
Course course = new Course("CS", 410, 4);
Section section =
new Section(course, Section.SPRING, 2001);
section.addStudent(student);
assertEquals(1, section.getClassSize());
}
}
7 8
Running The Test Case Testing Error Conditions
The org.junit.runner.JUnitCore class runs the tests Making sure that your program fails in a well-understood
in a test class and prints out the result to standard out fashion is very important
9 10
The Assert contains methods for validating that certain Test code is just a regular Java class with methods
conditions are true
• Methods annotated with @Before and @After
• assertEquals: Two entities (objects, ints, etc.) methods are invoked before and after the test is run
should be equal (compares objects using equals()) – Establish/disconnect network resources, etc.
• assertNotNull: A value should not be null • Each of your test methods must be annotated with
@Test
• assertSame: Two object references should be the
same (compare objects using ==) The TestSuite class
• assertTrue: A boolean expression should be true Annotating a class with @SuiteClasses specifies a suite
of multiple test classes
• fail: The test should fail • You’ll also need to annotate the class with
@RunWith(Suite.class) to tell the JUnit runner that
When an assertion evaluates to false, the test fails it is a suite
11 12
Test Classes and Packages More readable assertions
Should test classes be in the same package as the code JUnit provides some basic methods for validating the
they are testing? state of your tests (assertions), but the code and the
failure messages can be hard to read
Pros:
assertTrue(myString.contains("Hello"));
• Test code can access package-protected methods
and fields When the above fails, all you get is an “expected true,
but got false” error message
• Easy to associate test code with domain code
The Hamcrest library provides powerful “matchers” that
provide readable assertion statements with detailed and
Cons: specific failure messages
~/tests/edu/pdx/cs410J/...
13 14
@Test
public void isEqualTo() {
Integer int1 = new Integer("123");
Integer int2 = new Integer("123");
assertThat(int1, is(equalTo(int2)));
}
15 16
Examples of Hamcrest assertions Summary
@Test • When you make changes, you can verify that you
public void arrays() { didn’t break anything
Integer[] array = { 1, 2, 3, 4, 5};
assertThat(array, hasItemInArray(4));
assertThat(array, is(arrayWithSize(5))); • Spending time writing tests reducing debugging time
assertThat(array, is(not(emptyArray())));
assertThat(4, isIn(array));
} • JUnit makes it easy to write and run test cases
17 18