Wie kann ich Arduino-Code testen?

185

Ich möchte meinen Arduino-Code testen können. Im Idealfall kann ich alle Tests ausführen, ohne den Code auf das Arduino hochladen zu müssen. Welche Tools oder Bibliotheken können mir dabei helfen?

Es befindet sich ein Arduino-Emulator in der Entwicklung, der nützlich sein könnte, aber noch nicht einsatzbereit zu sein scheint.

AVR Studio von Atmel enthält einen Chip-Simulator, der nützlich sein könnte, aber ich kann nicht sehen, wie ich ihn in Verbindung mit der Arduino IDE verwenden würde.

Matthew Murdoch
quelle
Es gibt einen weiteren Thread zu dieser Frage aus dem Jahr 2011 unter arduino.cc/forum/index.php?action=printpage;topic=54356.0
Jakob
Danke @Jakob. Ein Arduino-Simulator, auf den in diesem Thread verwiesen wird (mit anderen potenziell nützlichen Links am Ende der Seite): arduino.com.au/Simulator-for-Arduino.html
Matthew Murdoch
5
Leider ist es nur für Windows, ich würde gerne eine Möglichkeit sehen, Arduino-Code einfach über die Befehlszeile ohne Closed-Source- oder Hardware-Abhängigkeiten zu kompilieren und auszuführen.
Jakob
3
Ein kleines Update, 5 Jahre später: Simavr ist immer noch sehr aktiv und hat sich stark verbessert, seit die Frage gestellt wurde. Ich dachte, es verdient, näher an die Spitze gebracht zu werden. Und es könnte das richtige Werkzeug für Regressionstests, szenariobasierte Tests und warum nicht auch Unit-Tests sein. Auf diese Weise ist der Code, den Sie testen, der gleiche wie der auf der Zielhardware.
Zmo
Ziehen Sie für wichtige Projekte einen Hardwaretester in Betracht. Eine andere MCU als Zeit- und Test-Tasten- / Schalterreaktionen, Startzeit, Temperatur, V / MA-Nutzung, seltsame Optionspermutationen usw. Ja, es muss mehr Hardware erstellt werden, aber es kann eine Sicherheitsebene für die Revisionserstellung hinzugefügt werden. Viele Pro-Geräte verwenden jtag et al.
Dandavis

Antworten:

136

Führen Sie keine Komponententests auf dem Arduino-Gerät oder Emulator durch

Der Fall gegen Mikrocontroller-Geräte- / Emulator- / Sim-basierte Tests

Es wird viel darüber diskutiert, was Unit-Test bedeutet, und ich versuche hier nicht wirklich, darüber zu streiten. Dieser Beitrag ist nicht zu sagen Sie zu vermeiden , alle praktischen Tests auf Ihre ultimative Ziel - Hardware. Ich versuche, einen Punkt zur Optimierung Ihres Entwicklungs-Feedback-Zyklus zu machen, indem ich Ihre Zielhardware aus Ihren alltäglichsten und häufigsten Tests eliminiere. Es wird angenommen, dass die zu testenden Einheiten viel kleiner sind als das gesamte Projekt.

Der Zweck von Unit-Tests besteht darin, die Qualität Ihres eigenen Codes zu testen. Unit-Tests sollten im Allgemeinen niemals die Funktionalität von Faktoren testen, die außerhalb Ihrer Kontrolle liegen.

Stellen Sie sich das so vor: Selbst wenn Sie die Funktionalität der Arduino-Bibliothek, der Mikrocontroller-Hardware oder eines Emulators testen, können solche Testergebnisse absolut nichts über die Qualität Ihrer eigenen Arbeit aussagen. Daher ist es weitaus wertvoller und effizienter, Komponententests zu schreiben, die nicht auf dem Zielgerät (oder Emulator) ausgeführt werden.

Häufige Tests auf Ihrer Zielhardware haben einen schmerzhaft langsamen Zyklus:

  1. Passen Sie Ihren Code an
  2. Kompilieren und auf das Arduino-Gerät hochladen
  3. Beobachten Sie das Verhalten und raten Sie, ob Ihr Code das tut, was Sie erwarten
  4. Wiederholen

Schritt 3 ist besonders unangenehm, wenn Sie erwarten, Diagnosemeldungen über die serielle Schnittstelle zu erhalten, Ihr Projekt jedoch die einzige serielle Hardware-Schnittstelle Ihres Arduino verwenden muss. Wenn Sie der Meinung sind, dass die SoftwareSerial-Bibliothek hilfreich sein könnte, sollten Sie wissen, dass dies wahrscheinlich alle Funktionen stört, die ein genaues Timing erfordern, z. B. das gleichzeitige Generieren anderer Signale. Dieses Problem ist mir passiert.

