Frage

ich auf einem Embedded-System in diesem Sommer arbeitete in geraden C geschrieben Es war ein bestehendes Projekt, das die Firma für die ich übernommen hatte arbeiten. Ich habe ziemlich daran gewöhnt, Unit-Tests in Java zu schreiben JUnit verwenden, aber mit Verlust war in Bezug auf die beste Art und Weise Unit-Tests für existierenden Code (die benötigten Refactoring) sowie neuer Code hinzugefügt, um das System zu schreiben.

Gibt es eine Möglichkeit Unit-Tests einfach in C-Code so einfach wie Unit-Tests von Java-Code mit, zum Beispiel, JUnit zu machen? Einsicht, die speziell auf dem Embedded-Entwicklung (Cross-Kompilierung bewaffnen-Linux-Plattform) gelten würde, würde sehr geschätzt.

War es hilfreich?

Lösung

Eine Einheit Test-Framework in C ist prüfen ; eine Liste der Gerüste Testeinheit in C können rel="noreferrer"> hier zu finden und wiedergegeben wird, unten. Je nachdem, wie viele Standard-Bibliotheksfunktionen Ihre Laufzeit hat, können Sie oder nicht in der Lage sein, einer von denen zu verwenden.

  

AceUnit

     

AceUnit (Advanced C und Embedded Unit) bezeichnet sich selbst als einen komfortablen C-Code Unit-Test-Framework. Es wird versucht zu JUnit 4.x mimick und beinhaltet Reflexions-ähnliche Funktionen. AceUnit kann in Ressourceneinschränkungs Umgebungen verwendet werden, z.B. Embedded-Software-Entwicklung, und vor allem läuft es gut in Umgebungen, in denen Sie nicht einen einzigen Standard-Header-Datei enthalten kann und eine einzelne Standard-C-Funktion von den ANSI / ISO-C-Bibliotheken nicht aufrufen kann. Es hat auch einen Windows-Port. Es verwendet keine Gabeln abzufangen Signale, obwohl die Autoren Interesse bekundet haben eine solche Funktion in hinzufügen. Siehe AceUnit Homepage .

     

GNU autounit

     

Viel auf die gleiche Linie wie überprüfen, einschließlich Forking Unit-Tests in einem separaten Adressraum laufen (in der Tat, der ursprüngliche Autor von Check entlehnt die Idee von GNU autounit). GNU autounit verwendet GLib ausführlich, was bedeutet, dass die Verknüpfung und so müssen spezielle Optionen, aber dies kann nicht ein großes Problem für Sie sein, vor allem, wenn Sie bereits GTK oder GLib verwenden. Siehe GNU autounit Homepage .

     

Cunit

     

Auch verwendet GLib, aber Gabel nicht den Adressraum von Unit-Tests zu schützen.

     

CUnit

     

Standard C, mit Plänen für eine Win32 GUI-Implementierung. Derzeit nicht blechen oder sonst den Adressraum von Unit-Tests schützen. In der frühen Entwicklung. Siehe CUnit Homepage .

     

niedlichste

     

Ein einfacher Rahmen mit nur einem .c und einer .h-Datei, die Sie in Ihren Quellbaum fallen. Finden Sie in der niedlichste Homepage .

     

CppUnit

     

Die Premier-Einheit Test-Framework für C ++; Sie können es auch C-Code zu testen. Es ist stabil, aktiv entwickelt und verfügt über eine GUI-Schnittstelle. Die primären Gründe nicht CppUnit für C zu verwenden, sind erstens, dass es recht groß ist, und zweitens haben Sie Ihre Tests in C ++ zu schreiben, was bedeutet, dass Sie einen C ++ Compiler benötigen. Wenn diese klingen nicht wie betrifft, ist es auf jeden Fall eine Überlegung wert, zusammen mit anderen C ++ Unit-Test-Frameworks. Siehe CppUnit Homepage .

     

embUnit

     

embUnit (Embedded Unit) ist eine weitere Einheit Test-Framework für Embedded-Systeme. Dies scheint durch AceUnit abgelöst werden. Embedded Einheit Homepage .

     

MinUnit

     

Eine minimale Menge von Makros und das ist es! Der Punkt ist, zu zeigen, wie einfach es zu Einheit testen Sie Ihren Code ist. Siehe MinUnit Homepage .

     

CUnit für Mr. Ando

     

Eine CUnit Implementierung, die ziemlich neu ist, und offenbar noch in der frühen Entwicklung. Sehen Sie sich die CUnit für Mr. Ando Homepage .

     

Diese Liste wurde zuletzt März 2008 aktualisiert.

Weitere Frameworks:

