Jak mogę przetestować kod Arduino?

186

Chciałbym móc testować jednostkowo mój kod Arduino. Idealnie byłoby w stanie uruchomić dowolne testy bez konieczności przesyłania kodu do Arduino. Jakie narzędzia lub biblioteki mogą mi w tym pomóc?

Jest emulator Arduino w rozwoju , które mogą być przydatne, ale to jeszcze nie wydają się być gotowe do użycia.

AVR Studio firmy Atmel zawiera symulator układu, który może być przydatny, ale nie widzę, jak bym go używał w połączeniu z Arduino IDE.

Matthew Murdoch
źródło
Jest inny wątek na to pytanie z 2011 r. Na stronie arduino.cc/forum/index.php?action=printpage;topic=54356.0
Jakob
Dzięki @Jakob. Symulator Arduino, do którego odwołuje się ten wątek (z innymi potencjalnie przydatnymi linkami u dołu strony): arduino.com.au/Simulator-for-Arduino.html
Matthew Murdoch
5
Niestety jest to tylko dla systemu Windows, chciałbym znaleźć sposób, aby po prostu skompilować i uruchomić kod Arduino z wiersza poleceń bez żadnych zamkniętych zależności źródłowych lub sprzętowych.
Jakob
3
Trochę aktualizacji, 5 lat później: Simavr jest nadal bardzo aktywny i znacznie się poprawił, odkąd zadano pytanie, więc pomyślałem, że zasługuje na to, aby podskoczyć bliżej góry. Może to być właściwe narzędzie do testowania regresji, testowania opartego na scenariuszach, a może także testowanie jednostkowe. W ten sposób testowany kod jest taki sam, jak kod na sprzęcie docelowym.
zmo
W przypadku ważnych projektów rozważ tester sprzętu; inny MCU niż czas i testowanie reakcji przycisków / przełączników, czasu rozruchu, temperatury, użycia v / ma, dziwnych permutacji opcji itp. Tak, to więcej sprzętu do zbudowania, ale może dodać warstwę bezpieczeństwa przy tworzeniu poprawek. wiele profesjonalnych urządzeń używa jtag i in.
dandavis

Odpowiedzi:

136

Nie uruchamiaj testów jednostkowych na urządzeniu Arduino lub emulatorze

Sprawa przeciwko testom urządzeń / emulatorów / mikrokontrolerów

Dużo się dyskutuje na temat tego, co oznacza test jednostkowy, i tak naprawdę nie próbuję tutaj o tym argumentować. Ten post nie mówi ci, aby unikać wszelkich praktycznych testów na twoim ostatecznym sprzęcie docelowym. Próbuję zoptymalizować cykl opinii programistów, eliminując docelowy sprzęt z najbardziej przyziemnych i częstych testów. Zakłada się, że testowane urządzenia są znacznie mniejsze niż cały projekt.

Celem testów jednostkowych jest przetestowanie jakości własnego kodu. Testy jednostkowe na ogół nigdy nie powinny sprawdzać funkcjonalności czynników pozostających poza twoją kontrolą.

Pomyśl o tym w ten sposób: Nawet jeśli były do funkcjonalności testowej biblioteki Arduino, sprzętu mikrokontrolerem lub emulatorze, jest to absolutnie niemożliwe, aby takie wyniki testów powiedzieć nic na temat jakości swojej pracy. Dlatego o wiele bardziej wartościowe i wydajne jest pisanie testów jednostkowych, które nie działają na urządzeniu docelowym (lub emulatorze).

Częste testowanie na docelowym sprzęcie ma boleśnie powolny cykl:

  1. Popraw swój kod
  2. Skompiluj i prześlij na urządzenie Arduino
  3. Obserwuj zachowanie i zgadnij, czy Twój kod działa zgodnie z oczekiwaniami
  4. Powtarzać