Wenn Sie Ihre Skizze mit einem Emulator testen und Ihre zeitkritischen Routinen perfekt laufen, bis Sie sie auf das eigentliche Arduino hochladen, ist die einzige Lektion, die Sie lernen werden, dass der Emulator fehlerhaft ist - und dies immer noch zu wissen verrät nichts über die Qualität Ihrer eigenen Arbeit.

Was soll ich tun, wenn es albern ist, auf dem Gerät oder Emulator zu testen ?

Sie verwenden wahrscheinlich einen Computer, um an Ihrem Arduino-Projekt zu arbeiten. Dieser Computer ist um Größenordnungen schneller als der Mikrocontroller. Schreiben Sie die Tests, die auf Ihrem Computer erstellt und ausgeführt werden sollen .

Denken Sie daran, dass das Verhalten der Arduino-Bibliothek und des Mikrocontrollers entweder korrekt oder zumindest durchweg falsch sein sollte .

Wenn Ihre Tests eine Ausgabe liefern, die Ihren Erwartungen widerspricht, liegt wahrscheinlich ein Fehler in Ihrem getesteten Code vor. Wenn Ihre Testausgabe Ihren Erwartungen entspricht, sich das Programm jedoch beim Hochladen auf das Arduino nicht richtig verhält, wissen Sie, dass Ihre Tests auf falschen Annahmen beruhten und Sie wahrscheinlich einen fehlerhaften Test haben. In beiden Fällen haben Sie echte Einblicke in Ihre nächsten Codeänderungen erhalten. Die Qualität Ihres Feedbacks wurde von " etwas ist kaputt" auf "dieser spezifische Code ist kaputt" verbessert .

Erstellen und Ausführen von Tests auf Ihrem PC

Als erstes müssen Sie Ihre Testziele identifizieren . Überlegen Sie, welche Teile Ihres eigenen Codes Sie testen möchten, und stellen Sie dann sicher, dass Sie Ihr Programm so erstellen , dass Sie einzelne Teile zum Testen isolieren können .

Wenn die Teile, die Sie testen möchten, Arduino-Funktionen aufrufen, müssen Sie in Ihrem Testprogramm Ersatzmodelle bereitstellen. Das ist viel weniger Arbeit als es scheint. Ihre Modelle müssen eigentlich nichts anderes tun, als vorhersehbare Ein- und Ausgaben für Ihre Tests bereitzustellen.

Jeder eigene Code, den Sie testen möchten, muss in anderen Quelldateien als der .pde-Skizze vorhanden sein. Keine Sorge, Ihre Skizze wird auch mit Quellcode außerhalb der Skizze kompiliert. Wenn Sie wirklich dazu kommen, sollte in der Skizzendatei kaum mehr als der normale Einstiegspunkt Ihres Programms definiert werden.

Sie müssen nur noch die eigentlichen Tests schreiben und sie dann mit Ihrem bevorzugten C ++ - Compiler kompilieren! Dies lässt sich wahrscheinlich am besten anhand eines Beispiels aus der Praxis veranschaulichen.

Ein aktuelles Arbeitsbeispiel

Eines meiner hier gefundenen Lieblingsprojekte enthält einige einfache Tests, die auf dem PC ausgeführt werden. Für diese Antwort werde ich nur erläutern, wie ich einige Funktionen der Arduino-Bibliothek und die Tests, die ich zum Testen dieser Modelle geschrieben habe, nachgebildet habe. Dies steht nicht im Widerspruch zu dem, was ich zuvor gesagt habe, dass ich den Code anderer Leute nicht getestet habe, weil ich derjenige war, der die Modelle geschrieben hat. Ich wollte sehr sicher sein, dass meine Modelle korrekt waren.

Quelle von mock_arduino.cpp, die Code enthält, der einige von der Arduino-Bibliothek bereitgestellte Unterstützungsfunktionen dupliziert:

#include <sys/timeb.h>
#include "mock_arduino.h"

timeb t_start;
unsigned long millis() {
  timeb t_now;
  ftime(&t_now);
  return (t_now.time  - t_start.time) * 1000 + (t_now.millitm - t_start.millitm);
}