CMocka

CMocka ist ein Test-Framework für C mit Unterstützung für Mock-Objekte. Es ist einfach zu bedienen und Setup.

Siehe der CMocka Homepage .

Kriterium

Criterion ist eine plattformübergreifende C-Einheit Test-Framework Stütz automac Testregistrierung, parametrisierten Tests, Theorien und das kann auf mehrere Ausgangsformate, einschließlich TAP und JUnit XML. Jeder Test wird in einem eigenen Prozess ausgeführt, so Signale und Abstürze können bei Bedarf gemeldet oder getestet werden.

Siehe Criterion Homepage für weitere Informationen.

HWUT

HWUT ist ein allgemeine Einheit Test-Tool mit großer Unterstützung für C. Es kann helfen Makefiles zu erstellen, erzeugt massive Testfälle codierten in minimal ‚Iteration Tabellen‘, zu Fuß entlang Zustandsmaschinen, erzeugen C-Stubs und vieles mehr. Der allgemeine Ansatz ist ziemlich einzigartig: Verdicts auf ‚gutes stdout / bad stdout‘ basieren. Die Vergleichsfunktion, ist aber flexibel. Somit kann jede Art von Skript für die Überprüfung verwendet werden. Es kann zu jeder Sprache angewendet werden, die Standardausgabe erzeugen kann.

Siehe der HWUT Homepage .

CGreen

Eine moderne, tragbare, sprachübergreifende Unit-Tests und spöttischen Rahmen für C und C ++. Es bietet eine optionale BDD Notation, eine spöttische Bibliothek, die Fähigkeit, sie in einem einzigen Prozess zu laufen (zu erleichtern Debugging). Ein Testläufer, die automatisch die Testfunktionen entdecken, ist verfügbar. Aber Sie können Ihre eigene programmatisch erstellen.

Alle diese Funktionen (und mehr) sind in der CGreen Handbuch erläutert.

Wikipedia gibt eine detaillierte Liste des C-Einheit Test-Frameworks unter Liste der Einheit Test-Frameworks: C

Andere Tipps

Persönlich mag ich die Google Test-Framework .

Die eigentliche Schwierigkeit bei der Prüfung von C-Code bricht die Abhängigkeiten von externen Modulen, so dass Sie Code in Einheiten isolieren können. Dies kann besonders problematisch sein, wenn Sie versuchen, Tests um Legacy-Code zu erhalten. In diesem Fall finde ich mich oft, den Linker mit Stubs Funktionen in Tests verwenden.

Das ist, was die Leute beziehen, wenn sie über „ Nähte “ sprechen. In C ist die einzige Möglichkeit ist, den Pre-Prozessor oder den Linker zu verwenden, um Ihre Abhängigkeiten zu verspotten.

Eine typische Test-Suite in eines meiner C-Projekten könnte wie folgt aussehen:

#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));
}