Krok 3 jest szczególnie paskudny, jeśli spodziewasz się otrzymywać komunikaty diagnostyczne przez port szeregowy, ale sam projekt musi korzystać z jedynego sprzętowego portu szeregowego w Arduino. Jeśli myślisz, że biblioteka SoftwareSerial może pomóc, powinieneś wiedzieć, że może to zakłócić funkcjonalność wymagającą dokładnego pomiaru czasu, np. Generowanie innych sygnałów w tym samym czasie. Ten problem mi się przytrafił.

Ponownie, jeśli miałbyś przetestować swój szkic za pomocą emulatora, a Twoje krytyczne pod względem czasu procedury działały idealnie, dopóki nie załadowałeś do rzeczywistego Arduino, jedyną lekcją, której się nauczysz, jest to, że emulator jest wadliwy - i wiedząc o tym nadal nie zdradza nic na temat jakości własnej pracy.

Jeśli głupio jest testować na urządzeniu lub emulatorze, co powinienem zrobić?

Prawdopodobnie używasz komputera do pracy nad projektem Arduino. Ten komputer jest o rząd wielkości szybszy niż mikrokontroler. Napisz testy, aby zbudować i uruchomić na swoim komputerze .

Pamiętaj, że zachowanie biblioteki Arduino i mikrokontrolera powinno być poprawne lub przynajmniej konsekwentnie niepoprawne .

Gdy testy generują dane wyjściowe niezgodnie z oczekiwaniami, prawdopodobnie masz wadę w testowanym kodzie. Jeśli wyniki testu są zgodne z oczekiwaniami, ale program nie działa poprawnie po przesłaniu go do Arduino, to wiesz, że twoje testy były oparte na niepoprawnych założeniach i prawdopodobnie masz wadliwy test. W obu przypadkach uzyskasz prawdziwy wgląd w to, jakie powinny być Twoje kolejne zmiany w kodzie. Poprawiono jakość opinii z „ coś jest zepsute” do „ten konkretny kod jest zepsuty” .

Jak zbudować i uruchomić testy na komputerze

Pierwszą rzeczą, którą musisz zrobić, to określić swoje cele testowe . Zastanów się, które części własnego kodu chcesz przetestować, a następnie upewnij się, że skonstruowałeś swój program w taki sposób, abyś mógł wyizolować dyskretne części do testowania.

Jeśli części, które chcesz przetestować, wywołują dowolne funkcje Arduino, musisz podać zastępcze zamienniki w swoim programie testowym. To znacznie mniej pracy, niż się wydaje. Twoje makiety nie muszą właściwie nic robić, ale zapewniają przewidywalne dane wejściowe i wyjściowe dla twoich testów.

Każdy własny kod, który zamierzasz przetestować, musi istnieć w plikach źródłowych innych niż szkic .pde. Nie martw się, szkic nadal będzie się kompilował, nawet z pewnym kodem źródłowym poza szkicem. Kiedy naprawdę do tego dojdziesz, w pliku szkicu powinno być zdefiniowane niewiele więcej niż normalny punkt wejścia programu.

Pozostaje tylko napisać aktualne testy, a następnie skompilować je przy użyciu ulubionego kompilatora C ++! Prawdopodobnie najlepiej to ilustruje przykład z prawdziwego świata.

Rzeczywisty przykład działania

Jeden z moich znalezionych tutaj projektów dla zwierząt domowych zawiera kilka prostych testów, które można uruchomić na komputerze. Aby odpowiedzieć na to pytanie, omówię sposób, w jaki wyszydziłem niektóre funkcje biblioteki Arduino i testy, które napisałem, aby przetestować te makiety. Nie jest to sprzeczne z tym, co powiedziałem wcześniej o nie testowaniu kodu innych osób, ponieważ to ja napisałem makiety. Chciałem mieć pewność, że moje makiety były prawidłowe.

Źródło mock_arduino.cpp, które zawiera kod powielający niektóre funkcje obsługi zapewniane przez bibliotekę Arduino:

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

Korzystam z następującej makiety, aby uzyskać czytelny wynik, gdy mój kod zapisuje dane binarne na sprzętowym urządzeniu szeregowym.

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;

i wreszcie aktualny program testowy:

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

