Dijkstra, The Humble Programmer 1972
Gute Tests
● Mit jedem Test stellen wir sicher, dass die getestete
Funktionalität korrekt umgesetzt ist
● Hoffnung, dass ä...
Böse Tests
● Fragile Tests: kleine Änderung in der
Implementierung => viele Tests betroffen
● Redundante Tests => Balast
●...
No Assertions
IResult result = format.execute();
System.out.println(result.size());
Iterator iter = result.iterator();
whi...
No Assertions
(verbessert)
IResult result = format.execute();
assertThat(result.size()).isEqualTo(3); 1
Iterator iter = re...
Get- Setter
public void testSetGetParam() throws Exception {
String[] tests = {"a", "aaa", "---",
"23121313", "", null};
f...
Happy Path
public class FizzBuzzTest {
@Test
public void testMultipleOfThreeAndFivePrintsFizzBuzz() {
assertEquals("FizzBu...
Happy Path
(verbessert)
@RunWith(JUnitParamsRunner.class)
public class FizzBuzzJUnitTest {
@Test
@Parameters(value = {"15"...
Not Enough Testing
@Test
public class PagerTest {
private static final int PER_PAGE = 10;
public void shouldGiveOffsetZero...
Not Enough Testing
(verbessert)
Zero, One and Many
Auskommentieren
//@Test
public void testTeaserWithBildPlusMarker()
{
String url = urlBuilder.setBaseUrl(HTTP_START_PATH +
...
Auskommentieren
(verbessert)
@Test @Ignore //TODO momentan nicht testbar auf Testsystem
public void testTeaserWithBildPlus...
Expecting Exceptions Anywhere
@Test(expected=IndexOutOfBoundsException.class)
public void testMyList() {
MyList<Integer> l...
Expecting Exceptions Anywhere
(verbessert)
● Tests aufteilen (Split)
● Exception-Test Lokalisieren
Assertions should be Merciless
@Test
public void shouldRemoveEmailsByState() {
//given
Email pending = createAndSaveEmail(...
Assertions should be Merciless
(verbessert)
assertThat(emailDAO.findAll(),
contains(pending, sent))
Is Mockito Working Fine?
@Test
public void testFormUpdate() {
// given
Form f = Mockito.mock(Form.class);
Mockito.when(
f....
@Test
public void will_getChangSecurityQuestRgtAndDetails_if_AdvUserhasRuleId25(){
User user = createUser(userId);
user.se...
@Test
public void will_getChangSecurityQuestRgtAndDetails_if_AdvUserhasRuleId25(){
// given
User user = createUser(userId)...
When a Test Name Lies
Should is Better than Test
public void testInsertNewValues() {
//given
//when
reportRepository.updat...
When a Test Name Lies
Should is Better than Test
(korrigiert)
public void shouldOverrideOldReportWithNewValues() {
//given...
Good Tests Bad Tests
Nächste SlideShare
Wird geladen in …5
×

Good Tests Bad Tests

84 Aufrufe

Veröffentlicht am

Ein Talk über gute und schlechte Tests in der Softwareentwicklung. Basierend auf dem Werk "Bad Tests, Good Tests" von Tomek Kaczanowski
Verlag: kaczanowscy.pl Tomasz Kaczanowski (11. Dezember 2013)
Sprache: Englisch
ISBN-10: 8393847133

Christof Vollrate (BILD GmbH & Co. KG)

Veröffentlicht in: Software
0 Kommentare
0 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

  • Gehören Sie zu den Ersten, denen das gefällt!

Keine Downloads
Aufrufe
Aufrufe insgesamt
84
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
3
Aktionen
Geteilt
0
Downloads
0
Kommentare
0
Gefällt mir
0
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

Good Tests Bad Tests

  1. 1. Dijkstra, The Humble Programmer 1972
  2. 2. Gute Tests ● Mit jedem Test stellen wir sicher, dass die getestete Funktionalitä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 und was zu erwarten ist. ●
  3. 3. Böse Tests ● Fragile Tests: kleine Änderung in der Implementierung => viele Tests betroffen ● Redundante Tests => Balast ● Triviale Tests ● Unvollständige Tests => falsche Sicherheit ● Tests ohne Asserts
  4. 4. 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()); }
  5. 5. No Assertions (verbessert) IResult result = format.execute(); assertThat(result.size()).isEqualTo(3); 1 Iterator iter = result.iterator(); while (iter.hasNext()) { IResult r = (IResult) iter.next(); assertThat(r.getMessage()).contains("error"); 2 }
  6. 6. 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()); } }
  7. 7. Happy Path public class FizzBuzzTest { @Test public void testMultipleOfThreeAndFivePrintsFizzBuzz() { assertEquals("FizzBuzz", FizzBuzz.getResult(15)); } @Test public void testMultipleOfThreeOnlyPrintsFizz() { assertEquals("Fizz", FizzBuzz.getResult(93)); }
  8. 8. 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(... }
  9. 9. Not Enough Testing @Test public 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); } }
  10. 10. Not Enough Testing (verbessert) Zero, One and Many
  11. 11. Auskommentieren //@Test public void testTeaserWithBildPlusMarker() { String url = urlBuilder.setBaseUrl(HTTP_START_PATH + TEASERREIHE_BILDPLUS_MARKER_PATH.setView("module".build(); driver.get(url); // Teaserreihe WebElement 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)
  12. 12. Auskommentieren (verbessert) @Test @Ignore //TODO momentan nicht testbar auf Testsystem public void testTeaserWithBildPlusMarker() { String url = urlBuilder.setBaseUrl(HTTP_START_PATH + TEASERREIHE_BILDPLUS_MARKER_PATH.setView("module".build(); driver.get(url); // Teaserreihe WebElement 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()); }
  13. 13. 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); }
  14. 14. Expecting Exceptions Anywhere (verbessert) ● Tests aufteilen (Split) ● Exception-Test Lokalisieren
  15. 15. Assertions should be Merciless @Test public void shouldRemoveEmailsByState() { //given Email pending = createAndSaveEmail("pending","content pending", "abc@def.com", Email.PENDING); Email failed = createAndSaveEmail("failed","content failed", "abc@def.com", Email.FAILED); Email sent = createAndSaveEmail("sent","content sent", "abc@def.com", Email.SENT); //when emailDAO.removeByState(Email.FAILED); //then assertThat(emailDAO.findAll()).excludes(failed); }
  16. 16. Assertions should be Merciless (verbessert) assertThat(emailDAO.findAll(), contains(pending, sent))
  17. 17. Is Mockito Working Fine? @Test public void testFormUpdate() { // given Form f = Mockito.mock(Form.class); Mockito.when( f.isUpdateAllowed()).thenReturn(true); // when boolean result = f.isUpdateAllowed(); // then assertTrue(result); }
  18. 18. @Test public 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
  19. 19. @Test public 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)
  20. 20. When a Test Name Lies Should 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); }
  21. 21. When a Test Name Lies Should 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); }

×