Beachten Sie, dass Sie tatsächlich einschließlich der C-Datei und nicht die Header-Datei . Dies bietet den Vorteil des Zugangs zu allen statischen Datenelementen. Hier verspotten ich meine Loggers (die in logger.o sein könnten und eine leere Implementierung geben. Das bedeutet, dass die Testdatei kompiliert und Links unabhängig vom Rest der Codebasis und führt in der Isolation.

Wie für den Code Cross-Kompilierung, damit dies funktioniert müssen Sie eine gute Ausstattung auf dem Ziel. Ich habe dies auf einer PowerPC-Architektur auf Linux kompiliert mit googletest Kreuz getan. Dies macht Sinn, weil es Ihnen eine volle Schale und os haben Ihre Ergebnisse zu sammeln. Für weniger reiche Umgebungen (die ich als etwas ohne ein vollständiges O klassifiziere) sollten Sie nur bauen und auf dem Host ausgeführt werden. Sie sollen dies auf jeden Fall tun, so dass Sie die Tests automatisch als Teil des Build ausgeführt werden können.

I C ++ Code finde Testen im Allgemeinen ist viel einfacher, aufgrund der Tatsache, dass OO-Code in der Regel viel weniger verbunden als prozedurale (natürlich hängt dies stark von Stil-Codierung). Auch in C ++ können Sie Tricks wie Dependency Injection und Verfahren überwiegendes verwenden, um Nähte in Code zu erhalten, die sonst eingekapselt ist.

Michael Feathers hat eine rel="noreferrer">. In einem Kapitel behandelt er Techniken, um mit Nicht-OO-Code zu tun, die ich sehr empfehlen kann.

Bearbeiten : Ich habe ein Blog-Post über Unit prozeduralen Code zu testen, mit Quelle auf GitHub .

Bearbeiten : Es gibt einen neues Buch von den speziell an Unit-Tests C-Code Pragmatische Programmierer das zu kommen, die a href <= "http://meekrosoft.wordpress.com/2011/03/25/book-review-test-driven-development -für-embedded-c-beta /“rel = "noreferrer"> ich empfehle hoch.

Minunit ist ein unglaublich einfacher Unit-Test-Framework. Ich bin es Unit-Test c Mikrocontroller Code für avr.

Ich bin derzeit mit dem süßeste Unit-Test-Framework:

http://cutest.sourceforge.net/

Es ist ideal für Embedded-Systeme, da es sehr leicht und einfach. Ich hatte keine Probleme bekommen es auf der Zielplattform, wie auf dem Desktop als auch zu arbeiten. Neben den Unit-Tests schreiben, alles, was erforderlich ist:

  • eine Header-Datei enthalten, wo immer Sie rufen die niedlichsten Routinen
  • eine einzige zusätzliche ‚C‘ Datei zu sein kompilierte / in das Bild verknüpft
  • einige einfache Code hinzugefügt, um zur Haupt zu Einrichtung und die Unit-Tests nennen - I Gerade eben habe in einem speziellen main () Funktion, die kompiliert wird, wenn Unittest wird während des definierten bauen.

Das System benötigt einen Haufen und einige stdio Funktionalität zu unterstützen (die nicht alle eingebetteten Systeme haben). Aber der Code ist einfach genug, dass Sie wahrscheinlich in Alternativen zu diesen Anforderungen arbeiten können, wenn Ihre Plattform sie nicht hat.

Mit einigen gezielten Einsatz von extern "C" {} Blöcke unterstützt es auch Tests C ++ gut.

sage, dass ich fast die gleich wie ratkok aber wenn Sie einen eingebetteten Twist auf die Unit-Tests haben dann ...

Unity - Highly recommended Rahmen für die C-Code-Unit-Tests.

Die Beispiele in dem Buch, das in diesem Thread TDD für Embedded-C genannt wird sind mit Unity (und CppUTest) geschrieben.

Sie können auch einen Blick auf libtap , einem C-Test-Framework nehmen wollen, die den Test Alles ausgibt Protocol (TAP) und integriert gut mit einer Vielzahl von Werkzeugen für diese Technologie herauskommen. Es ist vor allem in der dynamischen Sprache Welt verwendet, aber es ist einfach zu bedienen und immer sehr beliebt.

Ein Beispiel:

#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();
}

Es gibt eine elegante Einheit Test-Framework für C mit Unterstützung für Mock-Objekte genannt cmocka . Es erfordert nur die Standard-C-Bibliothek, arbeitet auf einer Reihe von Computer-Plattformen (einschließlich embedded) und mit verschiedenen Compilern.

Es hat auch Unterstützung für verschiedene Nachrichtenausgabeformate wie Subunit, Test Anything Protocol und jUnit XML-Berichte.

cmocka wurde auch auf Embedded-Plattformen zu arbeiten, und hat auch Windows-Unterstützung.

Ein einfacher Test sieht wie folgt aus:

#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);
}

Die API ist vollständig dokumentiert und einige Beispiele sind Teil des Quellcodes.

Um mit cmocka Sie den Artikel auf LWN.net sollte lauten: Unit-Tests mit Mock-Objekte in C

cmocka 1.0 wurde Februar 2015 veröffentlicht.

Ich habe nicht weit ein Vermächtnis C-Anwendung zu testen, bevor ich auf der Suche nach einem Weg, um Mock-Funktionen gestartet. Ich brauchte Mocks schlecht die C-Datei ich von anderen testen möchten, zu isolieren. Ich habe cmock einen Versuch und ich glaube, ich es annehmen wird.

Cmock durchsucht die Header-Dateien und erzeugt Mock-Funktionen basierend auf Prototypen es findet. Mocks ermöglicht es Ihnen, eine C-Datei in perfekter Isolierung zu testen. Alles was Sie tun müssen, ist Ihre Testdatei mit Mocks statt des echten Objektdateien zu verknüpfen.

Ein weiterer Vorteil von cmock ist, dass es übergebenen Parameter zu spotten Funktionen validieren, und es lässt Sie angeben, welche Rückgabewert die Mocks bieten sollte. Dies ist sehr nützlich, verschiedene Flüsse der Ausführungs in Ihren Funktionen zu testen.

Tests bestehen aus dem typischen testA (), TestB () -Funktionen, in dem Sie die Erwartungen, die Anruffunktionen aufbauen zu testen und überprüfen behauptet.