void delay( unsigned long ms ) {
  unsigned long start = millis();
  while(millis() - start < ms){}
}

void initialize_mock_arduino() {
  ftime(&t_start);
}

Ich verwende das folgende Modell, um eine lesbare Ausgabe zu erzeugen, wenn mein Code Binärdaten auf das serielle Hardwaregerät schreibt.

fake_serial.h

#include <iostream>

class FakeSerial {
public:
  void begin(unsigned long);
  void end();
  size_t write(const unsigned char*, size_t);
};

extern FakeSerial Serial;

fake_serial.cpp

#include <cstring>
#include <iostream>
#include <iomanip>

#include "fake_serial.h"

void FakeSerial::begin(unsigned long speed) {
  return;
}

void FakeSerial::end() {
  return;
}

size_t FakeSerial::write( const unsigned char buf[], size_t size ) {
  using namespace std;
  ios_base::fmtflags oldFlags = cout.flags();
  streamsize oldPrec = cout.precision();
  char oldFill = cout.fill();

  cout << "Serial::write: ";
  cout << internal << setfill('0');

  for( unsigned int i = 0; i < size; i++ ){
    cout << setw(2) << hex << (unsigned int)buf[i] << " ";
  }
  cout << endl;

  cout.flags(oldFlags);
  cout.precision(oldPrec);
  cout.fill(oldFill);

  return size;
}

FakeSerial Serial;

und schließlich das eigentliche Testprogramm:

#include "mock_arduino.h"

using namespace std;

void millis_test() {
  unsigned long start = millis();
  cout << "millis() test start: " << start << endl;
  while( millis() - start < 10000 ) {
    cout << millis() << endl;
    sleep(1);
  }
  unsigned long end = millis();
  cout << "End of test - duration: " << end - start << "ms" << endl;
}

void delay_test() {
  unsigned long start = millis();
  cout << "delay() test start: " << start << endl;
  while( millis() - start < 10000 ) {
    cout << millis() << endl;
    delay(250);
  }
  unsigned long end = millis();
  cout << "End of test - duration: " << end - start << "ms" << endl;
}

void run_tests() {
  millis_test();
  delay_test();
}

int main(int argc, char **argv){
  initialize_mock_arduino();
  run_tests();
}

Dieser Beitrag ist lang genug. Weitere Informationen zu Testfällen finden Sie in meinem Projekt auf GitHub . Ich behalte meine laufenden Arbeiten in anderen Zweigen als dem Master vor. Überprüfen Sie diese Zweige daher auch auf zusätzliche Tests.

Ich habe mich entschieden, meine eigenen leichten Testroutinen zu schreiben, aber es sind auch robustere Unit-Test-Frameworks wie CppUnit verfügbar.

Eisenretter
quelle
1
Das ist eine großartige Antwort! Danke dir!
Jonathan Arkell
5
@WarrenMacEvoy Nochmals, ich denke, Sie haben meinen Rat befolgt und daraus etwas gemacht, was es nicht ist. Sie sollten Ihren Code auf jeden Fall an einem bestimmten Punkt in seiner tatsächlichen Umgebung testen. Mein Argument ist, dass Sie das nicht jeden Tag tun sollten und es auf keinen Fall als Unit-Test bezeichnen sollten.
Iron Savior
1
@toasted_flakes Ich bin mir nicht sicher, woher du das Zitat hast, aber ich habe es nicht gesagt. Unit-Tests, die auf dem Gerät ausgeführt werden, haben viele Probleme - sehr langsame Rückkopplungsschleife, möglicherweise haben Sie keine seriellen Schnittstellen oder andere E / A-Mittel auf Ihrem Zielgerät und sie haben eine sehr begrenzte Kapazität, die sich auf den Umfang von auswirken kann Ihre Testsuite.
Eisenretter
1
@ChristianHujer Sie sollten auf jeden Fall auf echter Hardware testen - niemand sagt, Sie sollten niemals auf Zielhardware testen. In meinem Beitrag geht es darum, Ihren täglichen Entwicklungs-Feedback-Zyklus durch Unit-Tests auf Ihrer Entwicklungsmaschine zu verkürzen. Auf diese Weise wird Ihr Testaufwand minimiert, da Sie nur dann auf Ihrer Zielhardware testen, wenn dies erforderlich ist.
Eisenretter
1
@Benjohn Arduino Skizzenquelldateien hatten früher die Erweiterung "pde", obwohl sie C ++ sind. arduino.cc/en/Guide/Environment#toc1
Iron Savior
63

