Welcome to Part 2 of this review of the Pluralsight course Introduction to Testing in Java by Richard Warburton.
Testing Code
Writing Test Code
The key testing framework that we’ll be using is JUnit. There are other frameworks such as Testng, but once we learn the practices it will be easier to switch to a different framework if you want to.
JUnit is the most commonly used testing framework for Java.
Our first test has an enumeration and two classes: CoffeeType, Coffee and Cafe.
Writing Your First Test
Richard uses IntelliJ for editing Java code, but you can of course use whichever your prefer.
He explains the Cafe.java and Coffee.java classes and the CoffeeTypejava enum.
The key business logic is brewing the coffee, so a good place to start is a test for the brew method in Cafe.java.
We are advised to think carefully about a creating a descriptive name for the test, and are introduced to the @Test
annotation, which needs to be added above each test method.
This first test is called canBrewEspresso and includes statements for arranging the code, and a statement for acting on the method under test.
It also has three assertions to check that:
– It is an expresso
– There’s no milk
– We have enough coffee
Richard also shows us what happens when our test fails.
Running Tests on the Command Line
In this lesson we learn how to run our tests on the command line using the Maven build system.
Maven has a built-in plugin called Surefire that let’s us run tests written in JUnit or Testng.
>mvn clean test
Richard does not go into the details of configuring Maven or enabling/disabling tests here and recommends reading the online Maven documentation for that.
The Common Structure of Tests
This explains the three things we need to get right when we write tests:
Given – What should the work look like when the behaviour happens?
When – What is being tested?
Then – What are the changes that have happened?
I used the words Arrange, Act and Assert earlier. These translate to Given, When and Then
The Common Structure of Tests in Code
Richard adds comments to clarify the three sections of code in our first unit test. Next we write brewingEspressoConsumesBeans.
We see that we can run a single test by right clicking on the method name and choosing run test from the menu.
We can also right click on the class name to run all tests in a test class.
Exception, Failures, and Errors
Sooner or later, something goes wrong. When a test fails it may be because the production code is wrong. It might also be a bug in the test.
For some tests the expected result is an exception being thrown. To implement this so that a test passes instead of fails when an exception is thrown, we use an annotation such as this:
@Test(expected = IllegalArgumentException.class)
Richard also explains the difference between a failure and an error.
A failure is an assertion failing and it suggests the production code is broken (assuming the assertion is correct)
An error is an exception getting thrown somewhere in the test. It suggests the test is broken.
Exception, Failures, and Errors in Code
We write a new test latteRequiresMilk
, and in this test we expect the test to throw an exception. To set this expectation we use this annotation:
@Test(expected = IllegalStateException.class)