In this tutorial, we are going to look at how we can use unit tests to verify that our program is working correctly. The first questions you may have is what is unit testing and why are we doing it? Unit testing is where we test specific parts of our code against specific requirements. Tests are small in nature and focused on one specific aspect of the programs functionality. Unit test often make up the first part of testing when it comes to testing a program.
There are several important reasons to test code. Proper test cases are written against user requirements, independent of the code that is developed. With this in mind, we can use unit tests to verify that our code is actually working properly. If you are working on a larger project for a customer, unit tests can be helpful on several fronts. First, they can be used to verify that each part of the code works before integration. During integration, code may get changed or refactored and the unit tests can then be rerun to very that the code is still producing the expected output. Additionally, if you have a deliverable to a customer, unit tests can help provide documentation that your product is working as intended.
For this tutorial, we are going to create an ArrayList class that contains part of the functionality that we see in the built in ArrayList functions.
Specifically, we are going to address the following requirements:
Since this tutorial is about testing, we are not going to walk through the details of how we created our ArrayList class, but take some time to explore the ArrayList code and run the ArrayTester. Notice that we are not importing ArrayLists from Java, so the ArrayList object is from our class.
Before we can test, we need to come up with our test cases. As mentioned earlier, our test cases should be built off our requirements. With that in mind, let’s revist our requirements:
To create a test case for this first object, we want to create both a String ArrayList and an Integer ArrayList and verify that they have a size of zero before adding anything. So out first two test cases can be:
In similar fashion, we can create unit tests for the remainder of the requirements:
For our testing, we are going to use a basic test class. This class is similar to other testing classes such as JUnit testing, but is simplified for this tutorial.
The Test class contains one overloaded method, assertEqual. We will use the first variation where we will pass it a test name, followed by the actual results and the expected results. Like our ArrayList class, this class can take any type of object and compare them.
Take a minute to play around with the Test class before we get into writing our test cases.
When it comes to executing our test case, there are a couple of guiding principles that we want to follow. First, each test should only test one thing at a time. If we try and test more than one thing, we may not know what fails.
As we set up our tests, we want to follow the 3 A's: Arrange, Act, and Assert. Let's take a look at each of these steps:
Arrange - In the first step, we are setting up our test cases. For example, if we are going to test adding an object to the middle of our ArrayList, we want to start with an ArrayList
Act - The act step is where we actually perform the action we are going to test. For example, if we want to test adding to the middle of our ArrayList, our act step will be to add to the middle.
Assert - This is where we will test our results and make sure we are getting the expected results.
Let's take a look at this for one of our test cases below.
From here, we can add more of our test cases. More tests have been added below, but see if you can take time to finish them. Notice how each test case builds off of the others. This makes can make it easier so that you don't need to recreate the setup each time, but sometimes you will still need to arrange before you act.