In Ermangelung bereits vorhandener Unit-Test-Frameworks für Arduino habe ich ArduinoUnit erstellt . Hier ist eine einfache Arduino-Skizze, die ihre Verwendung demonstriert:

#include <ArduinoUnit.h>

// Create test suite
TestSuite suite;

void setup() {
    Serial.begin(9600);    
}

// Create a test called 'addition' in the test suite
test(addition) {
    assertEquals(3, 1 + 2);
}

void loop() {
    // Run test suite, printing results to the serial port
    suite.run();
}
Matthew Murdoch
quelle
18
Die Tests scheinen nur auf dem Arduino zu laufen, daher können Sie sie nicht automatisch auf Ihrem Entwicklungscomputer ausführen. Die Grundidee von Komponententests besteht darin, sie automatisch auszuführen. Das aktuelle Design scheint also eher ein Debugging-Tool zu sein, aber kein echtes Framework für Komponententests.
Jakob
1
Du hast recht. Um diese auf einem PC ausführen zu können, wäre zusätzlich entweder ein Arduino- oder ein AVR-Emulator erforderlich. Es gibt (im Moment) keine echte Hardware-Abstraktionsschicht in den Arduino-Bibliotheken, und die AVR-Emulatoren waren, wie ich sah, alle noch in der Entwicklung. Wenn sich die Dinge jetzt weiterentwickelt haben, könnte dies im Prinzip getan werden.
Matthew Murdoch
12
@MatthewMurdoch Ich fürchte, Sie sind falsch. Per Definition werden Komponententests niemals in der Zielumgebung ausgeführt. Tatsächlich besteht die Idee hinter Unit-Tests darin, die Zielumgebung vollständig vom Testen auszuschließen. Sie werden immer in einer laborähnlichen Umgebung ausgeführt, in der alle Aktivitäten außerhalb des zu testenden Geräts verspottet werden, um sicherzustellen, dass der Erfolg oder Misserfolg des Tests NUR das zu testende Gerät widerspiegelt. Dies ist einer der Hauptgründe, warum Menschen das Konzept der Inversion of Control in komplexen Projekten verwenden.
Eisenretter
2
@ marcv81 Bereiche, in denen solche Portabilitätsprobleme bestehen, sind sehr wahrscheinlich schlechte Probanden für Unit-Tests. Denken Sie daran, dass Unit-Tests nur IHREN Code testen sollten. Begrenzen Sie daher deren Umfang entsprechend. Angesichts der großen Unterschiede in der Hardware, über die wir hier sprechen, kann ich akzeptieren, dass einige dieser Umstände unvermeidbar sind. In diesen Fällen sollte ein Ingenieur auf dem Laufenden bleiben und mildernde Maßnahmen ergreifen. Dies kann bedeuten, dass Sie Ihr Design ändern, um die Testbarkeit zu verbessern, oder sogar so einfach wie die Dokumentation der relevanten Fakten.
Iron Savior
2
@Iron Saviour Ein Unit-Test testet Ihren Code, aber Ihr Code läuft irgendwo. Wenn dieser Kontext ein Arduino-Kontext ist oder emuliert; dann hilft Ihnen ArdunoUnit beim Schreiben von Komponententests. Wenn Sie sich das ArduinoUnit-Projekt ansehen, werden beim Testen des Frameworks automatisch die Testergebnisse auf dem plattformübergreifenden Ziel geladen, ausgeführt und überprüft. Genau wie bei anderen plattformübergreifenden Zielen. Ihre Sichtweise ist eine Entschuldigung dafür, Code nicht in einer eingebetteten Umgebung zu testen, in der Korrektheit genauso wichtig ist, wenn nicht oft mehr als in anderen Kontexten.
Warren MacEvoy
21

Ich habe einen beachtlichen Erfolg beim Testen meines PIC-Codes, indem ich den Hardwarezugriff abstrahiere und ihn in meinen Tests verspotte.

Zum Beispiel abstrahiere ich PORTA mit

#define SetPortA(v) {PORTA = v;}

Dann kann SetPortA leicht verspottet werden, ohne Overhead-Code in der PIC-Version hinzuzufügen.

Nachdem die Hardware-Abstraktion eine Weile getestet wurde, stelle ich bald fest, dass der Code im Allgemeinen vom Prüfstand zum PIC wechselt und beim ersten Mal funktioniert.

Aktualisieren:

