it-swarm-eu.dev

Kód C pro testování jednotky

Letos v létě jsem pracoval na vestavěném systému napsaném rovnou C. Byl to existující projekt, který převzala společnost, pro kterou pracuji. Jsem docela zvyklý psát jednotkové testy v Java pomocí JUnit, ale byl jsem na rozpacích, pokud jde o nejlepší způsob, jak napsat jednotkové testy pro existující kód (který vyžadoval refactoring), stejně jako nový kód přidaný do systému .

Existuje nějaký způsob, jak učinit testování jednotky prostým C kódem tak snadným jako testování jednotky Java kódem, například JUnit? Jakýkoli náhled, který by se týkal konkrétně vestavěného vývoje (křížové kompilace na platformu arm-linux), by byl velmi oceněn.

812
Paul Osborne

Jedna kostra testování jednotek v C je Check ; seznam rámců testování jednotek v C najdete zde a je reprodukován níže. V závislosti na tom, kolik standardních funkcí knihovny má váš runtime, můžete jednu z nich použít.

AceUnit

AceUnit (Advanced C and Embedded Unit) se účtuje jako pohodlný rámec pro testování jednotky C kódu. Snaží se napodobit JUnit 4.x a zahrnuje schopnosti podobné reflexi. AceUnit lze použít v prostředcích omezujících zdroje, např. vývoj vestavěného softwaru, a co je důležité, funguje dobře v prostředích, kde nemůžete zahrnout jediný standardní soubor záhlaví a nelze vyvolat jednu standardní funkci C z knihoven ANSI/ISO C. Má také port Windows. Nepoužívá vidlice k zachycení signálů, přestože autoři projevili zájem o přidání takové funkce. Viz domovská stránka AceUnit .

GNU Autounit

Hodně ve stejných liniích jako Check, včetně forkingu pro spouštění testů jednotek v samostatném adresním prostoru (ve skutečnosti si původní autor Checku půjčil nápad od GNU Autounit). GNU Autounit značně používá GLib, což znamená, že propojení a takové potřeby vyžadují speciální možnosti, ale to pro vás nemusí být velký problém, zejména pokud již používáte GTK nebo GLib. Podívejte se na GNU Autounit homepage .

cUnit

Používá také GLib, ale nezvětšuje ochranu adresového prostoru při jednotkových testech.

CUnit

Standard C, s plány implementace grafického rozhraní Win32. V současné době není vidlice ani jinak nechrání adresní prostor testů jednotek. V raném vývoji. Viz Domovská stránka CUnit .

CuTest

Jednoduchý rámec s jediným souborem .c a jedním .h, který vložíte do zdrojového stromu. Podívejte se na domovská stránka CuTest .

CppUnit

Přední rámec pro testování jednotek pro C++; můžete jej také použít k testování kódu C. Je stabilní, aktivně vyvíjený a má rozhraní GUI. Primární důvody, proč nepoužívat CppUnit pro C, jsou nejprve to, že je to docela velké, a za druhé, musíte napsat testy v C++, což znamená, že potřebujete kompilátor C++. Pokud to nezní jako obavy, určitě stojí za zvážení, spolu s dalšími kostry testování jednotek C++. Podívejte se na domovská stránka CppUnit .

rozzlobený

embUnit (Embedded Unit) je další rámec pro testování jednotek pro vestavěné systémy. Zdá se, že tento byl nahrazen AceUnitem. Domovská stránka Embedded Unit .

MinUnit

Minimální sada maker a to je vše! Jde o to ukázat, jak snadné je testovat váš kód. Viz Domovská stránka MinUnit .

CUnit pro pana Ando

CUnit implementace, která je celkem nová a zřejmě stále v počátečním vývoji. Podívejte se na CUnit pro domovskou stránku pana Anda .

Tento seznam byl naposledy aktualizován v březnu 2008

Více rámců:

CMocka

CMocka je testovací rámec pro C s podporou falešných objektů. Snadno se používá a nastavuje.

Viz domovská stránka CMocka .

Kritérium

Criterion je platforma pro testování na různých platformách C podporující automatickou registraci testu, parametrizované testy, teorie a která může výstup do více formátů, včetně TAP a JUnit XML. Každý test je spuštěn ve vlastním procesu, takže signály a pády mohou být v případě potřeby hlášeny nebo testovány.

Další informace naleznete na Domovská stránka kritéria .

HWUT

