Earning Unit Tests badge

This article gives you pointers on how to write good tests.

UnitTests overview

We are primarily looking for unit tests. We look at the quality of the tests, the readability and the coverage of the tests. The whole idea behind writing tests is to make your life easier by making you feel safe when changing your code. Please look at this document to understand what all testing tools we cover for different languages. 
We will use a deprecated Geektrust coding challenge to explain concepts. You can see the coding challenge here -> Cricket coding challenge

The usual suspects - common pitfalls while writing tests

1. No unit tests :)

2. Integration tests instead of unit tests
While writing tests, we should focus on testing individual units of functionality, that does one specific thing. Unit tests are like a low-level regression test suite that also helps to document your code. Unit test is usually done for a single functionality, a unit test never fulfills the final functional requirements.

Integration tests can be added to test an entire system or application with all of the code running together. But it should not replace unit tests.

Unit test

public class OverTest {

    private Team lineup;
    @Mock
    private Batsman kirat;
    @Mock
    private Batsman vraj;
    @Mock
    private Batsman dony;

    @Test
    public void shouldEndOverIfTargetRunsAreScored() throws Exception {
        Team teamLineup = Team.named("India").openingWith(kirat, vraj)
                              .followedBy(dony).build();
        Runs targetRuns = Runs.valueOf(10);

        when(kirat.score()).thenReturn(SIX).thenReturn(TWO).thenReturn(THREE);
        Over over = new Over(teamLineup, targetRuns);

        assertThat(over.ballsPlayed()).hasSize(3);
        verify(kirat, times(3)).score();
        assertThat(over.remainigBalls()).hasSize(3);
        verifyZeroInteractions(vraj);
    }
}
	

Integration test

public class TiebreakMatchIntegrationTest {

    private Batsman kirat;
    private Batsman dony;
    private Batsman bellyers;
    private Batsman aamla;

    @Before
    public void setUp() throws Exception {
        kirat = Batsman.named("Kirat Boli")
                .scores(DOT, 5).scores(ONE, 10).scores(TWO, 25).scores(THREE, 10)
                .scores(FOUR, 25).scores(FIVE, 1).scores(SIX, 14).scores(OUT, 10)
                .build();
        dony = Batsman.named("Dony")
                .scores(DOT, 5).scores(ONE, 15).scores(TWO, 15).scores(THREE, 10)
                .scores(FOUR, 20).scores(FIVE, 1).scores(SIX, 19).scores(OUT, 15)
                .build();

        bellyers = Batsman.named("Bellyers")
                .scores(DOT, 5).scores(ONE, 10).scores(TWO, 25).scores(THREE, 10)
                .scores(FOUR, 25).scores(FIVE, 1).scores(SIX, 14).scores(OUT, 10)
                .build();
        aamla = Batsman.named("Aamla")
                .scores(DOT, 10).scores(ONE, 15).scores(TWO, 15).scores(THREE, 10)
                .scores(FOUR, 20).scores(FIVE, 1).scores(SIX, 19).scores(OUT, 10)
                .build();
    }

    @Test
    public void integrationTest() throws Exception {
        Team lengaburu = Team.named("Lengaburu  Challengers")
                        .openingWith(kirat, dony).build();
        Team enchai = Team.named("Enchai Super Queens")
                        .openingWith(bellyers, aamla).build();

        Match match = new Match(lengaburu, enchai).playTiebreaker();

        assertThat(match.toString()).isEqualTo(concat(
                "Enchai Super Queens has tied the match with 0 balls remaining!",
                "",
                "Lengaburu Loyal Challengers",
                "Kirat Boli - 11* (4 balls)",
                "NS Nodhi - 9* (2 balls)",
                "",
                "Enchai Super Queens",
                "DB Vellyers - 20* (6 balls)",
                "H Mamla - 0* (0 balls)",
                "",
                "Lengaburu Loyal Challengers innings",
                "1 over left.",
                "",
                "0.1 Kirat Boli scores 2 runs",
                "0.2 Kirat Boli scores 2 runs",
                "0.3 Kirat Boli scores 6 runs",
                "0.4 Kirat Boli scores 1 run",
                "0.5 NS Nodhi scores 6 runs",
                "0.6 NS Nodhi scores 3 runs",
                "",
                "Enchai Super Queens innings",
                "1 over left. 21 runs to win",
                "",
                "0.1 DB Vellyers scores 4 runs",
                "0.2 DB Vellyers scores 4 runs",
                "0.3 DB Vellyers scores 0 runs",
                "0.4 DB Vellyers scores 4 runs",
                "0.5 DB Vellyers scores 4 runs",
                "0.6 DB Vellyers scores 4 runs",
                ""));
    }
}
	
3. Bad naming for your tests
The name of the test should give an indication which part of the code broke. 'assertForException' is not a good name for a test. But 'shouldRotateStrikeIfOneRunScoredAndIfOverNotFinished' is. 
4. Multiple things being asserted in one test
If the naming convention is right, we should be able to say exactly what broke by seeing the test name. However, if the test is asserting multiple things, it will be hard to quickly identify what the issue is.

Did this answer your question? Thanks for the feedback There was a problem submitting your feedback. Please try again later.

Still need help? Contact Us Contact Us