Ich verwende eine # Include-Naht für den Einheitencode, # einschließlich des Einheitencodes in einer C ++ - Datei für den Prüfstand und eine C-Datei für den Zielcode.

Als Beispiel möchte ich vier 7-Segment-Anzeigen multiplexen, wobei ein Port die Segmente steuert und ein zweiter die Anzeige auswählt. Der Anzeigecode ist über SetSegmentData(char)und mit den Anzeigen verbunden SetDisplay(char). Ich kann diese in meinem C ++ - Prüfstand verspotten und überprüfen, ob ich die erwarteten Daten erhalte. Für das Ziel verwende ich, #definedamit ich ohne den Aufwand eines Funktionsaufrufs eine direkte Zuordnung bekomme

#define SetSegmentData(x) {PORTA = x;}
David Sykes
quelle
Ich kann im Prinzip sehen, wie ich die Präprozessornaht für Unit-Tests verwenden kann. Ich bin mir jedoch nicht sicher, wie ich dies tun kann, ohne einen Emulator zu haben, auf dem die Tests ausgeführt werden können, oder einen avr-gcc-kompatiblen Compiler, der (in meinem Fall) Windows-Binärdateien ausgibt ...
Matthew Murdoch
Danke für das Update. Führen Sie die Unit-Tests auf dem PIC oder auf Ihrem PC durch?
Matthew Murdoch
Die Unit-Tests werden auf einem Mac mit Xcode ausgeführt. Um sie auf dem Bild auszuführen, wäre wahrscheinlich ein Emulator erforderlich. Wenn man es so abstrahiert, dass es auf dem Mac läuft, ist das Wechseln des Prozessors sehr einfach
David Sykes,
Die Arduino-Umgebung verwendet den avr-gcc-Compiler, der einige Besonderheiten aufweist, die bedeuten, dass das Kompilieren mit gcc (oder einem anderen C ++ - Compiler) und das Ausführen auf einem PC möglicherweise nicht bedeutet, dass der Code auch auf avr-gcc kompiliert wird.
Matthew Murdoch
Über was für einen Unterschied sprichst du? Sind es Dinge, die mit einigen Präprozessor-Direktiven nicht gehandhabt werden können?
Joseph Lisee
15

Es scheint, dass Emulino den Job perfekt machen würde.

Emulino ist ein Emulator für die Arduino-Plattform von Greg Hewgill. ( Quelle )

GitHub-Repository

Gonzo
quelle
12

simavr ist ein AVR- Simulator , der avr-gcc verwendet.

Es werden bereits einige ATTiny- und ATMega-Mikrocontroller unterstützt, und laut Autor ist es einfach, weitere hinzuzufügen.

In den Beispielen liegt Simduino, ein Arduino-Emulator. Es unterstützt das Ausführen des Arduino-Bootloaders und kann mit avrdude über Socat (einen modifizierten Netcat ) programmiert werden .

Gonzo
quelle
9

Sie können mit meinem Projekt PySimAVR einen Unit-Test in Python durchführen . Arscons wird zum Erstellen und simavr zum Simulieren verwendet.

Beispiel:

from pysimavr.sim import ArduinoSim    
def test_atmega88():
    mcu = 'atmega88'
    snippet = 'Serial.print("hello");'

    output = ArduinoSim(snippet=snippet, mcu=mcu, timespan=0.01).get_serial()
    assert output == 'hello'

Test starten:

$ nosetests pysimavr/examples/test_example.py
pysimavr.examples.test_example.test_atmega88 ... ok
Ponty
quelle
6

Mir ist keine Plattform bekannt, die Arduino-Code testen kann.

Es gibt jedoch die Fritzing- Plattform, mit der Sie die Hardware modellieren und später PCB-Diagramme und ähnliches exportieren können.

Eine Überprüfung wert.

Yuval Adam
quelle
6

In einem großen wissenschaftlichen Experiment verwenden wir Arduino-Boards zur Datenerfassung. Anschließend müssen wir mehrere Arduino-Boards mit unterschiedlichen Implementierungen unterstützen. Ich habe Python-Dienstprogramme geschrieben, um Arduino-Hex-Images während des Unit-Tests dynamisch zu laden. Der Code unter dem folgenden Link unterstützt Windows und Mac OS X über eine Konfigurationsdatei. Um herauszufinden, wo Ihre Hex-Bilder von der Arduino IDE platziert werden, drücken Sie die Umschalttaste, bevor Sie auf die Schaltfläche zum Erstellen (Abspielen) klicken. Drücken Sie die Umschalttaste, während Sie auf Hochladen klicken, um herauszufinden, wo sich Ihr avrdude (Befehlszeilen-Upload-Dienstprogramm) auf Ihrem System / Ihrer Version von Arduino befindet. Alternativ können Sie sich die enthaltenen Konfigurationsdateien ansehen und Ihren Installationsort verwenden (derzeit auf Arduino 0020).