Ten post jest wystarczająco długi, więc zapoznaj się z moim projektem na GitHub, aby zobaczyć więcej przypadków testowych w akcji. Nadal pracuję w toku w gałęziach innych niż master, więc sprawdź te gałęzie również pod kątem dodatkowych testów.

Zdecydowałem się napisać własne lekkie procedury testowe, ale dostępne są również bardziej niezawodne frameworki testów jednostkowych, takie jak CppUnit.

Żelazny Zbawiciel
źródło
1
To świetna odpowiedź! Dziękuję Ci!
Jonathan Arkell
5
@WarrenMacEvoy Znowu myślę, że posłuchałeś mojej rady i zmieniłeś ją w coś, czym nie jest. Z pewnością powinieneś przetestować swój kod w jego rzeczywistym środowisku W NIEKTÓRYM PUNKCIE. Moim argumentem jest to, że nie powinieneś tego robić codziennie i na pewno nie powinieneś nazywać go testem jednostkowym.
Żelazny Zbawiciel
1
@toasted_flakes Nie jestem pewien, skąd masz ten cytat, ale nie powiedziałem tego. Testy jednostkowe uruchomione na urządzeniu mają wiele problemów - bardzo wolna pętla sprzężenia zwrotnego, możesz nie mieć żadnych portów szeregowych lub innych środków IO do oszczędzenia na urządzeniu docelowym, a ich pojemność jest bardzo ograniczona, co może mieć wpływ na zakres twój zestaw testowy.
Żelazny Zbawiciel,
1
@ChristianHujer Z pewnością powinieneś przetestować na prawdziwym sprzęcie - nikt nie mówi, że nigdy nie powinieneś testować na sprzęcie docelowym. Mój post dotyczy ścisłego zaostrzania codziennego cyklu rozwojowego przez testowanie jednostkowe na maszynie programistycznej. Dzięki temu narzut związany z testowaniem jest minimalizowany, ponieważ będziesz testować na docelowym sprzęcie tylko wtedy, gdy będzie to konieczne.
Żelazny Zbawiciel
1
@Benjohn Arduino pliki źródłowe szkicu miały kiedyś rozszerzenie „pde”, mimo że są to C ++. arduino.cc/en/Guide/Environment#toc1
Iron Saviour
63

Wobec braku wcześniejszych ram testowania jednostek dla Arduino, stworzyłem ArduinoUnit . Oto prosty szkic Arduino demonstrujący jego użycie:

#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
źródło
18
Testy wydają się działać tylko na arduino, więc nie można wykonać ich automatycznie na komputerze programistycznym. Podstawową ideą testów jednostkowych jest ich automatyczne uruchamianie, więc obecny projekt wydaje się być bardziej narzędziem do debugowania, ale nie ma rzeczywistych ram testów jednostkowych.
Jakob
1
Masz rację. Aby móc je uruchomić na komputerze, wymagałby emulatora Arduino lub AVR. W bibliotekach Arduino (w tej chwili) nie ma żadnej warstwy abstrakcji sprzętu, a emulatory AVR, gdy patrzyłem, były wciąż w fazie rozwoju. Jeśli sprawy potoczyły się teraz, w zasadzie można to zrobić.
Matthew Murdoch
12
@MatthewMurdoch Obawiam się, że się mylisz. Z definicji testy jednostkowe nigdy nie są uruchamiane w środowisku docelowym. W rzeczywistości samą ideą testów jednostkowych jest całkowite wyeliminowanie testowanego środowiska docelowego. Zawsze są uruchamiane w środowisku laboratoryjnym, które kpi z całej aktywności zewnętrznej w stosunku do testowanego urządzenia, aby zapewnić, że sukces lub porażka testu będą widoczne TYLKO w testowanym urządzeniu. To jeden z głównych powodów, dla których ludzie używają koncepcji Inwersji Kontroli w złożonych projektach.
Żelazny Zbawiciel
2
@ marcv81 Obszary, w których występują takie problemy z przenośnością, prawdopodobnie są słabymi podmiotami do testów jednostkowych. Pamiętaj, że testy jednostkowe powinny testować tylko TWÓJ kod, więc odpowiednio ogranicz ich zakres. Przy ogromnej rozbieżności w sprzęcie, o którym tu mówimy, mogę zaakceptować, że niektórych takich okoliczności może być nieuniknionych. W takich przypadkach inżynier powinien pozostać świadomy i podjąć kroki łagodzące. Może to oznaczać zmianę projektu w celu poprawy testowalności lub nawet czegoś tak prostego, jak udokumentowanie odpowiednich faktów.
Żelazny Zbawiciel
2
@ Iron Saviour test jednostkowy testuje twój kod, ale twój kod gdzieś działa. Jeśli ten kontekst jest lub emuluje kontekst Arduino; wtedy ArdunoUnit pomoże Ci napisać testy jednostkowe. Jeśli spojrzysz na projekt ArduinoUnit, meta-testowanie frameworka automatycznie ładuje się, uruchamia i weryfikuje wyniki testu na celu międzyplatformowym. Podobnie jak w przypadku innych celów międzyplatformowych. Twój punkt widzenia jest usprawiedliwieniem dla nie testowania kodu w środowisku osadzonym, w którym poprawność ma takie samo znaczenie, jeśli nie częściej niż inne konteksty.
Warren MacEvoy
21