HWUT je obecný nástroj pro testování jednotek s velkou podporou pro C. Může pomoci vytvořit Makefiles, generovat masivní testovací případy kódované v minimálních iteračních tabulkách, chodit po státních strojích, generovat C-pahýly a další. Obecný přístup je dosti jedinečný: Verdikt je založen na „dobrém/špatném stdoutu“. Srovnávací funkce je však flexibilní. Pro kontrolu lze tedy použít jakýkoli typ skriptu. Může být použit pro jakýkoli jazyk, který může produkovat standardní výstup.

Viz domovská stránka HWUT .

CGreen

Moderní, přenosný, vícejazyčný testovací a simulační rámec pro C a C++. Nabízí volitelný zápis BDD, zesměšňující knihovnu, možnost spustit ji v jednom procesu (usnadnit ladění). K dispozici je zkušební běžec, který automaticky zjistí testovací funkce. Ale můžete si vytvořit svůj vlastní programově.

Všechny tyto funkce (a další) jsou vysvětleny v příručka CGreen .

Wikipedia uvádí podrobný seznam rámců pro testování jednotek C pod Seznam rámců pro testování jednotek: C

463
Adam Rosenfield

Osobně se mi líbí Google Test framework .

Skutečný problém při testování kódu C narušuje závislosti na externích modulech, takže můžete kód izolovat v jednotkách. To může být zvláště problematické, když se pokoušíte testovat starší kód. V tomto případě se často setkávám s používáním linkeru k použití stubových funkcí v testech.

To je to, o čem lidé mluví, když mluví o „ švech “. V C je jedinou možností skutečně použít předprocesor nebo linker k zesílení vašich závislostí.

Typický testovací balíček v jednom z mých C projektů může vypadat takto:

#include "myimplementationfile.c"
#include <gtest/gtest.h>

// Mock out external dependency on mylogger.o
void Logger_log(...){}

TEST(FactorialTest, Zero) {
    EXPECT_EQ(1, Factorial(0));
}

Všimněte si, že skutečně zahrnujete soubor C a ne soubor záhlaví . To poskytuje výhodu přístupu ke všem členům statických dat. Zde vysmívám svůj logger (který může být v logger.o a dávám prázdnou implementaci. To znamená, že testovací soubor kompiluje a propojuje nezávisle na zbytku základny kódu a provádí samostatně).

Pokud jde o křížové kompilace kódu, pro to, abyste mohli fungovat, potřebujete dobré vybavení v cíli. Udělal jsem to pomocí googletest cross zkompilovaného do Linuxu na architektuře PowerPC. To dává smysl, protože tam máte plnou Shell a OS, abyste shromáždili své výsledky. Pro méně bohatá prostředí (které klasifikuji jako cokoli bez plného OS) byste měli jen stavět a provozovat na hostiteli. Měli byste to přesto udělat, abyste mohli testy automaticky spustit jako součást sestavení.

Zjistil jsem, že testování kódu C++ je obecně mnohem snazší kvůli skutečnosti, že kód OO je obecně mnohem méně spřažený než procedurální (samozřejmě to hodně záleží na stylu kódování). Také v C++ můžete použít triky, jako je závislost injekce a potlačení metody, abyste dostali švy do kódu, který je jinak zapouzdřen.

Michael Feathers má vynikající kniha o testování dědického kód . V jedné kapitole se věnuji technikám zacházení s non-OO kódem, které vřele doporučuji.

Upravit : Napsal jsem blogový příspěvek o procedurálním kódu testování jednotky, s zdroj je k dispozici na GitHub .

Úpravy : Existuje nová kniha vychází z Pragmatických programátorů , která konkrétně řeší C testovací jednotky, které Velmi doporučuji .

152
mikelong

Minunit je neuvěřitelně jednoduchý rámec pro testování jednotek. Používám to k testování jednotky mikrokontroléru kód pro AVR.

128
Matteo Caprari

V současné době používám rámec testování jednotek CuTest:

http://cutest.sourceforge.net/

Je ideální pro vestavěné systémy, protože je velmi lehký a jednoduchý. Neměl jsem žádný problém dostat ho do práce na cílové platformě i na ploše. Kromě psaní jednotkových testů je nutné pouze:

  • soubor záhlaví zahrnutý kamkoli voláte rutiny CuTest
  • jeden další soubor „C“, který se má zkompilovat/propojit do obrázku
  • nějaký jednoduchý kód přidaný do main pro nastavení a zavolání testů jednotky - mám to jen ve speciální main () funkci, která se kompiluje, pokud je UNITTEST definován během sestavení.