http://github.com/toddstavish/Python-Arduino-Unit-Testing

toddstavish
quelle
+1 Tolles Zeug! Haben Sie Informationen darüber, wie Sie Ihre Unit-Tests durchgeführt haben, nachdem die Bilder hochgeladen wurden?
Matthew Murdoch
Wir haben Nosetests verwendet, um unsere Unit-Tests auf der Python-Seite durchzuführen. Das Setup für jeden Test lädt das richtige Hex-Bild für diesen Test. Wir fangen klein an und arbeiten dann an umfassenderen Tests. Stellen Sie sicher, dass die serielle Kommunikation funktioniert, stellen Sie sicher, dass die serielle Integration in die Benutzeroberfläche funktioniert, überprüfen Sie die serielle zu DB-Integration usw. Die analogen_read_speed-pde und py zeigen die Grundlagen hierfür (siehe Github-Link oben). Irgendwann werden wir das gesamte Projekt als Open Source veröffentlichen, also bleiben Sie bitte auf dem Laufenden. :)
toddstavish
6

Dieses Programm ermöglicht die automatische Ausführung mehrerer Arduino-Komponententests. Der Testprozess wird auf dem PC gestartet, die Tests werden jedoch auf der tatsächlichen Arduino-Hardware ausgeführt. Ein Satz von Komponententests wird normalerweise zum Testen einer Arduino-Bibliothek verwendet. (Dies

Arduino Forum: http://arduino.cc/forum/index.php?topic=140027.0

GitHub-Projektseite: http://jeroendoggen.github.com/Arduino-TestSuite

Seite im Python-Paketindex: http://pypi.python.org/pypi/arduino_testsuite

Die Unit-Tests werden mit der "Arduino Unit Testing Library" geschrieben: http://code.google.com/p/arduinounit

Die folgenden Schritte werden für jeden Satz von Komponententests ausgeführt:

  • Lesen Sie die Konfigurationsdatei, um herauszufinden, welche Tests ausgeführt werden sollen
  • Das Skript kompiliert und lädt eine Arduino-Skizze hoch, die den Unit-Test-Code enthält.
  • Die Unit-Tests werden auf dem Arduino-Board ausgeführt.
  • Die Testergebnisse werden über die serielle Schnittstelle gedruckt und vom Python-Skript analysiert.
  • Das Skript startet den nächsten Test und wiederholt die obigen Schritte für alle Tests, die in der Konfigurationsdatei angefordert werden.
  • Das Skript druckt eine Zusammenfassung mit einer Übersicht aller fehlgeschlagenen / bestandenen Tests in der vollständigen Testsuite.
jeroendoggen
quelle
5

Halten Sie hardwarespezifischen Code vom Rest getrennt oder abstrahiert, damit Sie diesen größeren "Rest" auf jeder Plattform testen und debuggen können, für die Sie gute Tools haben und mit der Sie am besten vertraut sind.

Versuchen Sie grundsätzlich, so viel endgültigen Code wie möglich aus so vielen bekannten Bausteinen wie möglich zu erstellen. Die verbleibende hardwarespezifische Arbeit wird dann viel einfacher und schneller. Sie können dies beenden, indem Sie vorhandene Emulatoren und / oder Emulationsgeräte selbst verwenden. Und dann müssen Sie natürlich die Realität irgendwie testen. Abhängig von den Umständen kann dies sehr gut automatisierbar sein oder auch nicht (dh wer oder was drückt Tasten und liefert andere Eingaben? Wer oder was beobachtet und interpretiert verschiedene Indikatoren und Ausgaben?).

Alexey Frunze
quelle
5

Ich benutze Searduino beim Schreiben von Arduino-Code. Searduino ist ein Arduino-Simulator und eine Entwicklungsumgebung (Makefiles, C-Code ...), mit der Sie C / C ++ ganz einfach mit Ihrem Lieblingseditor hacken können. Sie können Arduino-Skizzen importieren und im Simulator ausführen.

Screenshot von Searduino 0.8: http://searduino.files.wordpress.com/2014/01/jearduino-0-8.png

Searduino 0.9 wird veröffentlicht und ein Video wird aufgenommen, sobald die letzten Tests abgeschlossen sind ... in ein oder zwei Tagen.

Das Testen auf dem Simulator ist nicht als echter Test anzusehen, aber es hat mir sicherlich sehr geholfen, dumme / logische Fehler zu finden (das Vergessen zu tun) pinMode(xx, OUTPUT) usw.).

