4. Unit teszt: mire jó?
●
Unit: a kód legkisebb, önmagában tesztelhető egysége
●
C → függvény
●
C++ → osztály
●
Izoláltan teszteljük a szoftver építőkockáit.
●
Élő dokumentáció.
●
TDD-nél tervezési funkciója is van.
●
Ösztönzi az egészséges kód létrehozását.
6. Unit teszt: mikor?
●
Röviden: MINDIG :-)
●
Ha fontos a szoftver minősége.
●
Ha számít mennyit kell karbantartani.
●
Ha túl sok a komplikált manuális teszt.
●
Ha hiányos a dokumentáció.
●
Ha szeretnél gyakran refaktorálni.
●
Ha nem szeretsz tesztet írni.
7. Unit teszt: mivel?
●
Keretrendszerek: CppUnit, CxxTest, Boost.Test,
UnitTest++, Google Test
●
Legtöbbjük xUnit felépítésű
●
Könnyen használható eszköztár:
●
Case, fixture, suit
●
Setup, assert, teardown
8.
9. Google Test
Miért érdemes használni?
●
Hordozható: exception és RTTI nélkül is megy.
●
Nem fatális assert: egy futás, összes hiba.
●
Könnyű információt csatolni egy assert-hez: <<
●
Szelektív tesztfuttatás.
●
Érték és típus parametrizált tesztek.
●
Predikátum assert.
●
Death assert: várt program összeomlás.
●
Jól használható API, extra igényekhez.
10. Alapok: TEST(...)
Elég a dumából, írjunk tesztet:
#include "sample1.h"
#include "gtest/gtest.h"
TEST(FactorialTest, Zero) {
ASSERT_EQ(1, Factorial(0));
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
11. Alapok: ASSERT_*
●
Érték, objektum:
●
TRUE, FALSE
●
EQ, NE, LT, LE, GT, GE
●
FLOAT_EQ, DOUBLE_EQ, NEAR
●
C sztring:
●
STREQ, STRNE
●
STRCASEEQ, STRCASENE
●
Nem fatális: EXPECT_*
14. Control flow
Ha control flow alapján dől el:
●
SUCCEED()
●
FAIL(), ADD_FAILURE(),
ADD_FAILURE_AT(“file_path”, line_number)
switch(expression) {
case 1: ... some checks ...
case 2: ... some other checks
...
default: FAIL() << "We shouldn't get here.";
}
16. Predikátum
ASSERT_*, EXPECT_*:
●
PRED1(bool (*pred1fv)(arg1), test_arg1)
●
Jelenleg öt argumentumig implementált.
// Returns true iff m and n have no common
divisors except 1.
bool MutuallyPrime(int m, int n) { ... }
EXPECT_PRED2(MutuallyPrime, 3, 4); // SUCCEED()
EXPECT_PRED2(MutuallyPrime, 4, 10); // FAIL()
17. Extrák: death tesztelés
ASSERT_*, EXPECT_*:
●
DEATH, DEATH_IF_SUPPORTED
●
EXIT
TEST(MyDeathTest, Foo) {
// This death test uses a compound statement.
ASSERT_DEATH({ int n = 5; Foo(&n); }, "Error on line .* of Foo()");
}
TEST(MyDeathTest, NormalExit) {
EXPECT_EXIT(NormalExit(), ::testing::ExitedWithCode(0),
"Success"); }
TEST(MyDeathTest, KillMyself) {
EXPECT_EXIT(KillMyself(), ::testing::KilledBySignal(SIGKILL),
"Sending myself unblockable signal"); }
19. Extrák: TRACE kimenet
path/to/foo_test.cc:11: Failure
Value of: Bar(n)
Expected: 1
Actual: 2
Trace:
path/to/foo_test.cc:17: A
path/to/foo_test.cc:12: Failure
Value of: Bar(n + 1)
Expected: 2
Actual: 3
20. Extrák: globális fixtúra
class Environment {
public:
virtual ~Environment() {}
// Override this to define how to set up the
environment.
virtual void SetUp() {}
// Override this to define how to tear down the
environment.
virtual void TearDown() {}
};
// in main()
AddGlobalTestEnvironment(Environment* env);
21. Extrák: érték paraméter
class FooTest : public ::testing::TestWithParam<const
char*> {
// You can implement all the usual fixture class
members here.
};
TEST_P(FooTest, DoesBlah) {
EXPECT_TRUE(foo.Blah(GetParam()));
...
}
TEST_P(FooTest, HasBlahBlah) { ... }
INSTANTIATE_TEST_CASE_P(InstantiationName, FooTest,
::testing::Values("meeny", "miny", "moe"));
22. Extrák: érték paraméter II.
●
Values(v1, v2, ..., vN)
●
ValuesIn(container)
●
ValuesIn(begin, end)
●
Range(begin, end[, step])
●
Bool() = Values(false, true)
●
Combine(g1, g2, ..., gN) -> requires <tr1/tuple>
end nem része az értékhalmaznak
23. Extrák: típus paraméter
template <typename T>
class FooTest : public ::testing::Test {
...
}
TYPED_TEST_CASE_P(FooTest);
TYPED_TEST_P(FooTest, DoesBlah) {
// Inside a test, refer to TypeParam to get the type
parameter.
TypeParam n = 0;
...
}
TYPED_TEST_P(FooTest, HasPropertyA) { ... }
REGISTER_TYPED_TEST_CASE_P(FooTest, DoesBlah, HasPropertyA);
typedef ::testing::Types<char, int, unsigned int> MyTypes;
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, MyTypes);
INSTANTIATE_TYPED_TEST_CASE_P(My, FooTest, int);
24. Extrák: teszt események
●
Listener API
●
UnitTest
●
TestCase
●
TestInfo
●
TestPartResult
●
Result printer (Sample 9)
●
Memory Leak checker (Sample 10)
25. Extrák: unit test CLI
●
unit --help
●
unit --gtest_list_tests
●
unit --gtest_filter=<regexp>-<!regexp>
●
unit --gtest_repeat=<times>
●
unit --gtest_shuffle
●
unit --gtest_output=”xml:<output_file>”
●
Integrálás: debugger, test framework
●
Tesztek szétosztása gépek között
26. Google Mock
●
Osztályok izolált teszteléséhez
●
Elvárásokkal preparálhatjuk a függőségeket
●
Ellenőrizhetjük objektumainkat:
●
Hányszor érték el
●
Milyen argumentumokkal
●
Mi volt a visszatérési érték
az interakció során.
27. Linkek
● C++ unit teszt keretrendszerek:
http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C.2B.2B
● Kent Beck – xUnit testing framework:
http://www.xprogramming.com/testfram.htm
● Noel Llopis – C++ framework comparison:
http://gamesfromwithin.com/exploring-the-c-unit-testing-framework-jungle
● CppUnit:
https://launchpad.net/cppunit2
● CxxTest:
http://cxxtest.sourceforge.net/
● UnitTest++:
http://unittest-cpp.sourceforge.net/
● Boost.Test:
http://www.boost.org/doc/libs/release/libs/test/index.html
● Google Test Framework:
http://code.google.com/p/googletest/
● Google Mock Framework:
http://code.google.com/p/googlemock/