TDD - Bring Development to the next Level

Warum Tests? - Jeder macht Fehler

  • Fehlerquoten pro 1000 Zeilen Code nach QA
    • Industrie-Durchschnitt: 15 - 50
    • Microsoft - Software: 10 - 20 während Entwicklung / ca. 0,5 wenn produktiv
    • Sicherheitsrelevante Software: 0 - 0,2
      (http://www.mayerdan.com/ruby/2012/11/11/bugs-per-line-of-code-ratio)
  • Fehlerquote pro 1000 Zeilen Code vor QA um ca Faktor 4 höher

Warum Testdriven? - 9 Thesen

1. If you can’t write a test for something you don’t understand it

2. Without a regression test you can’t clean the code

3. Fast feedback cycles save time and money

4. You are going to test it anyway, spend the time to do it right

5. Without tests the next developer will need a word doc and a lot of luck

6. Evolutionary design is possible without fear

7. You will actually write less code

8. It actually makes your work more enjoyable

9. You will describe how software should work

http://toranbillups.com/blog/archive/2010/04/22/How-test-first-development-changed-my-life/

Warum Testdriven? - Ausreden die nicht zählen

1. ich habe keine Zeit Tests zu schreiben

 

2. Tests kann ich auch später noch schreiben

 

3. Der Code ist nicht testbar

 

4. Der Kunde zahlt mir die Entwicklung von Tests nicht

 

Warum Testdriven? - Ausreden die zählen

Hier gibts nichts zu sehen

Warum Testdriven? - Later equals never.

Weil:

1. Auch später steht keine Zeit zur Verfügung

2. Code, der nicht tdd entwickelt wurde ist meist schwer zu testen.

     Man braucht also noch mehr Zeit für die Tests (Und wir haben        ja bekanntlich keine Zeit...;-))

3. Es wird vergessen

4. Werden Tests weg gelassen um pünktlich zu liefern, wird dem       Kunden und dem Management ein falsche Bild vermittelt

Warum Testdriven? - Was hat der Kunde davon?

1. Features die bezahlt wurden, sind gewährleistet

    (=> das hat doch schon funktioniert)

2. Neue Features können "günstiger" umgesetzt werden

3. Wenn gewünscht, können Kunden Akzeptanz-Tests (z.B.
    Gherkin) selbst schreiben

4. Über Metriken und Berichte können tiefgreifende Informationen über die Qualität der Software ermittelt werden

Warum Testdriven? - Was hat der Chef davon?

1. Es werden deutlich weniger Bug-/Hotfixes erscheinen
    => Kosten für Software-Wartung wird gesenkt

2. Bugs die gefixt werden, können in Zukunft sicher
    ausgeschlossen werden, wenn mit dem Fix ausreichend Tests
    entstehen

3. Durch Tests sind Features spezifiziert. => Diskussionen um versprochene Features können reduziert werden

Warum Testdriven? - Und was hab ich davon?

1. Die Sicherheit, mit Code-Änderungen bestehende
    Funktionalität nicht kaputt zu machen

2. Die Möglichkeit Code jederzeit zu refaktorieren

3. Es entsteht quasi automatisch wartbarer Code

4. Die Möglichkeit der Automatisierung (CI etc)

5. LevelUp als Entwickler

Wie Testdriven entwicklen? - Der erste Schritt ist der schwerste

1. Was will ich testen?

2. Wie kann ich es testen?

3. Wie gehe ich mit Abhängigkeiten um?

4. Welche Tools sind für mich geeignet?

Wie Testdriven entwicklen? - Welche Tools gibt es?

1. Klassische UNIT-Test-Frameworks:

    PHPUnit / JUnit etc

2. Alternative/moderne UNIT-Test-Frameworks:

    PHPSpec / Rspec etc

3. TDD+ / BDD - Frameworks

     Behat / Cucumber (eher für funktionale / acceptance Tests)

4. Frameworks die versuchen das alles zu vereinen

    z.B. Codeception

Wie Testdriven entwicklen? - Welches Framework ist das richtige?

Unit-Tests:

- Für den Einstieg klassische Frameworks am besten geeignet