Übrigens: Ich bin einer der Leute, die Searduino entwickeln.

user3183814
quelle
5

Ich habe arduino_cifür diesen Zweck gebaut. Obwohl es auf das Testen von Arduino-Bibliotheken (und nicht auf eigenständige Skizzen) beschränkt ist, können Unit-Tests entweder lokal oder auf einem CI-System (wie Travis CI oder Appveyor) ausgeführt werden.

Betrachten wir eine sehr einfache Bibliothek in Ihrem Arduino Bibliothek Verzeichnis genannt DoSomething, mit do-something.cpp:

#include <Arduino.h>
#include "do-something.h"

int doSomething(void) {
  return 4;
};

Sie würden es wie folgt testen (mit einer Testdatei namens test/is_four.cppoder einer ähnlichen):

#include <ArduinoUnitTests.h>
#include "../do-something.h"

unittest(library_does_something)
{
  assertEqual(4, doSomething());
}

unittest_main()  // this is a macro for main().  just go with it.

Das ist alles. Wenn diese assertEqualSyntax und Teststruktur bekannt vorkommt, habe ich einige der ArduinoUnit-Bibliotheken von Matthew Murdoch übernommen , auf die er in seiner Antwort Bezug genommen hat .

Weitere Informationen zu E / A-Pins zum Testen von Einheiten, zur Uhr, zu seriellen Anschlüssen usw. finden Sie unter Reference.md .

Diese Komponententests werden mithilfe eines in einem Rubinstein enthaltenen Skripts kompiliert und ausgeführt. Beispiele für die Einrichtung finden Sie in der README.md oder kopieren Sie einfach eines dieser Beispiele:

Ian
quelle
Das sieht interessant aus, aber ich bin nicht sicher, ob es den Arduino-Code richtig testet. Aus der von Ihnen veröffentlichten Ausgabe wird eine x86_64-Architektur kompiliert, die für das Arduino offensichtlich nicht verwendet wird. Dies könnte zu Fehlern führen, die durch Konflikte zwischen Typimplementierungen verursacht werden.
Cerin
Diese Art von Fehler ist sicherlich möglich. Haben Sie ein Beispiel, das ich für einen Testfall verwenden könnte?
Ian
3

Es gibt ein Projekt namens ncore , das Arduino einen nativen Kern bietet. Und ermöglicht es Ihnen, Tests für Arduino-Code zu schreiben.

Aus der Projektbeschreibung

Mit dem nativen Kern können Sie Arduino-Skizzen auf dem PC kompilieren und ausführen, im Allgemeinen ohne Änderungen. Es bietet native Versionen der Standardfunktionen von Arduino und einen Befehlszeileninterpreter, mit dem Sie Eingaben für Ihre Skizze vornehmen können, die normalerweise von der Hardware selbst stammen.

Auch im Abschnitt "Was brauche ich, um es zu verwenden"

Wenn Sie die Tests erstellen möchten, benötigen Sie cxxtest von http://cxxtest.tigris.org . NCORE wurde mit cxxtest 3.10.1 getestet.

Sudar
quelle
Dies ist ein interessantes Projekt. Leider sieht es so aus, als wäre es jetzt tot, da es seit 6 Jahren keine Fortschritte mehr gemacht hat.
Cerin
2

Wenn Sie Code außerhalb der MCU (auf dem Desktop) testen möchten, lesen Sie libcheck: https://libcheck.github.io/check/

Ich habe es einige Male verwendet, um meinen eigenen eingebetteten Code zu testen. Es ist ein ziemlich robuster Rahmen.

ezaquarii
quelle
Der einzige Nachteil ist, dass dies kein g ++ unterstützt, was es für das Testen der meisten Arduino-Bibliotheken, die C ++ - Funktionen verwenden, unbrauchbar macht.
Cerin
1

Sie können emulare verwenden - Sie können einen Mikrocontroller per Drag & Drop in ein Diagramm ziehen und Ihren Code in Eclipse ausführen. In der Dokumentation auf der Website erfahren Sie, wie Sie sie einrichten.

Imre
quelle
1

