Structure Tests Into Given-When-Then

 class​ CruiseControlTest {
 
  @Test
 void​ setPlanetarySpeedIs7667() {
» CruiseControl cruiseControl = ​new​ CruiseControl();
» cruiseControl.setPreset(SpeedPreset.PLANETARY_SPEED);
» Assertions.assertTrue(7667 == cruiseControl.getTargetSpeedKmh());
  }
 }

Above, you can see a simple test written with JUnit5. Although it’s not part of the Java class library, JUnit’s the de facto standard for writing unit tests in Java and JUnit5 is the newest revision. Defining a test is simple enough, and chances are you’re already familiar with it: you just add the @Test annotation to a method and JUnit can execute it as a test.

That test above is worth its money—it runs correctly, and it will detect bugs in the code. And because it’s part of an assertion, we don’t need to apply Replace Magic Numbers with Constants for 7667. The problem is, as we’ve seen so many times before, it’s not as well structured and readable as it could be. Readability is just as important for testing code as it is for source code. After all, test code is code. But the test here looks like it was written in a hurry and without due diligence.

Usually, a test consists of three core parts: given, when, and then. Consider the following exemplary test specification:

  • given a calculator showing the number 2
  • when adding the number 3
  • then it should show the number 5.

The given part sets the stage for the actual test and captures all prerequisites for executing the functionality we want to test. The when part triggers the operation that we actually want to test. And in the then part, we assert that the result that the when trigger produced is actually what we expect.

You can make your test code much more readable if you make this structure stand out in your code. Can you spot which statement of the test above belongs to which of those three parts? There are three lines and three concepts (given, when, then) to match, so you would think it’s straightforward. In that case, you’re in for a little surprise.

Here’s how you can structure the test to communicate its parts more clearly:

 class​ CruiseControlTest {
 
  @Test
 void​ setPlanetarySpeedIs7667() {
» CruiseControl cruiseControl = ​new​ CruiseControl();
 
» cruiseControl.setPreset(SpeedPreset.PLANETARY_SPEED);
 
» Assertions.assertTrue(7667 == cruiseControl.getTargetSpeedKmh());
  }
 }

There’s a lot you can do in terms of readability with only little changes. Formatting with new lines to separate the given-when-then parts is already a big improvement. In a sense, we’ve just applied Group with New Lines to highlight the specific structure of the test.

Thanks to the extra vertical empty lines that split the statements, given, when, and then now directly shine in our faces. This makes it so much clearer. For practice, you can add comments into the test code to make the structure even more obvious. Consider the following:

»// given
 CruiseControl cruiseControl = ​new​ CruiseControl();
 
»// when
 cruiseControl.setPreset(SpeedPreset.PLANETARY_SPEED);
 
»// then
 Assertions.assertTrue(7667 == cruiseControl.getTargetSpeedKmh());

When teaching, we sometimes recommend adding these comments as a way for students to get used to structuring tests properly. But when you’re used to that structure, the vertical empty lines are more than enough. Frameworks like JGiven[37] make this structure even more explicit.

But there’s another problem in the code, as you’ll see in the next comparison.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.135.247.11