Mam duży sukces w testowaniu mojego kodu PIC poprzez wyciąganie dostępu do sprzętu i wyśmiewanie go w moich testach.

Na przykład streszczenie PORTA

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

Następnie SetPortA można łatwo wyśmiewać, bez dodawania kodu nadmiarowego w wersji PIC.

Po przetestowaniu abstrakcji sprzętu wkrótce okazuje się, że ogólnie kod przechodzi z zestawu testowego do PIC i działa po raz pierwszy.

Aktualizacja:

Używam szwy #include dla kodu jednostki, # włączając kod jednostki w pliku C ++ dla zestawu testowego i pliku C dla kodu docelowego.

Jako przykład chcę zmultipleksować cztery wyświetlacze 7-segmentowe, jeden port sterujący segmentami, a drugi wybór wyświetlacza. Kod wyświetlacza łączy się z wyświetlaczami za pomocą SetSegmentData(char)i SetDisplay(char). Mogę kpić z nich na moim testowym C ++ i sprawdzać, czy otrzymuję oczekiwane dane. Dla celu używam, #defineaby uzyskać bezpośrednie przypisanie bez narzutu wywołania funkcji

#define SetSegmentData(x) {PORTA = x;}
David Sykes
źródło
Widzę w zasadzie, jak mogę wykorzystać „szew” preprocesora do testowania jednostek. Jednak nie jestem pewien, jak mogę to zrobić bez emulatora, na którym można uruchomić testy, lub kompilatora kompatybilnego z avr-gcc, który wyprowadza (w moim przypadku) pliki binarne Windows ...
Matthew Murdoch,
Dziękuję za aktualizację. Czy przeprowadzasz testy jednostkowe na PIC lub na komputerze?
Matthew Murdoch
Testy jednostkowe są uruchamiane na komputerze Mac przy użyciu Xcode. Aby uruchomić je na Pic, prawdopodobnie potrzebowałby jakiegoś emulatora. Wyodrębnienie go tak, aby działało na komputerze Mac, znacznie ułatwia przełączanie procesorów
David Sykes
Środowisko Arduino korzysta z kompilatora avr-gcc, który ma pewne osobliwości, co oznacza, że ​​kompilacja z gcc (lub innym kompilatorem C ++) i uruchomienie na komputerze PC może nie oznaczać, że kod będzie również kompilował się na avr-gcc.
Matthew Murdoch,
O jakiej różnicy mówisz? Czy są to rzeczy, których nie da się rozwiązać za pomocą niektórych dyrektyw preprocesora?
Joseph Lisee
12

simavr to symulator AVR korzystający z avr-gcc.

Obsługuje już kilka mikrokontrolerów ATTiny i ATMega, i - zdaniem autora - łatwo dodać więcej.

W przykładach leży simduino, emulator Arduino. Obsługuje uruchamianie programu ładującego Arduino i może być programowany za pomocą avrdude poprzez Socat (zmodyfikowany Netcat ).