Systém musí podporovat haldu a některé funkce stdio (které nemají všechny vestavěné systémy). Ale kód je dostatečně jednoduchý, že pokud vaše platforma nemá, pravděpodobně byste mohli pracovat alternativně k těmto požadavkům.

S nějakým rozumným použitím externích bloků „C“ {} také podporuje testování C++ v pořádku.

40
Michael Burr

Říkám skoro to samé jako ratkok, ale pokud máte zabudovaný záplet na jednotkové testy, pak ...

nity - Vysoce doporučený rámec pro testování C kódu jednotky.

Příklady v knize, která je uvedena v tomto vlákně TDD pro vložený C , jsou psány pomocí Unity (a CppUTest).

36
Johan

Také byste se měli podívat na libtap , testovací rámec C, který vydává protokol Test Anything Protocol (TAP), a tak se dobře integruje s řadou nástrojů, které pro tuto technologii přicházejí. Používá se většinou v dynamickém světě jazyků, ale snadno se používá a stává se velmi populární.

Příklad:

#include <tap.h>

int main () {
    plan(5);

    ok(3 == 3);
    is("fnord", "eek", "two different strings not that way?");
    ok(3 <= 8732, "%d <= %d", 3, 8732);
    like("fnord", "f(yes|no)r*[a-f]$");
    cmp_ok(3, ">=", 10);

    done_testing();
}
32
Ovid

K dispozici je elegantní rámec pro testování jednotek pro C s podporou falešných objektů nazvaný cmocka . Vyžaduje pouze standardní knihovnu C, pracuje na řadě výpočetních platforem (včetně zabudovaných) as různými kompilátory.

Má také podporu pro různé formáty výstupu zpráv, jako je podjednotka, testovací protokol a zprávy XML XML.

program cmocka byl vytvořen také pro práci na integrovaných platformách a má také podporu Windows.

Jednoduchý test vypadá takto:

#include <stdarg.h>
#include <stddef.h>
#include <setjmp.h>
#include <cmocka.h>

/* A test case that does nothing and succeeds. */
static void null_test_success(void **state) {
    (void) state; /* unused */
}

int main(void) {
    const struct CMUnitTest tests[] = {
        cmocka_unit_test(null_test_success),
    };
    return cmocka_run_group_tests(tests, NULL, NULL);
}

API je plně zdokumentováno a několik příkladů je součástí zdrojového kódu.

Chcete-li začít s cmockou, přečtěte si článek o LWN.net: Testování jednotek s falešnými objekty v C

cmocka 1.0 byl vydán v únoru 2015.

26
asn

Nedostal jsem daleko testování starší aplikace C, než jsem začal hledat způsob, jak zesměšňovat funkce. Potřeboval jsem falešně izolovat soubor C, který chci testovat od ostatních. Zkusil jsem cmock a myslím, že to přijmu.

Cmock prohledává soubory záhlaví a generuje falešné funkce na základě prototypů, které najde. Mocks vám umožní testovat soubor C v dokonalé izolaci. Vše, co musíte udělat, je propojit zkušební soubor s falešnými namísto skutečných souborů objektů.

Další výhodou programu cmock je to, že bude ověřovat parametry předávané zesměšňovaným funkcím a umožní vám určit, jakou návratovou hodnotu by simulované funkce měly poskytovat. To je velmi užitečné pro testování různých toků provádění ve vašich funkcích.

Testy se skládají z typických funkcí testA (), testB (), ve kterých vytváříte očekávání, voláte funkce pro testování a kontrolu tvrzení.

Posledním krokem je vygenerovat běžec pro vaše testy s jednotou. Cmock je vázán na rámec testování jednoty. Jednotu lze snadno naučit jako jakýkoli jiný rámec pro testování jednotek.

Dobře stojí za vyzkoušení a docela snadno se uchopíte:

http://sourceforge.net/apps/trac/cmock/wiki

Aktualizace 1

Další rámec, který zkoumám, je Cmockery.

http://code.google.com/p/cmockery/

Jedná se o čistě C framework podporující testování jednotek a zesměšňování. Nemá žádnou závislost na Ruby (na rozdíl od Cmocku) a má velmi malou závislost na externích libsech.

To vyžaduje trochu více manuální práce k nastavení falešných, protože nedochází k generování kódu. To nepředstavuje pro existující projekt spoustu práce, protože prototypy se příliš nezmění: jakmile budete mít své výsměchy, nebudete je muset chvíli měnit (to je můj případ). Extra psaní poskytuje úplnou kontrolu zesměšňování. Pokud se vám něco, co se vám nelíbí, jednoduše změníte.

