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.
You need more than 70% coverage to earn this badge.
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 :) (or unit test coverage of less than 70%)
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.