Gonzo
źródło
9

Możesz przeprowadzić test jednostkowy w Pythonie z moim projektem PySimAVR . Arscons służy do budowania i simavr do symulacji.

Przykład:

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'

Rozpocznij test:

$ nosetests pysimavr/examples/test_example.py
pysimavr.examples.test_example.test_atmega88 ... ok
ponty
źródło
6

Nie znam żadnej platformy, która może testować kod Arduino.

Istnieje jednak platforma Fritzing , za pomocą której można modelować sprzęt, a później eksportować diagramy PCB i takie tam.

Warto sprawdzić.

Yuval Adam
źródło
6

Używamy tablic Arduino do akwizycji danych w dużym eksperymencie naukowym. Następnie musimy wesprzeć kilka płyt Arduino za pomocą różnych implementacji. Napisałem narzędzia Python do dynamicznego ładowania obrazów heksadecymalnych Arduino podczas testów jednostkowych. Kod znajdujący się w poniższym linku obsługuje systemy Windows i Mac OS X za pośrednictwem pliku konfiguracyjnego. Aby dowiedzieć się, gdzie Arduino IDE umieszcza twoje obrazy heksadecymalne, naciśnij klawisz Shift przed naciśnięciem przycisku kompilacji (odtwarzania). Naciśnij klawisz Shift podczas uruchamiania przesyłania, aby dowiedzieć się, gdzie znajduje się twoje avrdude (narzędzie do przesyłania z wiersza poleceń) w twoim systemie / wersji Arduino. Ewentualnie możesz przejrzeć dołączone pliki konfiguracyjne i użyć lokalizacji instalacji (obecnie w Arduino 0020).

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

Toddstavish
źródło
+1 Świetne rzeczy! Czy masz jakieś informacje o tym, jak przeprowadziłeś testy jednostki po przesłaniu zdjęć?
Matthew Murdoch,
Użyliśmy testów nosa, aby przeprowadzić nasze testy jednostkowe po stronie pytona. Ustawienia dla każdego testu ładują poprawny obraz szesnastkowy dla tego testu. Zaczynamy od małych, a następnie pracujemy nad bardziej kompleksowymi testami. Upewnij się, że komunikacja szeregowa działa, upewnij się, że integracja szeregowa z interfejsem użytkownika działa, sprawdź integrację szeregową z DB, itp. Analog_read_speed pde i py pokazują podstawy tego (patrz link github powyżej). W końcu otworzymy źródło całego projektu, więc bądźcie czujni. :)
toddstavish
6

