Week 03-1: Unit Testing / Developing a Sort
Sorting an Array
Let’s go through a workflow of development with a program that sorts words.
The Problem
Print out the command-line arguments in lexicographic order:
% java sort the quick brown fox jumped over the lazy dog
brown dog fox jumped lazy over quick the the
The Plan
public class Sort {
/** Sort lexicographically */
public static void main(String[] words) {
sort(words, 0, words.length - 1);
print(words);
}
static void sort(String[] A, int L, int U) { /* "TOMORROW" */ }
static void print(String[] A) {}
}
How do we know that it works?
-
Unit testing - testing of individual units (methods) within a program, rather than the whole program.
-
Module testing - Testing of classes or other groupings of methods and data.
-
System testing - Testing of a program’s entire functionality.
-
Integration testing - Tests that modules work correctly together
-
Regression testing - Ensures that fixes, enhancements, or other changes have not introduced faults (regressions)
We will mainly be using the JUnit tool for unit testing
Test-Driven Development
A popular development practice, Test-Driven Development (or TDD), involves writing the tests first, then implementing your logic to pass the tests.
-
Implement one unit at a time, run the tests, fix and refactor until it works.
-
This is only lightly going to be pushed in this course, but it is really good practice for real-world programming.
Let’s test our sort
program
-
Pretty easy: Give a bunch of arrays to sort, then make sure they are each sorted properly.
-
We must make sure that we cover all cases:
-
Corner (edge) cases: empty arrays, one element, all elements the same, etc.
-
Representative (middle) cases: elements reversed, elements in order, one pair of elements reversed
-
Coverage is a measure of how much of your program is actually being tested. You should strive to get as much coverage as you can in your code. If using a TDD approach, you would almost always be near 100% coverage.
JUnit
- We use the
@Test
annotation on a method, which tells JUnit to use that method as a test call. This method would contain assertions, which perform the validations of your program’s output.
An example of an assertion would be similar to the following:
assertArrayEquals("Empty array failed",
new String[] {},
runSort(new String[] { }, 0, -1));