Nowa wersja
|
Poprzednia wersja
|
pl:dydaktyka:jimp2:2017:labs:unit-testing [2017/06/01 00:19] mwp utworzono |
pl:dydaktyka:jimp2:2017:labs:unit-testing [2017/06/01 00:51] mwp [Google Test Framework] |
</file> | </file> |
| |
| Ręcznie napisane testy jednostkowe, sprawdzające poprawność implementacji funkcji silnia: |
| <file cpp FactorialTest.h> |
| #ifndef FACTORIAL_TEST_H_ |
| #define FACTORIAL_TEST_H_ |
| |
| bool FactorialOf0ShouldBe1(); |
| bool FactorialOf1ShouldBe1(); |
| bool FactorialOf10ShouldBe3628800(); |
| bool FactorialOfNegativeShouldBe0(); |
| |
| #endif |
| </file> |
| |
| <file cpp FactorialTest.cpp> |
| #include "FactorialTest.h" |
| |
| bool FactorialOf0ShouldBe1() { |
| int expected = 1; |
| int result = Factorial(0); |
| return expected == result; |
| } |
| |
| bool FactorialOf1ShouldBe1() { |
| int expected = 1; |
| int result = Factorial(1); |
| return expected == result; |
| } |
| |
| bool FactorialOf10ShouldBe3628800() { |
| int expected = 3628800; |
| int result = Factorial(10); |
| return expected == result; |
| } |
| |
| bool FactorialOfNegativeShouldBe0() { |
| int expected = 0; |
| int result = Factorial(-7); |
| return expected == result; |
| } |
| </file> |
| |
| main od testów jednostkowych, który ma na celu uruchomienie wszystkich testów i zaraportowanie o ewentualnych niepowodzeniach: |
| <file cpp main.cpp> |
| #include "FactorialTest.h" |
| |
| #include <string> |
| #include <utility> |
| #include <iostream> |
| |
| using std::string; |
| using std::pair; |
| using std::cerr; |
| using std::endl; |
| |
| //test function to wskaźnik na funkcję zwracającą bool |
| using TestFunction = bool (*)(); |
| |
| std::vector<pair<string,TestFunction>> all_tests {{"FactorialOf0ShouldBe1", FactorialOf0ShouldBe1}, {"FactorialOf1ShouldBe1", FactorialOf1ShouldBe1}, {"FactorialOf10ShouldBe3628800", FactorialOf10ShouldBe3628800}, {"FactorialOfNegativeShouldBe0", FactorialOfNegativeShouldBe0}}; |
| |
| void ReportTest(const string &failed_test_name) { |
| cerr << "Test " << failed_test_name << " FAILED" << endl; |
| } |
| |
| int RunTests(const std::vector<TestFunction> tests) { |
| int failed_tests = 0; |
| for (auto test : tests) { |
| bool result = test.first(); |
| if (result) { |
| continue; |
| } else { |
| ReportTest(test.second); |
| failed_tests++; |
| } |
| } |
| return failed_tests; |
| } |
| |
| int main() { |
| int result = RunTests(all_tests); |
| return result; |
| } |
| </file> |
| |
| Już jest nieźle - testy są zautomatyzowane, bo teraz możemy odpalać zawsze testy przez skompilowanie kodu i jego uruchomienie. Do tego nie trzeba weryfikować wyjścia w żaden sposób jeśli jest wszystko w porządku. Możemy również dopisywać nowe testy. |
| |
| Ale pojawia się wiele powtórzonego kodu, nazwę metody testowej trzeba powtórzyć w kilku miejscach, żeby wszystko działało sprawnie, informacje o tym co poszło nie tak są też bardzo uszczuplone. Ale jest na to rozwiązanie gotowe frameworki testowe. |
===== Google Test Framework ===== | ===== Google Test Framework ===== |
| |
| GTesty używają do specyfikacji testu makr języka C, dzięki temu przy definicji nowego przypadku testowego: |
| <file cpp FactorialTest.cpp> |
| #include <Factorial.h> |
| |
| TEST(FactorialTest, FactorialOf0ShouldBe1) { |
| EXPECT_EQ(1, Factorial(1)); |
| } |
| </file> |
| |
| Od razu następuje rejestracja metody testowej w strukturze przechowującej uchwyty do testów. Automatycznie następuje zamiana nazw na łańcuchy znaków w celu przygotowania czytelnej wiadomości dla użytkownika. A metodę main można wykorzystać jako domyślnie zaimplementowaną w frameworku, albo napisać ją samemu. Wtedy makro RUN_ALL_TESTS() uruchamia wszystkie testy. |
| |
| Dodatkową cechą frameworka są dodane specjalne makra do wyrażania naszych oczekiwań co do fragmentów kodu, które w przypadku nie spełnienia oczekiwań produkują czytelniejszą wiadomość dla dewelopera. |
| |
| Więcej o frameworku można doczytać tutaj: |
[[https://github.com/google/googletest/blob/master/googletest/docs/Primer.md|Podstawy GTest]] | [[https://github.com/google/googletest/blob/master/googletest/docs/Primer.md|Podstawy GTest]] |
| [[https://github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md|Zaawansowane GTesty]] |
| |
| |
| |