Behaviour-Driven Development

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    2 Favorites

    Behaviour-Driven Development - Presentation Transcript

    1. 2. Juni 2008
    2. Johannes Link
    3. Heidelberg
    4. Mein eigener Chef
    5. Mein eigener Chef (Extremer) Softwareentwickler
    6. Mein eigener Chef (Extremer) Softwareentwickler (Agiler) Coach
    7. Mein eigener Chef (Extremer) Softwareentwickler (Agiler) Coach Testgetrieben
    8. johanneslink.net
    9. Behaviour Driven Development
    10. Behaviour Driven Development Was. Warum. Wie.
    11. TDD
    12. Testgetriebene Entwicklung
    13. Test / Code / Refactor Tests Fail Tests OK
    14. Test / Code / Refactor 1) Test hinzufügen Tests Fail Tests OK
    15. Test / Code / Refactor 1) Test hinzufügen Tests Fail Tests OK 2) Test erfüllen
    16. Test / Code / Refactor 1) Test hinzufügen 3) Code Tests Fail Tests OK vereinfachen 2) Test erfüllen
    17. Warum TDD?
    18. Regressionstests Warum TDD?
    19. Regressionstests Weniger Bugs Warum TDD?
    20. Regressionstests Inkrementelles Vorgehen Weniger Bugs Warum TDD?
    21. Regressionstests Inkrementelles Vorgehen Designfokus Weniger Bugs Warum TDD?
    22. Regressionstests Inkrementelles Vorgehen Entkopplung Designfokus Weniger Bugs Warum TDD?
    23. Regressionstests Inkrementelles Vorgehen Entkopplung Designfokus Schnittstellen Weniger Bugs Warum TDD?
    24. Regressionstests Inkrementelles Vorgehen Entkopplung Designfokus Schnittstellen Weniger Bugs Warum TDD? Ausführbare Spezifikation?
    25. Regressionstests Inkrementelles Vorgehen Entkopplung Designfokus Schnittstellen Weniger Bugs Warum TDD? Ausführbare Spezifikation? Technische Dokumentation?
    26. Typische TDD-Fragen
    27. Wo fange ich an? Typische TDD-Fragen
    28. Wo fange ich an? Typische TDD-Fragen Wo höre ich auf?
    29. Wo fange ich an? Wie nenne ich die Testklasse? Typische TDD-Fragen Wo höre ich auf?
    30. Wo fange ich an? Wie nenne ich die Testklasse? Typische TDD-Fragen Wie nenne ich die Testmethode? Wo höre ich auf?
    31. Wo fange ich an? Wie nenne ich die Testklasse? Wie viele Assertions pro Testfall? Typische TDD-Fragen Wie nenne ich die Testmethode? Wo höre ich auf?
    32. Wo fange ich an? Welche Objekte erzeuge ich im Setup? Wie nenne ich die Testklasse? Wie viele Assertions pro Testfall? Typische TDD-Fragen Wie nenne ich die Testmethode? Wo höre ich auf?
    33. Wo fange ich an? Welche Objekte erzeuge ich im Setup? Wie nenne ich die Testklasse? Wie viele Assertions pro Testfall? Typische TDD-Fragen Wie nenne ich die Benötigt jede Klasse/ Testmethode? Methode eine eigene Test-Klasse/-Methode? Wo höre ich auf?
    34. Wo fange ich an? Welche Objekte erzeuge ich im Setup? Wie nenne ich die Testklasse? Wie viele Assertions pro Testfall? Typische TDD-Fragen Wie nenne ich die Benötigt jede Klasse/ Testmethode? Methode eine eigene Test-Klasse/-Methode? Wie gruppiere und organisiere ich meine Wo höre ich auf? Testfälle?
    35. Schwammige Regeln
    36. Heuristiken
    37. Beispiel...
    38. public class KontoTest { @Test public void neuesKonto() { Konto konto = new Konto(\"Johannes\"); assertEquals(\"Johannes\", konto.getInhaber()); assertEquals(0, konto.getSaldo()); } }
    39. public class KontoTest... private Konto konto; @Before public void init() { konto = new Konto(\"Johannes\"); } @Test public void neuesKonto() { ... } @Test public void einzahlung() { konto.zahleEin(100); assertEquals(100, konto.getSaldo()); konto.zahleEin(99); assertEquals(199, konto.getSaldo()); }
    40. public class KontoTest... @Test public void einzahlung() { konto.zahleEin(100); assertEquals(100, konto.getSaldo()); konto.zahleEin(99); assertEquals(199, konto.getSaldo()); } @Test(expected = IllegalArgumentException.class) public void negativeEinzahlungNichtErlaubt() { konto.zahleEin(-1); }
    41. public class KontoTest... @Test public void einzahlung() { konto.zahleEin(100); assertEquals(100, konto.getSaldo()); konto.zahleEin(99); assertEquals(199, konto.getSaldo()); } @Test(expected = IllegalArgumentException.class) public void negativeEinzahlungNichtErlaubt() { konto.zahleEin(100); konto.zahleEin(-1); }
    42. public class KontoTest... @Test public void einzahlung() { konto.zahleEin(100); assertEquals(100, konto.getSaldo()); konto.zahleEin(99); assertEquals(199, konto.getSaldo()); } @Test(expected = IllegalArgumentException.class) public void negativeEinzahlungNichtErlaubt() { konto.zahleEin(100); konto.zahleEin(-1); }
    43. public class NeuesKontoTest... @Test public void inhaber()... @Test public void anfangssaldo()... @Test public void ersteEinzahlung()... public class KontoMitPositivemSaldoTest... private static final int ANFANGSSALDO = 100; @Test public void einzahlung() { konto.zahleEin(99); assertEquals(99 + ANFANGSSALDO, konto.getSaldo()); } @Test(expected = IllegalArgumentException.class) public void negativeEinzahlungNichtErlaubt() { konto.zahleEin(-1); }
    44. Gewünschtes Kontoverhalten • Ein neues Konto • soll den Namen seines Inhabers mitteilen können • soll einen Saldo von 0 EUR haben • soll einen positiven Anfangssaldo eingezahlt bekommen können • Ein Konto mit positivem Saldo • soll den Saldo bei Einzahlungen entsprechenden vergrößern • soll bei negativen Einzahlungen eine IllegalArgumentException auslösen
    45. public class EinNeuesKonto... @Test public void sollInhaberLiefern()... @Test public void sollAnfangssaldoNullHaben()... @Test public void sollErsteEinzahlungErlauben()... public class EinKontoMitPositivemSaldo... @Test public void sollBeiPositiverEinzahlungSaldoErhöhen() { konto.zahleEin(99); assertThat(konto.getSaldo(), is(ANFANGSSALDO + 99)); //assertEquals(99 + ANFANGSSALDO, konto.getSaldo()); } @Test public void sollBeiNegativerEinzahlung- IllegalArgument-ExceptionWerfen()...
    46. public class EinNeuesKonto... @Test public void sollInhaberLiefern()... @Test public void sollAnfangssaldoNullHaben()... @Test public void sollErsteEinzahlungErlauben()... public class EinKontoMitPositivemSaldo... @Test public void sollBeiPositiverEinzahlungSaldoErhöhen() { konto.zahleEin(99); assertThat(konto.getSaldo(), is(ANFANGSSALDO + 99)); //assertEquals(99 + ANFANGSSALDO, konto.getSaldo()); } @Test public void sollBeiNegativerEinzahlung- IllegalArgument-ExceptionWerfen()...
    47. Dan North
    48. http://dannorth.net/introducing-bdd
    49. BDD: Vom Test zum Verhalten
    50. Die Sprache beeinflusst unser Verhalten
    51. Die Sprache des Testen
    52. Die Sprache des Testen Testfälle, Testen, Beweisen, Sicherstellen, Programmeinheit, Korrektheit, Vorbedingungen
    53. Die Sprache des Testen Testfälle, Testen, Beweisen, Sicherstellen, Programmeinheit, Korrektheit, Vorbedingungen Wir versuchen mit Testfällen zu beweisen, dass eine Programmeinheit unter bestimmten Vorbedingungen korrekt arbeitet
    54. Die Sprache des Testen Testfälle, Testen, Beweisen, Sicherstellen, Programmeinheit, Korrektheit, Vorbedingungen Wir versuchen mit Testfällen zu beweisen, dass eine Programmeinheit unter bestimmten Vorbedingungen korrekt arbeitet Set Up - Stimulate - Assert
    55. Die Sprache des BDD
    56. Die Sprache des BDD User Stories, Szenario, Spezifikation,Verhalten, Kontext
    57. Die Sprache des BDD User Stories, Szenario, Spezifikation,Verhalten, Kontext Wir spezifizieren in Szenarien, wie sich Dinge in einem bestimmten Kontext verhalten sollen, um eine User Story zu erfüllen
    58. Die Sprache des BDD User Stories, Szenario, Spezifikation,Verhalten, Kontext Wir spezifizieren in Szenarien, wie sich Dinge in einem bestimmten Kontext verhalten sollen, um eine User Story zu erfüllen Given - When - Then
    59. Wie funktioniert meine Klasse?
    60. Wie funktioniert meine Klasse?
    61. Wie funktioniert meine Klasse? Was soll mein Programm tun?
    62. JBehave Instinct JDave Werkzeuge GSpec easyb RSpec NSpec
    63. Instinct http://code.google.com/p/instinct/
    64. @RunWith(InstinctRunner.class) public class EinKontoMitPositivemSaldo { private static final int ANFANGSSALDO = 42; @Subject Konto konto; @BeforeSpecification void initialisiere() { konto = new Konto(\"Irgendwer\"); konto.zahleEin(ANFANGSSALDO); } @Specification(expectedException = IllegalArgumentException.class) void sollBeiNegativerEinzahlungIllegalArgumentExceptionWerfen() { konto.zahleEin(-1); } @Specification void sollBeiPositiverEinzahlungenSaldoErhöhen() { konto.zahleEin(1); expect.that(konto.getSaldo()).isEqualTo(ANFANGSSALDO + 1); konto.zahleEin(100); expect.that(konto.getSaldo()).isEqualTo(ANFANGSSALDO + 101); } }
    65. GSpec http://groovy.codehaus.org/ Using+GSpec+with+Groovy
    66. def ein = new GSpecBuilderRunner() ein.context('Ein neues Konto') { def INHABER = \"Johannes\" initially { ein.neuesKonto = new Konto(INHABER) } specify('soll den Inhaber als Property liefern') { ein.neuesKonto.inhaber.should_equal INHABER } specify('soll 0 EUR Anfangssaldo haben') {..} specify('soll positive Einzahlungen bekommen können') {..} } ein.context('Ein Konto mit positivem Saldo') { specify('soll bei positiver Einzahlungen den Saldo erhöhen') {..} specify('''soll bei negativer Einzahlungen IllegalArgumentException werfen''') {..} }
    67. def ein = new GSpecBuilderRunner() ein.context('Ein neues Konto') { def INHABER = \"Johannes\" initially { ein.neuesKonto = new Konto(INHABER) } specify('soll den Inhaber als Property liefern') { ein.neuesKonto.inhaber.should_equal INHABER } specify('soll 0 EUR Anfangssaldo haben') {..} Ein neues Konto soll den Inhaber als Property liefern specify('soll positive Einzahlungen bekommen können') {..} } Ein neues Konto soll 0 EUR Anfangssaldo haben ein.context('Ein Konto mit positivem Saldo') { Ein neues Konto specify('soll bei positiver Einzahlungen den Saldo erhöhen') {..} soll positive Einzahlungen bekommen können Ein Konto mit positivem Saldo specify('''soll bei negativer Einzahlungen soll bei positiver Einzahlungen den Saldo erhöhen IllegalArgumentException werfen''') {..} Ein Konto mit positivem Saldo } soll bei negativer Einzahlungen IllegalArgumentException werfen
    68. easyb http://www.easyb.org/
    69. scenario \"Konto mit ANFANGSSALDO\", { def ANFANGSSALDO = 42 def BETRAG = 101 given \"ein Konto mit SALDO\", { konto = new Konto(\"irgendwer\") konto.zahleEin(ANFANGSSALDO) } when \"ein BETRAG eingezahlt wird\", { konto.zahleEin(BETRAG) } then \"der Saldo entspricht ANFANGSSALDO + BETRAG\", { konto.getSaldo().shouldBe ANFANGSSALDO + BETRAG } } scenario \"Negative Einzahlung\", { given \"ein Konto\", {...} when \"ein negativer Betrag eingezahlt wird\", { negativeEinzahlung = { konto.zahleEin(-1) } } then \"eine IllegalArgumentException soll geworfen werden\", { ensureThrows(IllegalArgumentException) { negativeEinzahlung() } } }
    70. scenario \"Konto mit ANFANGSSALDO\", { def ANFANGSSALDO = 42 def BETRAG = 101 given \"ein Konto mit SALDO\", {einzelnes konto Story: konto = new Konto(\"irgendwer\") scenario Neues Konto konto.zahleEin(ANFANGSSALDO) given ein neues Konto } then der Inhaber ist als Property verfŸgbar when \"ein BETRAG eingezahltthen der { wird\", Anfangssaldo ist 0 konto.zahleEin(BETRAG) } scenario Einfache Einzahlung then \"der Saldo entspricht given ein leeres BETRAG\", { ANFANGSSALDO + Konto konto.getSaldo().shouldBe ANFANGSSALDOeingezahlt wird when ein BETRAG + BETRAG } then der Saldo entspricht dem BETRAG } scenario Konto mit ANFANGSSALDO scenario \"Negative Einzahlung\", { ein Konto mit SALDO given given \"ein Konto\", {...} when ein BETRAG eingezahlt wird when \"ein negativer Betrag then der Saldo entspricht ANFANGSSALDO + BETRAG eingezahlt wird\", { negativeEinzahlung = { konto.zahleEin(-1) } } scenario Negative Einzahlung given ein Konto then \"eine IllegalArgumentException soll geworfen werden\", { ensureThrows(IllegalArgumentException) { Betrag eingezahlt wird } when ein negativer negativeEinzahlung() then eine IllegalArgumentException } soll geworfen werden }
    71. Veränderter Fokus
    72. Veränderter Fokus • Weg vom Wie - hin zum Was • User Stories -> Szenarios • Anfangszustand pro Szenario • Einzelne Zusicherungen
    73. Veränderter Fokus • Weg vom Wie - hin zum Was • User Stories -> Szenarios • Anfangszustand pro Szenario • Einzelne Zusicherungen • Weg von der Unit - hin zum Verhalten • Geringere Kopplung zwischen Code und Spezifikation • Refactoring vereinfacht
    74. Veränderter Fokus • Weg vom Wie - hin zum Was • User Stories -> Szenarios • Anfangszustand pro Szenario • Einzelne Zusicherungen • Weg von der Unit - hin zum Verhalten • Geringere Kopplung zwischen Code und Spezifikation • Refactoring vereinfacht • Aber: Aussagekräftiges Reporting erfordert Investition in gute Texte
    75. „Prozess“
    76. Naives TDD
    77. JDK
    78. Technik JDK
    79. Domänenmodell Technik JDK
    80. Applikationsmodell Domänenmodell Technik JDK
    81. Benutzerschnittstelle Applikationsmodell Domänenmodell Technik JDK
    82. Anforderungen Benutzerschnittstelle Applikationsmodell Domänenmodell Technik JDK
    83. Von Außen nach Innen
    84. Von Außen nach Innen Vom Bekannten zum Unbekannten
    85. JDK
    86. Anforderungen JDK
    87. Anforderungen Benutzerschnittstelle JDK
    88. Anforderungen Benutzerschnittstelle Applikationsmodell JDK
    89. Anforderungen Benutzerschnittstelle Applikationsmodell Domänenmodell JDK
    90. Anforderungen Benutzerschnittstelle Applikationsmodell Domänenmodell Technik JDK
    91. JDK
    92. Anforderungen JDK
    93. Anforderungen Domänenmodell JDK
    94. Anforderungen Benutzerschnittstelle Domänenmodell JDK
    95. Anforderungen Benutzerschnittstelle Applikationsmodell Domänenmodell JDK
    96. Anforderungen Benutzerschnittstelle Applikationsmodell Domänenmodell Technik JDK
    97. Domänenmodell
    98. Anforderungen Domänenmodell
    99. Anforderungen Domänenmodell Domänen- analyse
    100. Domain Driven Design Eric Evans
    101. Beispiel: Konten-GUI
    102. Story: konten gui
    103. Story: konten gui scenario Leere Kontenliste anzeigen given eine Bank ohne Konten when die Konten-Applikation gestartet wird then dann ist das Konten-Fenster offen then ist die Liste der angezeigten Konten leer
    104. Story: konten gui scenario Leere Kontenliste anzeigen given eine Bank ohne Konten when die Konten-Applikation gestartet wird then dann ist das Konten-Fenster offen then ist die Liste der angezeigten Konten leer scenario Gefüllte Kontenliste anzeigen given eine Bank mit drei Konten when die Konten-Applikation gestartet wird then werden im Konten-Fenster drei Konten mit Inhaber und Saldo angezeigt
    105. Story: konten gui scenario Leere Kontenliste anzeigen given eine Bank ohne Konten when die Konten-Applikation gestartet wird then dann ist das Konten-Fenster offen then ist die Liste der angezeigten Konten leer scenario Gefüllte Kontenliste anzeigen given eine Bank mit drei Konten when die Konten-Applikation gestartet wird then werden im Konten-Fenster drei Konten mit Inhaber und Saldo angezeigt scenario Löschen eines Kontos aus Kontenliste given ein offenes Konten-Fenster mit drei Konten when das erste Konto angewählt wird when der Löschen-Button gedrückt wird then verschwindet das Konto aus der Liste then wird an der Bank das Konto gelöscht
    106. scenario \"Leere Kontenliste anzeigen\", { given \"eine Bank ohne Konten\" when \"die Konten-Applikation gestartet wird\" then \"dann ist das Konten-Fenster offen \" and \"ist die Liste der angezeigten Konten leer\" }
    107. scenario \"Leere Kontenliste anzeigen\", { given \"eine Bank ohne Konten\", { bank = new Bank() } when \"die Konten-Applikation gestartet wird\" then \"dann ist das Konten-Fenster offen \" and \"ist die Liste der angezeigten Konten leer\" }
    108. import static org.mockito.Mockito.* scenario \"Leere Kontenliste anzeigen\", { given \"eine Bank ohne Konten\", { bank = new Bank() mock(IBank) } when \"die Konten-Applikation gestartet wird\" then \"dann ist das Konten-Fenster offen \" and \"ist die Liste der angezeigten Konten leer\" }
    109. import static org.mockito.Mockito.* scenario \"Leere Kontenliste anzeigen\", { given \"eine Bank ohne Konten\", { bank = new Bank() mock(IBank) } when \"die Konten-Applikation gestartet wird\" then \"dann ist das Konten-Fenster offen \" and \"ist die Liste der angezeigten Konten leer\" } public interface IBank { }
    110. import static org.mockito.Mockito.* scenario \"Leere Kontenliste anzeigen\", { given \"eine Bank ohne Konten\", { bank = mock(IBank) stub(bank.getKonten()).toReturn([]) } when \"die Konten-Applikation gestartet wird\" then \"dann ist das Konten-Fenster offen \" and \"ist die Liste der angezeigten Konten leer\" }
    111. import static org.mockito.Mockito.* scenario \"Leere Kontenliste anzeigen\", { given \"eine Bank ohne Konten\", { bank = mock(IBank) stub(bank.getKonten()).toReturn([]) } when \"die Konten-Applikation gestartet wird\" then \"dann ist das Konten-Fenster offen \" and \"ist die Liste der angezeigten Konten leer\" } public interface IBank { List<Konto> getKonten(); }
    112. import static org.mockito.Mockito.* scenario \"Leere Kontenliste anzeigen\", { given \"eine Bank ohne Konten\", { bank = mock(IBank) stub(bank.getKonten()).toReturn([]) } when \"die Konten-Applikation gestartet wird\", { gui = new KontenApp(bank) gui.setVisible(true) } then \"dann ist das Konten-Fenster offen \" and \"ist die Liste der angezeigten Konten leer\" }
    113. import static org.mockito.Mockito.* scenario \"Leere Kontenliste anzeigen\", { given \"eine Bank ohne Konten\", { bank = mock(IBank) stub(bank.getKonten()).toReturn([]) } when \"die Konten-Applikation gestartet wird\", { gui = new KontenApp(bank) gui.setVisible(true) } then \"dann ist das Konten-Fenster offen \" public class KontenApp extends JFrame { and \"ist die Liste der angezeigten Konten leer\" public KontenApp(IBank bank) { } } }
    114. import static org.mockito.Mockito.* scenario \"Leere Kontenliste anzeigen\", { given \"eine Bank ohne Konten\", { bank = mock(IBank) stub(bank.getKonten()).toReturn([]) } when \"die Konten-Applikation gestartet wird\", { gui = new KontenApp(bank) gui.setVisible(true) } then \"dann ist das Konten-Fenster offen \", { frame = new JFrameOperator(\"Meine Konten\") } and \"ist die Liste der angezeigten Konten leer\" }
    115. import static org.mockito.Mockito.* scenario \"Leere Kontenliste anzeigen\", { given \"eine Bank ohne Konten\", { bank = mock(IBank) stub(bank.getKonten()).toReturn([]) } when \"die Konten-Applikation gestartet wird\", { gui = new KontenApp(bank) gui.setVisible(true) } then \"dann ist das Konten-Fenster offen \", { frame = new JFrameOperator(\"Meine Konten\") } public \"ist die Liste der angezeigten Konten leer\" and class KontenApp extends JFrame { } public KontenApp(IBank bank) { super(\"Meine Konten\"); } }
    116. import static org.mockito.Mockito.* scenario \"Leere Kontenliste anzeigen\", { given \"eine Bank ohne Konten\", { bank = mock(IBank) stub(bank.getKonten()).toReturn([]) } when \"die Konten-Applikation gestartet wird\", { gui = new KontenApp(bank) gui.setVisible(true) } then \"dann ist das Konten-Fenster offen \", { frame = new JFrameOperator(\"Meine Konten\") } and \"ist die Liste der angezeigten Konten leer\", { table = new JTableOperator(frame); table.model.rowCount.shouldBe 0 } }
    117. public class KontenApp extends JFrame { private JTable kontenTable; private final IBank bank; import static org.mockito.Mockito.* public KontenApp(IBank bank) { super(\"Meine Konten\"); scenario \"Leere Kontenliste anzeigen\", { this.bank = bank; given \"eine Bank ohne Konten\", { createLayout(); bank = mock(IBank)} stub(bank.getKonten()).toReturn([]) private void createLayout() { } ... createKontenTable(); when \"die Konten-Applikation gestartet wird\", { fillKontenTable(); gui = new KontenApp(bank) pack(); gui.setVisible(true) } } private void fillKontenTable() { then \"dann ist das Konten-Fenster offen \", { ((KontenTableModel) kontenTable.getModel()). setKonten(bank.getKonten()); frame = new JFrameOperator(\"Meine Konten\") } } } and \"ist die Liste der angezeigten Konten leer\", { table = new JTableOperator(frame); table.model.rowCount.shouldBe 0 } }
    118. public class KontenApp extends JFrame { private JTable kontenTable; private final IBank bank; import static org.mockito.Mockito.* public KontenApp(IBank bank) { super(\"Meine Konten\"); scenario \"Leere Kontenliste anzeigen\", { this.bank = bank; given \"eine Bank ohne Konten\", { createLayout(); bank = mock(IBank)} stub(bank.getKonten()).toReturn([]) private void createLayout() { } ... createKontenTable(); when \"die Konten-Applikation gestartet wird\", { fillKontenTable(); gui = new KontenApp(bank) pack(); gui.setVisible(true) } } private void fillKontenTable() { then \"dann ist das Konten-Fenster offen \", { ((KontenTableModel) kontenTable.getModel()). setKonten(bank.getKonten()); frame = new JFrameOperator(\"Meine Konten\") } } } and \"ist die Liste der angezeigten Konten leer\", { table = new JTableOperator(frame); table.model.rowCount.shouldBe 0 } gui.dispose() }
    119. Dummies und Mocks werden wichtiger
    120. Dummies und Mocks werden wichtiger import static org.mockito.Mockito.* scenario \"Leere Kontenliste anzeigen\", { given \"eine Bank ohne Konten\", { bank = mock(IBank) stub(bank.getKonten()).toReturn([]) } ... }
    121. scenario \"Löschen eines Kontos aus Kontenliste\", { given \"ein offenes Konten-Fenster mit drei Konten\", {...} when \"das erste Konto angewählt wird\", {...} and \"der Löschen-Button gedrückt wird\", { deleteButton = new JButtonOperator(frame, \"Lösche Konto\") deleteButton.push() } then \"verschwindet das Konto aus der Liste\", { checkKontenliste(table.model, [[\"in1\", 10], [\"in2\", 20]]) } and \"wird an der Bank das Konto gelöscht\", { ??? } }
    122. import static org.easymock.EasyMock.* scenario \"Löschen eines Kontos aus Kontenliste\", { given \"ein offenes Konten-Fenster mit drei Konten\", {...} when \"das erste Konto angewählt wird\", {...} and \"der Löschen-Button gedrückt wird\", { expect(bank.loescheKonto(dreiKonten[0])) deleteButton = new JButtonOperator(frame, \"Lösche Konto\") deleteButton.push() } then \"verschwindet das Konto aus der Liste\", { checkKontenliste(table.model, [[\"in1\", 10], [\"in2\", 20]]) } and \"wird an der Bank das Konto gelöscht\", { verify(bank) } }
    123. import static org.mockito.Mockito.* scenario \"Löschen eines Kontos aus Kontenliste\", { given \"ein offenes Konten-Fenster mit drei Konten\", {...} when \"das erste Konto angewählt wird\", {...} and \"der Löschen-Button gedrückt wird\", { deleteButton = new JButtonOperator(frame, \"Lösche Konto\") deleteButton.push() } then \"verschwindet das Konto aus der Liste\", { checkKontenliste(table.model, [[\"in1\", 10], [\"in2\", 20]]) } and \"wird an der Bank das Konto gelöscht\", { verify(bank).loescheKonto(dreiKonten[0]) } }
    124. Macht BDD Akzeptanztests überflüssig?
    125. Ziele von Akzeptanztests
    126. Ziele von Akzeptanztests • Funktionale Tests aus Kundensicht
    127. Ziele von Akzeptanztests • Funktionale Tests aus Kundensicht • Sprechen die Sprache des Kunden
    128. Ziele von Akzeptanztests • Funktionale Tests aus Kundensicht • Sprechen die Sprache des Kunden • Konkrete Beispiele der Verwendung
    129. Ziele von Akzeptanztests • Funktionale Tests aus Kundensicht • Sprechen die Sprache des Kunden • Konkrete Beispiele der Verwendung • Können vom Kunden geschrieben und geändert werden
    130. Ziele von Akzeptanztests • Funktionale Tests aus Kundensicht • Sprechen die Sprache des Kunden • Konkrete Beispiele der Verwendung • Können vom Kunden geschrieben und geändert werden • Testen (überwiegend) das System als Ganzes
    131. Sind diese Ziele auch mit BDD erreichbar?
    132. scenario Gefüllte Kontenliste anzeigen given eine Bank mit drei Konten when die Konten-Applikation gestartet wird then werden im Konten-Fenster drei Konten mit Inhaber und Saldo angezeigt scenario Löschen eines Kontos aus Kontenliste given ein offenes Konten-Fenster mit drei Konten when das erste Konto angewählt wird when der Löschen-Button gedrückt wird then verschwindet das Konto aus der Liste then wird an der Bank das Konto gelöscht
    133. Funktionale Tests aus Kundensicht Sprechen die Sprache des Kunden Konkrete Beispiele der Verwendung Können vom Kunden geschrieben und geändert werden Testen (überwiegend) das System als Ganzes
    134.  Funktionale Tests aus Kundensicht Sprechen die Sprache des Kunden Konkrete Beispiele der Verwendung Können vom Kunden geschrieben und geändert werden Testen (überwiegend) das System als Ganzes
    135.  Funktionale Tests aus Kundensicht  Sprechen die Sprache des Kunden Konkrete Beispiele der Verwendung Können vom Kunden geschrieben und geändert werden Testen (überwiegend) das System als Ganzes
    136.  Funktionale Tests aus Kundensicht  Sprechen die Sprache des Kunden  Konkrete Beispiele der Verwendung Können vom Kunden geschrieben und geändert werden Testen (überwiegend) das System als Ganzes
    137.  Funktionale Tests aus Kundensicht  Sprechen die Sprache des Kunden  Konkrete Beispiele der Verwendung Können vom Kunden geschrieben und   geändert werden Testen (überwiegend) das System als Ganzes
    138.  Funktionale Tests aus Kundensicht  Sprechen die Sprache des Kunden  Konkrete Beispiele der Verwendung Können vom Kunden geschrieben und   geändert werden  Testen (überwiegend) das System als Ganzes
    139. BDD ist...
    140. BDD ist... • „Richtiges TDD“ leicht(er) gemacht • Veränderung der Sprache • Anpassung der Tools
    141. BDD ist... • „Richtiges TDD“ leicht(er) gemacht • Veränderung der Sprache • Anpassung der Tools • Fokus auf Spezifikation und Verhalten
    142. BDD ist... • „Richtiges TDD“ leicht(er) gemacht • Veränderung der Sprache • Anpassung der Tools • Fokus auf Spezifikation und Verhalten • Vom Bekannten zum Unbekannten • Dummies und Mocks werden wichtiger
    143. BDD ist... • „Richtiges TDD“ leicht(er) gemacht • Veränderung der Sprache • Anpassung der Tools • Fokus auf Spezifikation und Verhalten • Vom Bekannten zum Unbekannten • Dummies und Mocks werden wichtiger • Das Domänenmodell im Mittelpunkt
    144. Web-Ressourcen • http://jbehave.org/ • http://www.jdave.org/ • http://rspec.info/ • http://nspec.tigris.org/ • http://www.domaindrivendesign.org/ • http://mockito.org/ • http://jemmy.netbeans.org/
    145. Fragen und Anmerkungen?

    + jlinkjlink, 2 years ago

    custom

    4935 views, 2 favs, 0 embeds more stats

    A talk given in german about BDD, its relationship more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 4935
      • 4935 on SlideShare
      • 0 from embeds
    • Comments 0
    • Favorites 2
    • Downloads 0
    Most viewed embeds

    more

    All embeds

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories