What Is A Unit Testing Framework?
I am going to split this into two parts. First of all, what you would normally do to test, then how a unit testing framework can help.
What You Would Normally Do
First of all, I am going to talk about how someone fairly new will handle testing. Let's say you wrote a AVL tree implementation, and you want to check if it works. There are a lot of things an AVL tree needs to have. The most obvious one is that all the nodes on the left side of a node are smaller than that node, and then all the nodes on the right side of that node are larger than that node. So you quickly write a method which checks this. Then in your tester:
System.out.println(tree.isValidBST());
But then you find that this is printing false
. Where is it going wrong? You search your isValidBST()
method. That looks fine. Then you look at the operations you did before.
tree.insert(5);
tree.insert(4);
tree.insert(7);
tree.delete(4);
So you first go to the insert()
method, and debug everything. You see that it is working fine. Then you go to the delete()
method, and then you found your bug. Congratulations! You have finished the first part. Now you need to check if the tree is always balanced. So, you add this check:
System.out.println(tree.isBalanced());
And that again doesn't work. Then you go back to your insert()
method, and find that it wasn't re-balancing the tree correctly. You didn't find this before because originally you didn't need the tree to be re-balanced. This seems like a tedious process. There must be an easier way. And luckily, there is!
How JUnit Can Help
JUnit is Javas implementation of a unit testing framework.
A unit testing framework, put simply, allows you to test the individual parts of your code. If one thing goes wrong, if you wrote your tests correctly you can easily find which part went wrong, and easily debug it. Taking the AVLTree
example, you can use JUnit to simplify it to this.
AVLTree tree;
@Before
public void setup() {
tree = new AVLTree();
}
// Add tests to check if insert and delete are working
@Test
public void balanceTest() {
int[] values = new int[1000];
// initialize the values.
for(int num : values) {
tree.insert(num);
assertTrue(tree.isBalanced());
}
}
// Same for the valid bst check
Now when you get an error, let's say in the height, you can pinpoint exactly what is causing the error. Then you can debug it easily.
Syntax
The syntax of JUnit is pretty simple. If you use the @Before
annotation, it will execute that code before every test. You should use this to reset anything you were working on. In this example, I used it to reset the AVLTree
values. Then, use the @Test
annotation for tests. Use certain special methods to check if something is working properly. These methods are assert
methods. There are tons of them, like assertEquals(expectedValue, actualValue)
or assertTrue(booleanThatShouldBeTrue)
. After every test, if you want you can add a method with the @After
annotation. This is usually used to tear down and work.