Ten program umożliwia automatyczne uruchamianie kilku testów jednostkowych Arduino. Proces testowania jest uruchamiany na komputerze PC, ale testy są przeprowadzane na rzeczywistym sprzęcie Arduino. Jeden zestaw testów jednostkowych jest zwykle używany do testowania jednej biblioteki Arduino. (to

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

Strona projektu GitHub: http://jeroendoggen.github.com/Arduino-TestSuite

Strona w indeksie pakietów Python: http://pypi.python.org/pypi/arduino_testsuite

Testy jednostkowe są napisane w „Arduino Unit Testing Library”: http://code.google.com/p/arduinounit

Dla każdego zestawu testów jednostkowych wykonywane są następujące kroki:

  • Przeczytaj plik konfiguracyjny, aby dowiedzieć się, które testy uruchomić
  • Skrypt kompiluje i przesyła szkic Arduino, który zawiera kod testu jednostkowego.
  • Testy jednostkowe są przeprowadzane na płycie Arduino.
  • Wyniki testu są drukowane przez port szeregowy i analizowane przez skrypt Pythona.
  • Skrypt rozpoczyna następny test, powtarzając powyższe kroki dla wszystkich testów wymaganych w pliku konfiguracyjnym.
  • Skrypt drukuje podsumowanie pokazujące przegląd wszystkich nieudanych / zdanych testów w kompletnym testsuite.
jeroendoggen
źródło
5

Trzymaj kod specyficzny dla sprzętu oddzielnie lub abstrakcyjnie, abyś mógł przetestować i debugować ten większy „odpoczynek” na dowolnej platformie, dla której masz dobre narzędzia i którą znasz najlepiej.

Zasadniczo spróbuj zbudować jak najwięcej końcowego kodu z jak największej liczby znanych bloków konstrukcyjnych. Pozostała praca związana ze sprzętem będzie wtedy znacznie łatwiejsza i szybsza. Możesz go zakończyć, korzystając z istniejących emulatorów i / lub urządzeń emulujących. A potem oczywiście trzeba jakoś przetestować prawdziwą rzecz. W zależności od okoliczności może to być bardzo mało zautomatyzowane (tj. Kto lub co naciska przyciski i zapewnia inne dane wejściowe? Kto lub co będzie obserwował i interpretował różne wskaźniki i wyniki?).

Alexey Frunze
źródło
5

Używam Searduino podczas pisania kodu Arduino. Searduino to symulator Arduino i środowisko programistyczne (Makefiles, kod C ...), które ułatwia hakowanie w C / C ++ przy użyciu ulubionego edytora. Możesz importować szkice Arduino i uruchamiać je w symulatorze.

Zrzut ekranu z Searduino 0.8: http://searduino.files.wordpress.com/2014/01/jearduino-0-8.png

Searduino 0.9 zostanie wydane, a wideo zostanie nagrane, gdy tylko ostatnie testy zostaną wykonane .... za dzień lub dwa.

Testowania na symulatorze nie należy uważać za prawdziwe testy, ale z pewnością bardzo pomogło mi to w znalezieniu głupich / logicznych błędów (zapomnienie o zrobieniu pinMode(xx, OUTPUT) itp.).

BTW: Jestem jedną z osób rozwijających Searduino.

użytkownik3183814
źródło
5

Zbudowałem arduino_ciw tym celu. Chociaż ogranicza się do testowania bibliotek Arduino (a nie samodzielnych szkiców), umożliwia uruchamianie testów jednostkowych lokalnie lub w systemie CI (np. Travis CI lub Appveyor).

Rozważmy bardzo prostą bibliotekę w katalogu biblioteki Arduino, zwany DoSomethingz do-something.cpp:

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

int doSomething(void) {
  return 4;
};

Testowałbyś go w następujący sposób (z wywołanym plikiem testowym test/is_four.cpplub innym takim):

#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.

To wszystko. Jeśli ta assertEqualskładnia i struktura testu wygląda znajomo, to dlatego, że zaadaptowałem część biblioteki ArduinoUnit Matthew Murdocha , o której wspominał w swojej odpowiedzi .

Zobacz Reference.md, aby uzyskać więcej informacji na temat testowania jednostek we / wy, zegara, portów szeregowych itp.

Te testy jednostkowe są kompilowane i uruchamiane przy użyciu skryptu zawartego w rubinie. Aby zapoznać się z przykładami konfiguracji, zobacz plik README.md lub po prostu skopiuj z jednego z tych przykładów:

Ian
źródło
Wygląda to interesująco, ale nie jestem pewien, czy poprawnie testuje kod Arduino. Z opublikowanych danych wyjściowych kompiluje się w architekturze x86_64, która oczywiście nie jest używana w Arduino. To mogłoby wprowadzić błędy spowodowane konfliktami między implementacjami typów.
Cerin,
Tego rodzaju błąd jest z pewnością możliwy. Czy masz przykład, którego mógłbym użyć dla przypadku testowego?
Ian
3

Istnieje projekt o nazwie ncore , który zapewnia natywny rdzeń dla Arduino. I pozwala pisać testy dla kodu Arduino.

Z opisu projektu

Natywny rdzeń pozwala kompilować i uruchamiać szkice Arduino na komputerze, zasadniczo bez modyfikacji. Zapewnia natywne wersje standardowych funkcji Arduino oraz interpreter wiersza poleceń do wprowadzania danych do szkicu, które normalnie pochodziłyby z samego sprzętu.

Również w sekcji „Czego muszę używać”

Jeśli chcesz zbudować testy, potrzebujesz cxxtest z http://cxxtest.tigris.org . NCORE został przetestowany przy pomocy cxxtest 3.10.1.

Sudar
źródło
To ciekawy projekt. Niestety wygląda na to, że jest już martwy, ponieważ nie miał postępu przez 6 lat.
Cerin,
2

Jeśli chcesz przetestować kod jednostki poza MCU (na komputerze), sprawdź libcheck: https://libcheck.github.io/check/

Użyłem go kilka razy do przetestowania własnego kodu osadzonego. To dość solidne środowisko.

ezaquarii
źródło
Jedynym minusem jest to, że nie obsługuje g ++, co czyni go bezużytecznym do testowania większości bibliotek Arduino, które używają funkcji C ++.
Cerin,
1

Możesz użyć emulare - możesz przeciągnąć i upuścić mikrokontroler na diagramie i uruchomić swój kod w Eclipse. Dokumentacja na stronie internetowej informuje, jak ją skonfigurować.

Imre
źródło
1

Użyj Proteus VSM z biblioteką Arduino do debugowania kodu lub przetestowania go.

Jest to najlepsza praktyka przed wprowadzeniem kodu na pokład, ale pamiętaj o taktowaniu, ponieważ symulacja nie działa w czasie rzeczywistym, ponieważ działa na płycie.

satycki
źródło
1

Wypróbuj symulator obwodu Autodesk . Umożliwia testowanie kodu i obwodów Arduino z wieloma innymi komponentami sprzętowymi.

Sidhant Goyal
źródło
0

W podstawowym Arduino jest napisane w C i C ++, nawet biblioteki arduino są napisane w C i C ++. Tak więc w prostych słowach po prostu obsługuj kod jako C i C ++ i spróbuj przeprowadzić test jednostkowy. Tutaj przez słowo „uchwyt” mam na myśli zmianę wszystkich podstawowych składni, takich jak serial.println na sysout, pinmode na zmienne, void loop na while (), która psuje się po naciśnięciu klawisza lub po pewnej iteracji.

Wiem, że jest to trochę długi i nie tak prosty proces. Z mojego osobistego doświadczenia wynika, że ​​kiedy już sobie z tym poradzisz, okazuje się, że jest bardziej niezawodny.

-Nandha_Frost

Nandha Frost
źródło
0

Jeśli jesteś zainteresowany uruchomieniem szkicu INO i sprawdzeniem wyjścia szeregowego, mam działającą implementację tego w mojej sumie kontrolnej Arduino NMEA projekcie .

Poniższy skrypt pobiera plik i używa Arduino CLI do skompilowania go do pliku HEX, który jest następnie ładowany do SimAVR, który ocenia go i drukuje wyjście szeregowe. Ponieważ wszystkie programy Arduino działają wiecznie bez możliwości samobójstwa ( exit(0)nie działa), pozwalam na szkicowanie przez kilka sekund, a następnie różnicuję przechwycone wyjście z oczekiwanym wyjściem.

Pobierz i rozpakuj Arduino CLI (w tym przypadku wersja 0.5.0 - najpóźniej w momencie pisania):

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

Teraz możesz zaktualizować indeks i zainstalować odpowiedni rdzeń:

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

Zakładając, że twój szkic ma nazwę nmea-checksum.ino, aby uzyskać ELF i HEX, uruchom:

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

Następnie SimAVR do uruchomienia HEX (lub ELF) - buduję ze źródła, ponieważ najnowsze wydanie nie działało dla mnie:

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

Pomyślna kompilacja da ci simavr/run_avrmożliwość uruchomienia szkicu. Jak powiedziałem, timeoutinaczej nigdy się nie skończy:

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

Wygenerowany plik będzie zawierał znaki sterujące kodem koloru ANSI zawijające wyjście szeregowe, aby pozbyć się tych:

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

Teraz wszystko, co musisz zrobić, to porównać ten plik ze znanym dobrym plikiem:

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

Jeśli nie ma różnic, diffwyjdzie z kodem 0, w przeciwnym razie skrypt się nie powiedzie.

Tomáš Hübelbauer
źródło