good tests bad tests
TRANSCRIPT
![Page 1: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/1.jpg)
![Page 2: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/2.jpg)
Dijkstra, The Humble Programmer 1972
![Page 3: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/3.jpg)
Gute Tests
● Mit jedem Test stellen wir sicher, dass die getesteteFunktionalität korrekt umgesetzt ist
● Hoffnung, dass ähnliche Fälle genauso gut funktionieren(Äquivalenzklassen)
● Änderungen werden leichter möglich, weil sichergestellt wird,dass die bestehende Funktionalität nicht kaputt geht
● Tests sind die aktuellste Dokumentation
● Jeder Test erzählt eine Geschichte über was passiert undwas zu erwarten ist.
●
![Page 4: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/4.jpg)
Böse Tests
● Fragile Tests: kleine Änderung in derImplementierung => viele Tests betroffen
● Redundante Tests => Balast
● Triviale Tests
● Unvollständige Tests => falsche Sicherheit
● Tests ohne Asserts
![Page 5: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/5.jpg)
No Assertions
IResult result = format.execute();System.out.println(result.size());Iterator iter = result.iterator();while (iter.hasNext()) { IResult r = (IResult) iter.next(); System.out.println(r.getMessage());}
![Page 6: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/6.jpg)
No Assertions(verbessert)
IResult result = format.execute();assertThat(result.size()).isEqualTo(3); 1Iterator iter = result.iterator();while (iter.hasNext()) { IResult r = (IResult) iter.next(); assertThat(r.getMessage()).contains("error"); 2}
![Page 7: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/7.jpg)
Get- Setter
public void testSetGetParam() throws Exception { String[] tests = {"a", "aaa", "---", "23121313", "", null};
for (int i = 0; i < tests.length; i++) { adapter.setParam(tests[i]); assertEquals(tests[i], adapter.getParam()); }}
![Page 8: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/8.jpg)
Happy Path
public class FizzBuzzTest { @Test public void testMultipleOfThreeAndFivePrintsFizzBuzz() { assertEquals("FizzBuzz", FizzBuzz.getResult(15)); }
@Test public void testMultipleOfThreeOnlyPrintsFizz() { assertEquals("Fizz", FizzBuzz.getResult(93)); }
![Page 9: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/9.jpg)
Happy Path(verbessert)
@RunWith(JUnitParamsRunner.class)public class FizzBuzzJUnitTest {
@Test @Parameters(value = {"15", "30", "75"}) public void testMultipleOfThreeAndFivePrintsFizzBuzz( int multipleOf3And5) { assertEquals("FizzBuzz", FizzBuzz.getResult(multipleOf3And5)); }
@Test @Parameters(value = {"9", "36", "81"}) public void testMultipleOfThreeOnlyPrintsFizz(...
@Test @Parameters(value = {"10", "55", "100"}) public void testMultipleOfFiveOnlyPrintsBuzz(...
@Test @Parameters(value = {"2", "16", "23", "47", "52", ... public void testInputOfEightPrintsTheNumber(...}
![Page 10: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/10.jpg)
Not Enough Testing
@Testpublic class PagerTest {
private static final int PER_PAGE = 10;
public void shouldGiveOffsetZeroWhenOnZeroPage() { Pager pager = new Pager(PER_PAGE);
assertThat(pager.getOffset()).isEqualTo(0); }
public void shouldIncreaseOffsetWhenGoingToPageOne() { Pager pager = new Pager(PER_PAGE);
pager.goToNextPage();
assertThat(pager.getOffset()).isEqualTo(PER_PAGE); }}
![Page 11: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/11.jpg)
Not Enough Testing (verbessert)
Zero, One and Many
![Page 12: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/12.jpg)
Auskommentieren
//@Testpublic void testTeaserWithBildPlusMarker(){
String url = urlBuilder.setBaseUrl(HTTP_START_PATH + TEASERREIHE_BILDPLUS_MARKER_PATH.setView("module".build();
driver.get(url);
// TeaserreiheWebElement teaserReiheElement = getRootElement();BTOTeaserReihe_modulePO teaserReihePO =
new BTOTeaserReihe_modulePO(teaserReiheElement);List<Resource_teaserPO> teaserPOs =
teaserReihePO.getTeaserPOs();assertNotNull("Teaser-Page-Objekte fehlen", teaserPOs);assertEquals(1, teaserPOs.size());
}
(Aus bildcms JSP-Tests)
![Page 13: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/13.jpg)
Auskommentieren(verbessert)
@Test @Ignore //TODO momentan nicht testbar auf Testsystempublic void testTeaserWithBildPlusMarker(){
String url = urlBuilder.setBaseUrl(HTTP_START_PATH + TEASERREIHE_BILDPLUS_MARKER_PATH.setView("module".build();
driver.get(url);
// TeaserreiheWebElement teaserReiheElement = getRootElement();BTOTeaserReihe_modulePO teaserReihePO =
new BTOTeaserReihe_modulePO(teaserReiheElement);List<Resource_teaserPO> teaserPOs =
teaserReihePO.getTeaserPOs();assertNotNull("Teaser-Page-Objekte fehlen", teaserPOs);assertEquals(1, teaserPOs.size());
}
![Page 14: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/14.jpg)
Expecting Exceptions Anywhere
@Test(expected=IndexOutOfBoundsException.class)public void testMyList() { MyList<Integer> list = new MyList<Integer>(); list.add(1); list.add(2); list.add(3); list.add(3); list.add(4); assertTrue(4 == list.get(4)); assertTrue(2 == list.get(1)); assertTrue(3 == list.get(2));
list.get(6);}
![Page 15: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/15.jpg)
Expecting Exceptions Anywhere(verbessert)
● Tests aufteilen (Split)● Exception-Test Lokalisieren
![Page 16: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/16.jpg)
Assertions should be Merciless
@Testpublic void shouldRemoveEmailsByState() { //given Email pending = createAndSaveEmail("pending","content pending", "[email protected]", Email.PENDING); Email failed = createAndSaveEmail("failed","content failed", "[email protected]", Email.FAILED); Email sent = createAndSaveEmail("sent","content sent", "[email protected]", Email.SENT);
//when emailDAO.removeByState(Email.FAILED);
//then assertThat(emailDAO.findAll()).excludes(failed);}
![Page 17: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/17.jpg)
Assertions should be Merciless(verbessert)
assertThat(emailDAO.findAll(),contains(pending, sent))
![Page 18: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/18.jpg)
Is Mockito Working Fine?
@Testpublic void testFormUpdate() { // given Form f = Mockito.mock(Form.class); Mockito.when( f.isUpdateAllowed()).thenReturn(true);
// when boolean result = f.isUpdateAllowed();
// then assertTrue(result);}
![Page 19: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/19.jpg)
@Testpublic void will_getChangSecurityQuestRgtAndDetails_if_AdvUserhasRuleId25(){ User user = createUser(userId); user.setAdvanced(true); PasswordRuleDto passwordRuleDto = new PasswordRuleDto(); passwordRuleDto.setPasswordRuleId(rulId25); List<PasswordRuleDto> passwordRules = new ArrayList<PasswordRuleDto>(); passwordRules.add(passwordRuleDto); given(currentUser.getUser()).thenReturn(user); given(userDAO.readByPrimaryKey(userId)).thenReturn(user); given(passwordBean.getPasswordRules()).thenReturn(passwordRules); UserSecurityQuestionDto dto = userChangeSecurityQuestionBean .getChangSecurityQuestionRgtAndDetails(); assertNotNull(dto.getEmail()); assertNotNull(dto.getFirstName()); assertNotNull(dto.getLastName()); assertEquals(dto.isChangeSecurityQuestion(), true);}
Why formatting helps
![Page 20: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/20.jpg)
@Testpublic void will_getChangSecurityQuestRgtAndDetails_if_AdvUserhasRuleId25(){ // given User user = createUser(userId); user.setAdvanced(true); PasswordRuleDto passwordRuleDto = new PasswordRuleDto();
passwordRuleDto.setPasswordRuleId(rulId25); List<PasswordRuleDto> passwordRules = new ArrayList<PasswordRuleDto>(); passwordRules.add(passwordRuleDto);
given(currentUser.getUser()).willReturn(user); given(userDAO.readByPrimaryKey(userId)).willReturn(user); given(passwordBean.getPasswordRules()).willReturn(passwordRules);
// when UserSecurityQuestionDto dto = userChangeSecurityQuestionBean .getChangSecurityQuestionRgtAndDetails();
// then assertNotNull(dto.getEmail()); assertNotNull(dto.getFirstName()); assertNotNull(dto.getLastName()); assertEquals(dto.isChangeSecurityQuestion(), true);}
Why formatting helps(verbessert)
![Page 21: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/21.jpg)
When a Test Name LiesShould is Better than Test
public void testInsertNewValues() { //given //when reportRepository.updateReport(ReportColumn.DATE, ReportColumn.PLACE, reportMap(BigDecimal.TEN)); reportRepository.updateReport(ReportColumn.DATE, ReportColumn.PLACE, reportMap(new BigDecimal("5")));
//then assertThat(reportRepository .getCount(ReportColumn.DATE, ReportColumn.PLACE)) .isEqualTo(1);}
![Page 22: Good Tests Bad Tests](https://reader034.vdocuments.net/reader034/viewer/2022042502/58837eb81a28ab22688b6e69/html5/thumbnails/22.jpg)
When a Test Name LiesShould is Better than Test
(korrigiert)public void shouldOverrideOldReportWithNewValues() { //given //when reportRepository.updateReport(ReportColumn.DATE, ReportColumn.PLACE, reportMap(BigDecimal.TEN)); reportRepository.updateReport(ReportColumn.DATE, ReportColumn.PLACE, reportMap(new BigDecimal("5")));
//then assertThat(reportRepository .getCount(ReportColumn.DATE, ReportColumn.PLACE)) .isEqualTo(1);}