Der letzte Schritt ist ein Läufer für Ihre Tests mit der Einheit zu erzeugen. Cmock an die Einheit Test-Framework gebunden. Die Einheit ist so einfach wie jede andere Einheit Test-Framework zu lernen.

Nun einen Versuch wert und ganz leicht zu verstehen:

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

Update 1

Ein weiterer Rahmen, den ich untersucht habe ist Cmockery.

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

Es ist ein reiner C Rahmen unterstützt Unit-Tests und spöttisch. Es hat keine Abhängigkeit von Rubin (im Gegensatz zu Cmock), und es hat eine sehr geringe Abhängigkeit von externen Libs.

Es erfordert etwas mehr manuelle Arbeit zu Setup verspottet, weil es keine Code-Generierung der Fall ist. Das macht nicht viel Arbeit für ein vorhandenes Projekt dar, da Prototypen wird nicht viel ändern: Sobald Sie Ihre Mocks haben, werden Sie nicht sie für eine Weile ändern müssen (dies ist mein Fall). Extra Typisierung bietet die vollständige Kontrolle über spottet. Wenn es etwas, das Sie nicht mögen, Sie einfach Ihre mock ändern.

Keine Notwendigkeit eines speziellen Testläufer. Sie müssen nur noch eine Reihe von Tests erstellen und an eine run_tests Funktion übergeben. Ein bisschen mehr manuelle Arbeit hier auch, aber ich auf jeden Fall, wie die Idee eines in sich geschlossenen autonomen Rahmen.

Plus enthält es einige nette C Tricks, die ich nicht kannte.

Insgesamt Cmockery braucht ein bisschen mehr Verständnis von Mocks, um loszulegen. Diese Beispiele sollen Ihnen dabei helfen zu überwinden. Es sieht aus wie es die Arbeit mit einfacher Mechanik zu tun.

Als C Neuling, fand ich die genannten Folien Testgetriebene Entwicklung in C sehr hilfreich. Grundsätzlich verwendet es die Standard assert() zusammen mit && eine Nachricht zu übermitteln, ohne externe Abhängigkeiten. Wenn jemand zu einem vollen Stack-Test-Framework verwendet wird, wird dies wahrscheinlich nicht tun:)

Es gibt CUnit

Und Embedded Einheit ist Unit Testing Framework für Embedded C-System. Sein Entwurf wurde von JUnit und CUnit kopiert und mehr, und dann etwas für Embedded C-System angepasst. Embedded Einheit nicht std C Libs erfordern. Alle Objekte werden zu konst Bereich zugeordnet.

Und Tessy automatisiert die Unit-Tests von Embedded Software .

Ich verwende keinen Rahmen, verwende ich nur Autotools „check“ Ziel Unterstützung. Implementieren einer "Haupt" und die Nutzung assert (s).

Mein Test dir Makefile.am (n) wie folgt aussehen:

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

Wir schrieben CHEAT (hosted auf GitHub ) für die einfache Bedienbarkeit und Portabilität.

Es hat keine Abhängigkeiten und erfordert keine Installation oder Konfiguration. Nur eine Header-Datei und ein Testfall erforderlich ist.

#include <cheat.h>

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

Tests kompilieren in eine ausführbare Datei, die Pflege übernimmt die Tests und ihre Ergebnisse berichten.

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

Es hat schöne Farben zu.

Michael Feder Buch „Effektives Arbeiten mit Legacy Code“ präsentiert während C Entwicklung viele Techniken spezifisch für Unit-Tests.

Es gibt Techniken, um Dependency Injection bezogen, die C spezifisch sind, die ich nirgendwo anders gesehen.

CppUTest - Highly recommended Rahmen für die C-Code-Unit-Tests.

Die Beispiele in dem Buch, das in diesem Thread erwähnt TDD für Embedded C verwenden CppUTest geschrieben.

Ich benutze CxxTest für eine eingebetteten c / c ++ Umgebung (vor allem C ++).

Ich ziehe CxxTest, weil es ein Perl / Python-Skript hat den Test Runner zu bauen. Nach einer kleinen Steigung ihm Setup (noch kleiner, da Sie den Test Runner nicht schreiben müssen) zu bekommen, es (enthält Beispiele und nützliche Dokumentation) zu verwenden, ziemlich einfach ist. Die Arbeit wurde die Einrichtung der ‚Hardware‘ der Code greift so konnte ich Einheit / Modultest effektiv. Danach ist es einfach, neue Einheit Testfall hinzuzufügen.

Wie bereits erwähnt, ist es eine C / C ++ Unit-Test-Framework. So erhalten Sie einen C ++ Compiler benötigen.