Verwenden Sie Proteus VSM mit einer Arduino-Bibliothek, um Ihren Code zu debuggen oder zu testen.

Es ist eine bewährte Methode, bevor Sie Ihren Code an Bord bringen. Achten Sie jedoch auf das Timing, da die Simulation nicht in Echtzeit ausgeführt wird, da sie auf dem Board ausgeführt wird.

sathish
quelle
1

Probieren Sie den Autodesk-Schaltungssimulator aus . Es ermöglicht das Testen von Arduino-Code und -Schaltungen mit vielen anderen Hardwarekomponenten.

Sidhant Goyal
quelle
0

In Basic Arduino wird mit C und C ++ geschrieben, sogar Bibliotheken von Arduino werden in C und C ++ geschrieben. In einfachen Worten, behandeln Sie den Code einfach als C und C ++ und versuchen Sie, den Unit-Test durchzuführen. Mit dem Wort "handle" meine ich hier, dass Sie die gesamte grundlegende Syntax wie serial.println in sysout, pinmode in varaibles, void loop in while () - Schleife ändern, die entweder im Keystock oder nach einer gewissen Iteration unterbrochen wird.

Ich weiß, dass dies ein wenig langer und nicht so einfacher Prozess ist. Nach meiner persönlichen Erfahrung wird dies zuverlässiger, sobald Sie damit fertig sind.

-Nandha_Frost

Nandha Frost
quelle
0

Falls Sie daran interessiert sind, eine INO-Skizze auszuführen und die serielle Ausgabe zu überprüfen , habe ich eine funktionierende Implementierung davon in meinem Arduino NMEA-Prüfsummenprojekt .

Das folgende Skript nimmt die Datei und kompiliert sie mit Arduino CLI in eine HEX-Datei, die dann in SimAVR geladen wird, die sie auswertet und die serielle Ausgabe druckt. Da alle Arduino-Programme für immer ausgeführt werden, ohne wirklich die Möglichkeit zu haben, sich selbst zu töten ( exit(0)funktioniert nicht), lasse ich die Skizze einige Sekunden lang laufen und differenziere dann die erfasste Ausgabe mit der erwarteten Ausgabe.

Laden Sie die Arduino CLI herunter und extrahieren Sie sie (in diesem Fall Version 0.5.0 - spätestens zum Zeitpunkt des Schreibens):

curl -L https://github.com/arduino/arduino-cli/releases/download/0.5.0/arduino-cli_0.5.0_Linux_64bit.tar.gz -o arduino-cli.tar.gz
tar -xvzf arduino-cli.tar.gz

Jetzt können Sie den Index aktualisieren und den entsprechenden Kern installieren:

./arduino-cli core update-index
./arduino-cli core install arduino:avr

Angenommen, Ihre Skizze heißt nmea-checksum.ino, um ELF und HEX zu erhalten, führen Sie Folgendes aus:

./arduino-cli compile -b arduino:avr:uno nmea-checksum.ino

Als nächstes SimAVR, um HEX (oder ELF) auszuführen - Ich baue aus dem Quellcode, weil die neueste Version für mich nicht funktioniert hat:

sudo apt-get update
sudo apt-get install -y build-essential libelf-dev avr-libc gcc-avr freeglut3-dev libncurses5-dev pkg-config
git clone https://github.com/buserror/simavr.git
cd simavr
make

Nach erfolgreicher Kompilierung erhalten Sie simavr/run_avrdie Möglichkeit, die Skizze auszuführen. Wie ich schon sagte, timeoutsonst wird es nie enden:

cd simavr
timeout 10 ./run_avr -m atmega168 -f 16000000 ../../nmea-checksum.ino.arduino.avr.uno.elf &> nmea-checksum.ino.clog || true

Die generierte Datei enthält ANSI-Farbcode-Steuerzeichen, die die serielle Ausgabe umschließen, um Folgendes zu entfernen:

cat nmea-checksum.ino.clog | sed -r "s/\x1B\[([0-9]{1,2}(;[0-9]{1,2})?)?[mGK]//g" > nmea-checksum.ino.log
cat nmea-checksum.ino.log

Jetzt müssen Sie nur noch diese Datei mit einer bekanntermaßen guten Datei vergleichen:

diff nmea-checksum.ino.log ../../nmea-checksum.ino.test

Wenn es keine Unterschiede gibt, diffwird mit Code 0 beendet, andernfalls schlägt das Skript fehl.

Tomáš Hübelbauer
quelle