Unit- und Regressionstests
Transcription
Unit- und Regressionstests
Unit-Tests Frederik Heber Einleitung Motivation Tests Code verifizieren mittels Unit-Tests Regression-Tests Prinzipien und Philosophie Unit- und Regressionstests Funktionsweise Unit-Tests Regression-Tests Frameworks Frederik Heber CppUnit Autotest Links Institut für Numerische Simulation, Universität Bonn Seminarreihe Technische Numerik Unit-Tests Einleitung Wozu sollen Tests gut sein? Was für Testarten gibt es? Unit-Tests Regression-Tests Prinzipien und Philosophie Frederik Heber Einleitung Motivation Tests Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks Wie funktionieren solche Tests? Unit-Tests Regression-Tests Test-Frameworks und Beispiel CppUnit Autotest Links CppUnit Autotest Links Wozu sollen Tests gut sein? Unit-Tests Frederik Heber Refactoring: Ändern des Codes bei gleichbleibender Funktionalität. Einleitung ◮ Unabhängiger Einbau von Features Tests ◮ Verifizierung von Komponenten eines neuen System(teil)s ◮ Motivation Unit-Tests ◮ Funktionsweise überprüfen Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks Potentielle Quellen von Bugs Änderungen am Code stellen grundsätzlich eine Quelle für Bugs in bereits vorhandenem Code dar! Problem Unabsichtliches Verändern des Interfaces bestimmter Funktionen für neue Features. CppUnit Autotest Links Wozu sollen Tests gut sein? Unit-Tests Frederik Heber Refactoring: Ändern des Codes bei gleichbleibender Funktionalität. Einleitung ◮ Unabhängiger Einbau von Features Tests ◮ Verifizierung von Komponenten eines neuen System(teil)s ◮ ◮ Funktionsweise überprüfen Motivation Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks Potentielle Quellen von Bugs Änderungen am Code stellen grundsätzlich eine Quelle für Bugs in bereits vorhandenem Code dar! Lösung Regressions- und Komponententests stellen (weitest gehend) sicher, dass die Funktionalität des vorhandenen Codes fortbesteht. CppUnit Autotest Links Abstecher: Extreme Programming Unit-Tests Frederik Heber Einleitung Motivation Test-Driven Development Tests Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Pair Programming Refactoring Frameworks CppUnit Autotest Links Simple Design Website http://www.extremeprogramming.org/ Unit-Tests Frederik Heber 1. Komponenten- oder Unit-Tests Eingebaute Testroutinen Unabhängige Routinen Einleitung Motivation Tests Testroutinen im Code, welche eine bestimmte Funktionalität entweder bei Programmbeginn oder auf Wunsch testen. Testroutinen in externem Programm, welches einzig dazu dient, das Funktionieren und gewollte Nicht-Funktionieren sicher zu stellen. Was ist eine Komponente? Eine Klasse oder eine Funktion: class Vector oder MatrixMultiplication(). Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks CppUnit Autotest Links Unit-Tests 2. Regressionstests Testsuite Frederik Heber Einleitung Shell-Skripte Ansammlung von Skripten, die für bestimmte Eingaben bestimmten Ausgaben erwarten. Zusammenfassung von Skripten zu einer Testsuite, welche die gesamte Funktionaliät eines Codes in einer gegebenen Fassung automatisiert überprüfen soll. Was bedeutet Regression? lat. re-gregere - zurückgehen, zurückschreiten. Hier: Das repetitive Wiederholen aller Testfälle, um mg̈liche unabsichtliche Veränderungen aufzuspüren. Motivation Tests Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks CppUnit Autotest Links Unit-Tests Frederik Heber Einleitung Testprinzipien und -philosophien Motivation Tests ◮ Testentwicklung parallel zur Programmentwicklung (Test-Driven Development). ◮ Alle Funktionen sollen getestet werden. ◮ Hierarchische Abhängigkeit: Komplexere Funktionen nutzen verfizierte einfachere. Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests ◮ Test von Gut- und Fehlfall. ◮ pro Bug ein Test: D. h. ein Test für jeden gefundenen Fehler: Und der Fix behebt genau den Alarm dieses Tests. Frameworks CppUnit Autotest Links Unit-Tests Frederik Heber Einleitung Wie funktionieren Komponenten- oder Unit-Tests? Motivation Tests Prinzip Getestet wird das Interface bzw. der ”Vertrag“ einer Komponente, nicht der Code der Komponente selbst (Black Box). Arbeitsweise Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks CppUnit Autotest Links ◮ Test-Funktionen mit Zeilen a la ”ASSERT(. . . );“ ◮ Test-Runner, der die Test-Funktionen der Reihe nach ausführt und in ”OK(...)“ oder ”FAILED: ...“ endet. Unit-Tests Wie funktionieren Regression-Tests? Frederik Heber Einleitung Prinzip Alle Testfälle einer Software werden wiederholt und automatisiert durchlaufen, um unabsichtliche Veränderungen zu entdecken, umfasst sowohl Komponenten- als auch Integrations- und System-tests. Arbeitsweise Motivation Tests Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks CppUnit Autotest ◮ Kleine Test-Skripte, die den Code mit bestimmten Eingabeparametern und -files startet und bestimmte Ausgabe erwartet. ◮ Testsuite, die die Skripte alle der Reihe nach ausführt und Ausgabe bei Fehler sichert bzw. verwirft, wenn kein Fehler auftritt. Links Unvollständige Auflistung ◮ Komponenten-Tests für C ◮ ◮ ◮ ◮ Komponenten-Tests für C++ ◮ ◮ ◮ ◮ ◮ ◮ AutoUnit CUnit ... Boost Test Library CppUnit CUTE CxxTest ... Regressions-Tests für C/C++ ◮ ◮ Autotest Beaker Quelle http://en.wikipedia.org/wiki/List of unit testing frameworks Unit-Tests Frederik Heber Einleitung Motivation Tests Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks CppUnit Autotest Links CppUnit Unit-Tests Frederik Heber Einleitung Beispiel: Test einer Klasse ”Vector“ Motivation Sechs Files: Tests 1. vector.hpp 2. vector.cpp 3. vectorunittest.hpp 4. vectorunittest.cpp 5. vectornormtest.cpp 6. testrunner.cpp Download Code steht nach Vortragsende auf der Webseite. Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks CppUnit Autotest Links Deklarationen in vector.hpp Unit-Tests Frederik Heber #ifndef VECTOR_HPP_ #define VECTOR_HPP_ /** Vector-Klasse mit * -# Konstruktor * -# Destruktor * -# Funktion Norm(). */ class Vector { public: Vector(); Vector(double a, double b, double c); ˜Vector() {}; double Norm(); private: double x[3]; }; #endif // VECTOR_HPP_ Einleitung Motivation Tests Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks CppUnit Autotest Links Unit-Tests Definitionen in vector.cpp Frederik Heber Einleitung #include <math.h> #include "vector.hpp" Motivation Tests Unit-Tests Vector::Vector() { x[0] = 0.; x[1] = 0.; x[2] = 0.; }; Vector::Vector(double a, double b, double c) { x[0] = a; x[1] = b; x[2] = c; }; double Vector::Norm() { double result = 0.; for(int i=0;i<3;i++) result += x[i]*x[i]; return (sqrt(result)); }; Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks CppUnit Autotest Links Unit-Test in vectorunittest.hpp Unit-Tests Frederik Heber #ifndef VECTORUNITTEST_HPP_ #define VECTORUNITTEST_HPP_ #include <cppunit/extensions/HelperMacros.h> #include "vector.hpp" class VectorTest : public CppUnit::TestFixture { CPPUNIT_TEST_SUITE( VectorTest ); CPPUNIT_TEST ( NormTest ); CPPUNIT_TEST_SUITE_END(); public: void setUp(); void tearDown(); void NormTest(); private: Vector *zero; Vector *unit; Vector *two; }; #endif // VECTORUNITTEST_HPP_ Einleitung Motivation Tests Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks CppUnit Autotest Links Unit-Tests Unit-Test in vectorunittest.cpp #include "vector.hpp" #include "vectorunittest.hpp" Frederik Heber Einleitung Motivation Tests // Registers the fixture into the ’registry’ CPPUNIT_TEST_SUITE_REGISTRATION( VectorTest ); Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise void VectorTest::setUp() { zero = new Vector(0.,0.,0.); unit = new Vector(1.,0.,0.); two = new Vector(2.,0.,0.); }; void VectorTest::tearDown() { delete(zero); delete(unit); delete(two); }; Unit-Tests Regression-Tests Frameworks CppUnit Autotest Links Unit-Tests Unit-Test in vectornormtest.cpp Frederik Heber Einleitung #include "vectorunittest.hpp" #include <math.h> Motivation Tests Unit-Tests /** UnitTest fuer Vector::Norm(). */ void VectorTest::NormTest() { // unity and zero tests CPPUNIT_ASSERT_EQUAL( 0., zero->Norm() ); CPPUNIT_ASSERT_EQUAL( 1., unit->Norm() ); // besser? CPPUNIT_ASSERT ( fabs(zero->Norm()) < 1e-13 ); CPPUNIT_ASSERT ( fabs(1. - unit->Norm()) < 1e-13 ); }; Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks CppUnit Autotest Links Unit-Tests Frederik Heber Einleitung Motivation Tests Ausführung Unit-Tests Regression-Tests Prinzipien und Philosophie heber@bespin:> ./VectorUnitTest Funktionsweise Unit-Tests Regression-Tests . Frameworks CppUnit OK(1) heber@bespin:> Autotest Links Unit-Tests Frederik Heber Auflistung der wichtigsten Befehle Einleitung In einer Test-Klasse ”. . . Test“ definiert bzw. implementiert: Motivation Tests Unit-Tests Regression-Tests CPPUNIT TEST SUITE (. . . Test); Deklariert die Testsuite . . . Test. CPPUNIT TEST (TestFunktion); Deklariert einen Testcase namens Testfunktion. Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks CppUnit Autotest CPPUNIT TEST SUITE END(); Schliesst die Deklaration der Testsuite ab. . . . Test::setUp(); Wird vor jedem Test aufgerufen. . . . Test::tearDown(); Wird nach jedem Test aufgerufen. . . . Test::Testfunktion(); Die eigentliche Testfunktion. Links Autotest Unit-Tests Frederik Heber Einleitung Motivation Tests Unit-Tests Regression-Tests Prinzipien und Philosophie Definition in testsuite.at Funktionsweise Unit-Tests AT_INIT([VectorTest]) AT_SETUP([Norm]) AT_CHECK([$at_dir/../VectorUnitTest], \ [ignore], [ignore]) AT_CLEANUP Regression-Tests Frameworks CppUnit Autotest Links Unit-Tests Frederik Heber Einleitung Zusammenfassung der wichtigsten Befehle AT INIT (name) Initialisert die Testsuite und gibt ihr einen Namen AT SETUP (name) Bezeichnet den Anfang einer Testgruppe mit Namen. Motivation Tests Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Unit-Tests Regression-Tests Frameworks CppUnit AT CHECK([cmd , [], [])] Fuehrt ”cmd” aus und testet auf Return code, stdout und stderr koennen ”ignore”d werden oder in File umgeleitet. AT CLEANUP Bezeichnet das Ende einer Testgruppe. Autotest Links Wikipediaeintrag zu Unit-Tests http://de.wikipedia.org/wiki/Unit-Test Wikipediaeintrag zu CppUnit http://de.wikipedia.org/wiki/CppUnit Unit-Tests Frederik Heber Einleitung Motivation Tests Homepage von CppUnit http://sourceforge.net/projects/cppunit/ Unit-Tests Regression-Tests Prinzipien und Philosophie Funktionsweise Tutorial zu CppUnit http://www.evocomp.de/tutorials/tutorium cppunit/howto tutoria cppunit.html Unit-Tests Regression-Tests Frameworks CppUnit Erklärung zu Autotest http://www.gnu.org/software/automake/manual/autoconf/UsingAutotest.html Einstiegstutorial zu Autotest http://www.lrde.epita.fr/~akim/ccmp/doc/gnuprog2/Simple-Uses-ofAutotest.html Autotest Links