Im Oktober 2012 startete die Ringvorlesung "Informatik in der Praxis: Wirtschaft und Industrie" an der Universität Leipzig. Am 08. Januar 2013 übernahm der 3. Praxispartner FIO SYSTEMS AG den dritten Aufgabenkomplex zum Thema „Unit Tests und Test Driven Development in der Praxis – alles grün?“.
Die Community ITmitte.de und die Universität Leipzig machen sich stark für Mitteldeutschland. Gemeinsam suchen IT- und Softwareunternehmen aus Halle, Leipzig, Jena, Erfurt, Bitterfeld-Wolfen, Zeitz, Leuna und Markkleeberg die Fachkräfte von morgen für ihre Jobs, Stellen, Praktika-und Ausbildungsangebote.
3. FIO® SYSTEMS AG
Unit Tests
• Testen automatisiert kleine, isolierte Einheiten (Units)
eines Programms
• Stellen sicher, dass diese Units bestimmte Erwartungen
erfüllen
4. FIO® SYSTEMS AG
Ein Unit Test
[TestFixture]
public class AccountTest
{
private Account firstAccount = new Account();
private Account secondAccount = new Account();
[TestFixtureSetUp]
public void SetUp()
{
firstAccount.Transfer(secondAccount, 100);
}
[Test]
public void TransferTest()
{
Assert.AreEqual(100, secondAccount.Balance);
}
}
5. FIO® SYSTEMS AG
Funktionen von Unit Test Frameworks
• Annotationen zum Kennzeichnen der Testklasse (NUnit:
[TestFixture], JUnit / TestNG: keine erforderlich)
• Annotationen zum Kennzeichnen von SetUp / TearDown
(NUnit: [TestFixtureSetUp] / [SetUp],
[TestFixtureTearDown] / [TearDown], JUnit / TestNG:
@Before, @After, @BeforeClass, @BeforeMethod, …)
• Kennzeichnung der eigentlichen Tests (NUnit: [Test],
JUnit / TestNG: @Test)
6. FIO® SYSTEMS AG
Funktionen von Unit Test Frameworks
• Assert Statements zum Definieren von Bedingungen
(NUnit: Assert.AreEqual, JUnit / TestNG: assertsEquals)
• Annotationen zum Kennzeichnen von erwarteten
Exceptions: NUnit:
[Test][ExpectedException(typeof(ArithmeticException))],
JUnit / TestNG: @Test(expected(Exceptions) =
ArithmeticException.class)
7. FIO® SYSTEMS AG
Bedingungen an Unit Tests
from „Working effectively with legacy code“ by Michael Feathers:
„A test is not a unit test if:
1. It talks to a database.
2. It communicates across a network.
3. It touches the file system.
4. You have to do special things to your environment to run
it.“
Weitere: schnell, wiederholbar, verständlich, unabhängig
8. FIO® SYSTEMS AG
Was bringen Unit Tests?
• Sicherheit
• Dokumentation
• Automatische Tests / Continuous Integration
• Geschwindigkeit (mittel- / langfristig)
• Aber: hohe Einarbeitungszeit, Zeitaufwand für Tests
9. FIO® SYSTEMS AG
Unit Test nach dem Code
• …werden oft nicht geschrieben
• …testen nur das, was der Code hergibt
• …prüfen meist nur einen Teil der Funktionalität
• …sind oft schwer zu schreiben, da der Code schlecht
testbar ist
Die Lösung: Test Driven Development
10. FIO® SYSTEMS AG
Test Driven Development (TDD)
• RED: fehlschlagenden Test schreiben
• GREEN: nur soviel Code schreiben, um den Test grün zu
machen
• REFACTOR: den Code aufräumen
12. FIO® SYSTEMS AG
Kriterien für gute Tests
Gute Tests:
• Stellen sicher, dass erwartete Ergebnisse geliefert
werden
• Testen Extrembedingungen / Fehlerzustände
• Testen Performance bei kritischen Funktionen
• Decken möglichst 100% des Codes ab
14. FIO® SYSTEMS AG
Weitere Schwierigkeiten
• Wie lässt sich eine solche Methode sinnvoll testen:
public class AccountController
{
...
public void Save()
{
Account account = accountService.GetById(accountId);
// ToDo: fill account with values from mask
accountService.Save(account);
}
}
15. FIO® SYSTEMS AG
Die Lösung: Dependency-Injection
• Interface statt konkreter Implementierung verwenden
• Implementierung zugänglich machen durch z.B.:
• Übergabe im Konstruktor
• Übergabe im Funktionsaufruf
• Setter
• Service-Locator
• DI-Framework
16. FIO® SYSTEMS AG
Verwendung eines DI-Frameworks
ObjectFactory.Initialize(...);
public class AccountController
{
private IAccountService service =
ObjectFactory.GetInstance<IAccountService>();
public void Save()
{
Account account = service.GetById(accountId);
// ToDo: fill account with values from mask
service.Save(account);
}
}
17. FIO® SYSTEMS AG
Und dann?
• Der getesteten Methode / Klasse etwas vorgauckeln mit:
• Fakes (Implementierung nur für den Test)
• Stubs (Geben die Werte zurück, die für den Test
gebraucht werden)
• Mocks (Objekte mit Erwartungen bzgl. übergebener
Werte und aufgerufener Funktionen)
20. FIO® SYSTEMS AG
Behaviour Driven Development (BDD)
• Ausgangspunkt der Tests ist ein Akzeptanzkriterium
• Daraus wird eine Spezifikation der Form „Name, When,
Then“ oder „Given, When, Then“ erstellt
• Die Ausgabe der Testläufe soll menschenlesbar und für
Tester, Fachanwender oder Kunden verständlich sein
• Der Testcode selbst soll leicht verständlich sein, um als
„lebendige Dokumentation“ zu dienen
23. FIO® SYSTEMS AG
Continuous Integration (CI)
• Der beste Tests nutzt nichts, wenn er nicht nach jeder
Änderung ausgeführt wird
• Der beste Code nutzt nichts, wenn er nicht integrierbar ist
• Bei 2 oder mehr Entwicklern lässt sich beides nur
automatisiert sicherstellen
• Des Weiteren muss es im Team eine Quelle der
ultimativen Wahrheit geben
24. FIO® SYSTEMS AG
Continuous Integration (CI)
• Zentrales Code Repository
• Zentraler automatisierter Build nach jedem Commit
• Zentrale automatisierte Tests (evtl. nach Schedule)
• Info an das ganze Team bei Fehlern in Build oder in Tests
26. FIO® SYSTEMS AG
Die Aufgabe
Als praktisches Beispiel soll im Rahmen dieser Aufgabe eine Funktion zum
Berechnen von Zinsen nach der Methode 30/360 erarbeitet werden.
Voraussetzungen:
Technisch: Die eingesetzte Programmiersprache sowie das verwendete Test-
Framework können frei gewählt werden.
Fachlich: Es soll die für Spareinlagen übliche Zinsmethode 30/360
angewendet werden, wobei der letzte Tag (Auszahlungstag) als zinsfrei zu
behandeln ist.
27. FIO® SYSTEMS AG
Aufgabenstellung
• Erstellung Programm zur Zinsberechnung in Einzelarbeit, Zinsmethode 30/360
• Nutzer soll Anzahl von Buchungen eingeben können (Buchungsdatum, Betrag,
Buchungstext) und zur Zinsberechnung Start- sowie Enddatum und Zinssatz
festlegen
• Programm soll Zinstage und berechnete Zinsen ausgeben
• Die Funktion zur Zinsberechnung mit den oben beschriebenen
Eingabeparametern ist testgetrieben zu entwickeln. Es ist dabei immer zuerst
der Test zu schreiben, ehe weitere Funktionalität hinzugefügt wird.
28. FIO® SYSTEMS AG
Ergebnispräsentation
Bei der Präsentation des Arbeitsergebnisses soll auch auf folgende Aspekte
eingegangen werden:
aus welchem Grund die verwendeten Technologien und Tools zum Einsatz
kamen
welche Tests erstellt wurden und welches Schema zur Benennung der Tests
verwendet wurde
welche Probleme das testgetriebene Vorgehen aufgeworfen hat und wie sie
ggf. gelöst werden konnten