- Mocking mit einem Mocking-Framework wie Prophecy (php)

 

Funktionale-Tests:

- Behat 

- Klassische Frameworks (PHPUnit)

 

Das Komplett-Paket:

- Codeception

Wie Testdriven entwicklen? - Übung macht den Meister

- zusätzlicher (Zeit-)Aufwand wird mit der Zeit deutlich weniger

- kleine zugängliche Probleme erleichtern den Einstieg

- bei komplexeren Aufgaben erst Werkzeuge mit TDD entwickeln
   => Lösung ist dann meist eine Verbindung der Werkzeuge

 

Wie Testdriven entwicklen? - Wie ist ein Unit-Test aufgebaut?

- möglichst klar und leicht verständlich

- Aufteilbar in 3 Phasen

  1. Testvorbereitung (längere Vorbereitungen in Methode auslagern)
  2. Beschreibung der Erwartungen
  3. Vergleich von Erwartung und tatsächlichem Ergebnis

Wie Testdriven entwicklen? - Mocking der Schlüssel für TDD

- durch Mocking können Abhängigkeiten aufgelöst werden

- das Verhalten der "gemockten" Objekte kann gesteuert werden

- Jedes Objekt in einem Test, dass nicht das getestete Unit selbst ist, muss gemockt werden

- Es können nicht nur Klassen sondern auch Interfaces gemockt werden

- Nur Objekte, die nicht in dem zu testenden Unit erstellt werden, können gemockt werden (Factory-Pattern kann hier sehr hilfreich sein)

Wie Testdriven entwicklen? - Wie viele Tests sind genug?

- Jede Klasse sollte getestet sein

     - innerhalb jeder Klasse sollte jede public-Methode getestet sein

          - innerhalb jeder Methode sollte jeder Code-Pfad getestet sein

 

- Man hat genug Tests wenn 95-100% Testabdeckung auf unit-Ebene erreicht ist

- Man hat ausreichend Tests wenn 80-95% Testabdeckung erreicht ist

Wie Testdriven entwicklen? - Ok, ich hab jetzt Unit-Tests, bin ich jetzt fertig?

Nein!

 

- Unit-Tests sind ein solides und unverzichtbares Fundament, aber

- Unit-Tests sagen nichts darüber aus ob die Applikation insgesamt
  funktioniert, denn

  - Sie testen nur ein Unit und

  - niemals das Zusammenspiel mehrerer
     "echter" Komponenten

Wie Testdriven entwicklen? - Ok, aber wie geht es weiter?

1. Funktionale Tests

2. Acceptance Tests

3. Automatisierte Testing-Pipeline

4. Automatisiertes Deployment

Praktischer Teil

Codewars - Kata

Gegeben sei ein Array das mit folgenden Regeln gebaut wird:

1. $array[0] = 1

2. Für jedes Item `x` in $array gilt:
2.1 füge ein Item `y` dem Array hinzu, das 2 * `x` + 1 entspricht

2.2 fuge ein Item `z` dem Array hinzu, das 3 * `x` + 1 entspricht

Beispiel:
$array = [1, 3, 4, 7, 9, 10, 13, 15, 19, 21, 22, 27, ...]

$array = [1, 3, 4, 7, 9, 10, 13, 15, 19, 21, 22, 27, ...]

$array = [1, 3, 4, 7, 9, 10, 13, 15, 19, 21, 22, 27, ...]

$array = [1, 3, 4, 7, 9, 10, 13, 15, 19, 21, 22, 27, ...]

Aufgabe:

Schreibe eine Funktion, die zu einer gegeben Position den Eintrag aus $array zurück gibt. `getPosition(10) == 22`

mögliche Tests

public function it_returns_1_as_first_position()

public function it_returns_4_as_third_position()

public function it_throws_exception_for_negative_values()

public function it_builds_correct_array_for_x_4()

 

Ausbau-Stufen:

Klasse die sich um die Erstellung des Arrays kümmert

    -> könnte das Array so groß bauen, wie es sein muss

Klasse die diese Array für die Ermittlung der Einträge verwendet

Made with Slides.com