Není potřeba speciální testovací běžec. Musíte pouze vytvořit řadu testů a předat je do funkce run_tests. Trochu více manuální práce také tady, ale rozhodně se mi líbí myšlenka na samostatný autonomní rámec.

Navíc obsahuje několik šikovných triků, které jsem nevěděl.

Celkově Cmockery potřebuje trochu větší porozumění falešných, než začít. Příklady by vám to měly pomoci překonat. Vypadá to, že dokáže pracovat s jednodušší mechanikou.

20
Philippe A.

Jako nováček C jsem našel snímky s názvem Testem řízený vývoj v C velmi užitečný. V zásadě používá standardní assert() spolu s && k doručení zprávy, bez jakýchkoli vnějších závislostí. Pokud je někdo zvyklý na plný testovací rámec, pravděpodobně to neudělá :)

15
chelmertz

Nepoužívám rámec, pouze používám automatické kontroly "check" cílové podpory. Implementujte „hlavní“ a použijte tvrzení.

Můj testovací ředitel Makefile.am vypadal takto:

check_PROGRAMS = test_oe_amqp

test_oe_amqp_SOURCES = test_oe_amqp.c
test_oe_amqp_LDADD = -L$(top_builddir)/components/common -loecommon
test_oe_amqp_CFLAGS = -I$(top_srcdir)/components/common -static

TESTS = test_oe_amqp
12
navicore

Existuje CUnit

A Embedded Unit je framework pro testování jednotek pro Embedded C System. Jeho design byl zkopírován z JUnit a CUnit a dalších a poté byl trochu upraven pro Embedded C System. Vestavěná jednotka nevyžaduje std C libs. Všechny objekty jsou přiděleny do oblasti const.

A Tessy automatizuje testování jednotky vestavěného softwaru.

12
prakash

Pro snadnou použitelnost a přenositelnost jsme napsali CHEAT (hostováno na GitHub ).

Nemá žádné závislosti a nevyžaduje instalaci ani konfiguraci. Je potřeba pouze soubor záhlaví a testovací případ.

#include <cheat.h>

CHEAT_TEST(mathematics_still_work,
    cheat_assert(2 + 2 == 4);
    cheat_assert_not(2 + 2 == 5);
)

Testy se kompilují do spustitelného souboru, který se stará o provádění testů a hlášení jejich výsledků.

$ gcc -I . tests.c
$ ./a.out
..
---
2 successful of 2 run
SUCCESS

Má také hezké barvy.

12
Tuplanolla

Kniha Michaela Feathera „Efektivně pracuje se starým kódem“ představuje řadu technik specifických pro testování jednotek během vývoje C.

Existují techniky související s injekcí závislosti, které jsou specifické pro C, které jsem nikde jinde neviděl.

11

CppUTest - Vysoce doporučený rámec pro testování C kódu jednotky.

Příklady v knize, která je uvedena v tomto vlákně TDD pro vložený C , jsou psány pomocí CppUTest.

7
ratkok

jiné než moje zřejmá zaujatost

http://code.google.com/p/seatest/

je pěkný jednoduchý způsob, jak testovat C kód. napodobuje xUnit

6
Keith Nicholas

Používám CxxTest pro vestavěné prostředí c/c ++ (především C++).

Dávám přednost CxxTestu, protože má skript Perl/python pro vytvoření testovacího běhounu. Po malém sklonu, abyste si jej mohli nastavit (ještě menší, protože nemusíte psát testovací běžec), je to docela snadné (zahrnuje ukázky a užitečnou dokumentaci). Největší prací bylo nastavení „hardwaru“ pro přístup k kódu, abych mohl efektivně testovat jednotky/moduly. Poté je snadné přidat nové případy testování jednotek.

Jak již bylo zmíněno, jedná se o testovací rámec jednotky C/C++. Budete tedy potřebovat kompilátor C++.

živatelská příručka CxxTestCxxTest Wiki

6
Zing-

Po přečtení Minunitu jsem si myslel, že lepší způsob je založit test v prosazovacím makru, který používám podobně jako technika defenzivního programu. Takže jsem použil stejnou myšlenku Minunitu smíchanou se standardním tvrzením. Můžete vidět můj framework (dobré jméno může být NoMinunit) v blog k0ga

Google má vynikající testovací rámec. https://github.com/google/googletest/blob/master/googletest/docs/primer.md

