W przyszłym tygodniu będę rozmawiać z moim działem na temat testów jednostkowych i rozwoju opartego na testach. W ramach tego zamierzam pokazać przykłady z rzeczywistego świata z kodu, który napisałem niedawno, ale chciałbym też pokazać kilka bardzo prostych przykładów, które napiszę w wykładzie.
Szukałem dobrych przykładów w Internecie, ale starałem się znaleźć takie, które szczególnie pasują do naszego obszaru rozwoju. Prawie całe oprogramowanie, które piszemy, to głęboko osadzone systemy sterowania działające na małych mikrokontrolerach. Jest dużo kodu C, który można łatwo zastosować do testowania jednostkowego (będę mówił o testowaniu jednostkowym na PC, a nie na samym celu), o ile trzymasz się z dala od „dolnej” warstwy: rzeczy, które mówią bezpośrednio do urządzeń peryferyjnych mikrokontrolera. Jednak większość przykładów, które znalazłem, zwykle opiera się na przetwarzaniu ciągów (np. Doskonały przykład cyfr rzymskich Dive Into Python), a ponieważ rzadko kiedy używamy ciągów, nie jest to tak naprawdę odpowiednie (o jedynych funkcjach bibliotecznych, których zwykle używa nasz kod są memcpy
, memcmp
i memset
,strcat
lub wyrażenia regularne nie są całkiem właściwe).
Tak więc, na pytanie: czy ktoś może zaoferować dobre przykłady funkcji, których mogę użyć do zademonstrowania testów jednostkowych podczas sesji na żywo? Dobrą odpowiedzią w mojej (z zastrzeżeniem zmiany) opinii byłoby prawdopodobnie:
- Funkcja, która jest na tyle prosta, że każdy (nawet ci, którzy piszą kod tylko od czasu do czasu) może zrozumieć;
- Funkcja, która nie wydaje się bezcelowa (tj. Wypracowanie parzystości lub CRC jest prawdopodobnie lepsza niż funkcja, która mnoży dwie liczby razem i dodaje losową stałą);
- Funkcja, która jest wystarczająco krótka, aby pisać przed pokojem ludzi (mogę skorzystać z wielu schowków Vima, aby zmniejszyć liczbę błędów ...);
- Funkcja, która przyjmuje liczby, tablice, wskaźniki lub struktury jako parametry i zwraca coś podobnego, zamiast obsługi ciągów;
- Funkcja z prostym błędem (np.
>
Zamiast>=
), łatwa do wprowadzenia, która nadal działałaby w większości przypadków, ale zepsułaby się w przypadku określonego przypadku krawędzi: łatwa do zidentyfikowania i naprawienia za pomocą testu jednostkowego.
jakieś pomysły?
Chociaż prawdopodobnie nie jest to istotne, same testy prawdopodobnie zostaną napisane w C ++ przy użyciu Google Test Framework: wszystkie nasze nagłówki mają już #ifdef __cplusplus extern "C" {
wokół siebie opakowanie; działało to dobrze z testami, które przeprowadziłem do tej pory.
Odpowiedzi:
Oto prosta funkcja, która ma generować sumę kontrolną na bajtach len .
Ma błąd płotu: w instrukcji for powinien być test
i < len
.Zabawne jest to, że jeśli zastosujesz go do takiego ciągu tekstowego ...
dostaniesz „właściwą odpowiedź”! Jest tak, ponieważ dodatkowy bajt, który został sprawdzony, był terminatorem zerowego ciągu. Możesz więc skończyć z dodawaniem funkcji sumy kontrolnej do kodu, a może nawet wysyłaniem jej razem i nigdy nie zauważać problemu - to znaczy, dopóki nie zaczniesz stosować jej do czegoś innego niż ciągi tekstowe.
Oto prosty test jednostkowy, który oznaczy ten błąd (przez większość czasu ... :-)
źródło
Co z implementacją funkcji sortowania, takiej jak bąbelkowa ? Po uruchomieniu funkcji sortowania możesz kontynuować wyszukiwanie binarne, które jest równie dobre do wprowadzenia testów jednostkowych i TDD.
Sortowanie i wyszukiwanie zależy od porównań, które łatwo się pomylić. Obejmuje to także zamianę wskaźników, które należy wykonać ostrożnie. Oba są podatne na błędy, więc możesz się popsuć :)
Jeszcze kilka pomysłów:
qsort
, a testy powinny się jeszcze udać, co potwierdza, że twoja nowa funkcja sortowania również działa.źródło