CxxTest Benutzerhandbuch CxxTest Wiki

andere als meine offensichtliche Voreingenommenheit

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

ist eine schöne einfache Art und Weise zu Unit-Test von C-Code. ahmt xUnit

Nach dem Lesen Minunit Ich dachte, ein besserer Weg Basis des Test in assert Makro, das ich viel wie defensivem Programm Technik verwenden. So habe ich die gleiche Idee von Minunit mit Standard-Assertion gemischt. Sie können mein Rahmen (ein guter Name sein könnte NoMinunit) in k0ga Blog

Google hat eine ausgezeichnete Test-Framework. https://github.com/google/googletest/blob/ Master / googletest / docs / primer.md

Und ja, soweit ich sehe, es wird mit einfachen C arbeiten, das heißt nicht erforderlich C ++ Funktionen (möglicherweise C ++ Compiler erfordert, nicht sicher).

Cmockery ist ein kürzlich gestartetes Projekt, das auf einem sehr einfaches besteht Einheit C-Bibliothek verwendet zum Schreiben Tests.

Zuerst schauen Sie hier: http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks# C

Meine Firma hat eine C-Bibliothek unserer Kunden nutzen. Wir verwenden CxxTest (eine C ++ Unit-Test-Bibliothek), um den Code zu testen. CppUnit wird auch funktionieren. Wenn Sie in C stecken, würde ich empfehlen RCUNIT (aber CUnit ist auch gut).

Wenn Sie mit JUnit vertraut sind, dann empfehle ich CppUnit. http://cppunit.sourceforge.net/cppunit-wiki

Das ist vorausgesetzt, Sie haben c ++ Compiler die Unit-Tests zu tun. wenn nicht, dann muss ich mit Adam Rosenfield zustimmen, dass der Check ist das, was Sie wollen.

Ich benutzen RCUNIT für Embedded-Code auf dem PC einige Unit-Tests zu tun vor dem Test auf dem Ziel. Gute Hardware-Schnittstelle Abstraktion ist wichtig, sonst endianness und Memory-Mapped-Register werden Sie töten.

API Sanity Checker - Test-Framework für C / C ++ Bibliotheken:

  

Ein automatischer Generator von Grundeinheitstests für eine gemeinsamen C / C ++ Bibliothek. Es ist in der Lage vernünftig zu erzeugen (in den meisten, aber leider nicht in alle Fälle) Eingangsdaten für Parameter und komponieren einfach ( „geistige Gesundheit“ oder „flache“ -Qualität) Testfälle für jede Funktion in der API durch die Analyse von Erklärungen in Kopf Dateien.

     

Die Qualität der generierten Tests ermöglicht Fehlen kritischer Fehler in einfachen Anwendungsfällen zu überprüfen. Das Werkzeug ist in der Lage zu bauen und generierten Tests auszuführen und Abstürze (segfaults) zu erfassen, bricht, alle Arten von ausgesendeten Signalen, von Null Programmrückkehrcode und Programm hängen.

Beispiele:

Eine Technik zu verwenden, ist die Einheit Testcode mit einem C ++ xUnit Framework (und C ++ Compiler), zu entwickeln, während der Quelle für das Zielsystem als C-Module aufrechterhalten wird.

Achten Sie darauf, regelmäßig Ihre C-Quelle unter den Cross-Compiler kompilieren, automatisch mit Unit-Tests, wenn möglich.

LiBu ( http://koanlogic.com/libu ) ein Komponententest-Modul, die expliziten Test ermöglicht Suite / Fall Abhängigkeiten Test Isolation, die parallele Ausführung und ein anpassbare Report-Formatierer (Standardformate sind xML und txt).

Die Bibliothek ist BSD lizenziert und enthält viele andere nützliche Module - Vernetzung, Debuggen, häufig verwendete Datenstrukturen, Konfiguration usw. - sollten Sie sie in Ihren Projekten benötigen ...

Ich bin überrascht, dass niemand erwähnt Cutter (http://cutter.sourceforge.net/) Sie können testen, C und C ++, es integriert sich nahtlos mit Autotools und hat eine wirklich schöne Tutorial zur Verfügung.

Falls Sie zielen auf Win32-Plattformen oder NT-Kernel-Modus, sollten Sie einen Blick auf cfix .

Wenn Sie noch auf der Suche nach Test-Frameworks sind, CUnitWin32 ist ein für die Win32 / NT-Plattform.

Dies löst ein grundsätzliches Problem, das ich mit anderem Test-Frameworks konfrontiert. Und zwar global / statische Variablen sind in einem deterministischen Zustand, da jeder Test als separater Prozess ausgeführt wird.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top