A ano, pokud to vidím, bude to fungovat s obyčejným C, tj. Nevyžaduje funkce C++ (může vyžadovat kompilátor C++, ne jistý).

4
Paweł Hajdan
4
Landon Kuhn

Cmockery je nedávno spuštěný projekt, který se skládá z velmi snadno použitelné knihovny C pro psaní testů jednotek.

4

Nejprve se podívejte sem: http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks#C

Moje společnost má knihovnu C, kterou naši zákazníci používají. K testování kódu používáme CxxTest (C++ unit test library). CppUnit bude také fungovat. Pokud jste uvízli v C, doporučil bych RCUNIT (ale CUnit je také dobrý).

3
Kevin
2
Tony Bai

API Sanity Checker - testovací rámec pro knihovny C/C++:

Automatický generátor základních testů jednotek pro sdílenou knihovnu C/C++. Je schopen generovat přiměřená (ve většině, ale bohužel ne ve všech) vstupních datech pro parametry a skládat jednoduché („rozumné“ nebo „mělké“ kvalitativní) testovací případy pro každou funkci v API prostřednictvím analýzy deklarací v záhlaví soubory.

Kvalita generovaných testů umožňuje kontrolovat nepřítomnost kritických chyb v jednoduchých případech použití. Nástroj je schopen vytvářet a provádět generované testy a detekovat pády (segfaulty), přerušení, všechny druhy vysílaných signálů, nenulový návratový kód programu a zavěšení programu.

Příklady:

2
linuxbuild

Použil jsem RCUNIT , abych provedl nějaké testování jednotky na vložený kód na PC před testováním na cíli. Dobrá abstrakce hardwarového rozhraní je důležitá, protože endianness a registry mapované v paměti vás zabijí.

2
Gerhard

Pokud znáte JUnit, doporučuji CppUnit. http://cppunit.sourceforge.net/cppunit-wiki

To je za předpokladu, že máte kompilátor c ++, který provádí testy jednotek. pokud ne, pak musím souhlasit s Adamem Rosenfieldem, že kontrola je to, co chcete.

2
Kwondri

LibU ( http://koanlogic.com/lib ) má modul pro testování jednotek, který umožňuje explicitní závislosti testovací sady/případu, izolaci testu, paralelní provádění a přizpůsobitelný formátovací modul sestavy (výchozí formáty jsou xml a txt) ).

Knihovna má licenci BSD a obsahuje mnoho dalších užitečných modulů - vytváření sítí, ladění, běžně používané datové struktury, konfigurace atd. - pokud je potřebujete ve svých projektech ...

1
bongo

Jsem překvapen, že se nikdo nezmínil Cutter (http://cutter.sourceforge.net/) Můžete vyzkoušet C a C++, bezproblémově se integruje s autotooly a má k dispozici opravdu pěkný tutoriál.

1
Kris

Jedna technika, která se má použít, je vyvinout testovací kód jednotky s rámcem C++ xUnit (a kompilátorem C++), zatímco zdroj zdroje pro cílový systém zůstane zachován jako moduly C.

Ujistěte se, že svůj zdroj C pravidelně kompilujete pod křížovým kompilátorem, pokud možno automaticky s testy jednotek.

1
quamrana

Pokud jste stále v honbě za testovacími rámci, CUnitWin32 je jedna pro platformu Win32/NT.

To řeší jeden zásadní problém, kterému jsem čelil s jinými testovacími rámci. Konkrétně globální/statické proměnné jsou v deterministickém stavu, protože každý test je prováděn jako samostatný proces.

0
Dushara

V případě, že cílíte na platformy Win32 nebo režim jádra NT, měli byste se podívat na cfix .

0
Johannes Passing

Právě jsem napsal Libcut z frustrace s existujícími knihovnami testování jednotek C. Má automatické typování řetězců primitivů (není třeba test_eq_int, test_eq_long, test_eq_short atd.;; Pouze dvě různé sady pro primitivy a řetězce) a skládá se z jednoho souboru záhlaví. Zde je krátký příklad:

#include <libcut.h>

LIBCUT_TEST(test_abc) {
    LIBCUT_TEST_EQ(1, 1);
    LIBCUT_TEST_NE(1, 0);
    LIBCUT_TEST_STREQ("abc", "abc");
    LIBCUT_TEST_STRNE("abc", "def");
}

LIBCUT_MAIN(test_abc);

Funguje to však pouze s C11.

0
kirbyfan64sos