Вопрос

Я хотел бы иметь возможность модульного тестирования моего кода Arduino.В идеале я мог бы запускать любые тесты без необходимости загружать код в Arduino.Какие инструменты или библиотеки могут помочь мне в этом?

Существует Эмулятор Arduino в разработке который мог бы быть полезен, но, похоже, он еще не готов к использованию.

Студия AVR от Atmel содержит симулятор чипа, который мог бы быть полезен, но я не вижу, как бы я мог использовать его в сочетании с Arduino IDE.

Это было полезно?

Решение 2

В отсутствие каких-либо ранее существовавших фреймворков модульного тестирования для Arduino я создал ArduinoUnit.Вот простой эскиз Arduino, демонстрирующий его использование:

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

Другие советы

Не запускайте модульные тесты на устройстве или эмуляторе Arduino

Аргументы в пользу тестов на основе микроконтроллерного устройства / эмулятора / Sim-карты

Идет много дискуссий о том, что модульный тест означает, и я не собираюсь на самом деле пытаюсь привести аргумент по этому поводу здесь.Этот пост является не советую вам избегать ВСЕ практическое тестирование на вашей конечной цели оборудование.Я пытаюсь подчеркнуть необходимость оптимизации вашего цикла обратной связи при разработке путем исключения целевого оборудования из ваших самых рутинных и частых тестов.Предполагается, что тестируемые модули будут намного меньше, чем весь проект.

Цель модульного тестирования - проверить качество вашего собственного кода.Модульные тесты, как правило, никогда не должны проверять функциональность факторов, находящихся вне вашего контроля.

Подумайте об этом с такой точки зрения:Даже если бы вы тестировали функциональность библиотеки Arduino, аппаратного обеспечения микроконтроллера или эмулятора, это абсолютно невозможно чтобы такие результаты теста могли что-либо сказать вам о качестве вашей собственной работы.Следовательно, гораздо ценнее и эффективнее писать модульные тесты, которые не выполняются на целевом устройстве (или эмуляторе).

Частое тестирование на вашем целевом оборудовании имеет болезненно медленный цикл:

  1. Измените свой код
  2. Скомпилируйте и загрузите на устройство Arduino
  3. Понаблюдайте за поведением и угадайте, стоит ли ваш код делает то, что вы ожидаете
  4. Повторять

Шаг 3 особенно неприятен, если вы ожидаете получать диагностические сообщения через последовательный порт, но сам ваш проект должен использовать единственный аппаратный последовательный порт вашего Arduino.Если вы думали, что библиотека SoftwareSerial могла бы помочь, вы должны знать, что это, скорее всего, приведет к нарушению любой функциональности, требующей точного выбора времени, например, одновременной генерации других сигналов.Эта проблема случилась со мной.

Опять же, если вы тестировали свой эскиз с помощью эмулятора, и ваши критичные по времени процедуры выполнялись идеально до тех пор, пока вы не загрузили его в реальный Arduino, то единственный урок, который вы должны усвоить, заключается в том, что эмулятор несовершенен - и знание этого все еще показывает ничего о качестве твой собственный работать.

Если глупо тестировать на устройстве или эмуляторе, что следует Я делаю?

Вероятно, вы используете компьютер для работы над своим проектом Arduino.Этот компьютер на порядки быстрее, чем микроконтроллер.Напишите тесты для сборки и запустите на вашем компьютере.

Помните, что поведение библиотеки Arduino и микроконтроллера должно быть предполагается, что это либо правильно, либо, по крайней мере последовательно неверный.

Когда ваши тесты выдают результат, противоречащий вашим ожиданиям, то, скорее всего, у вас есть недостаток в вашем коде, который был протестирован.Если результаты вашего теста соответствуют вашим ожиданиям, но программа ведет себя некорректно, когда вы загружаете ее в Arduino, тогда вы знаете, что ваши тесты были основаны на неверных предположениях, и у вас, вероятно, некорректный тест.В любом случае, вы получите реальное представление о том, какими должны быть ваши следующие изменения в коде.Качество вашей обратной связи улучшается с "что - то разбит" на "это конкретный код сломан".

Как создавать и запускать тесты на Вашем КОМПЬЮТЕРЕ

Первое, что вам нужно сделать, это определите свои цели тестирования.Подумайте о том, какие части ваш собственный код вы хотите протестировать, а затем убедиться, что ваша программа сконструирована таким образом, чтобы вы могли изолировать дискретные части для тестирования.

Если детали, которые вы хотите протестировать, вызывают какие-либо функции Arduino, вам нужно будет предоставить макетные замены в вашей тестовой программе.Это гораздо меньше работы, чем кажется.Ваши макеты на самом деле не должны делать ничего, кроме предоставления предсказуемых входных и выходных данных для ваших тестов.

Любой ваш собственный код, который вы собираетесь тестировать, должен существовать в исходных файлах, отличных от .pde sketch.Не волнуйтесь, ваш эскиз все равно будет скомпилирован даже с некоторым исходным кодом за пределами эскиза.Когда вы действительно приступите к делу, в файле sketch должно быть определено немного больше, чем обычная точка входа вашей программы.

Все, что остается, это написать сами тесты, а затем скомпилировать их с помощью вашего любимого компилятора C ++!Вероятно, лучше всего это проиллюстрировать на примере реального мира.

Реальный рабочий пример

Один из моих любимых проектов найден здесь имеет несколько простых тестов, которые запускаются на ПК.Для отправки этого ответа я просто расскажу о том, как я смоделировал некоторые функции библиотеки Arduino и тесты, которые я написал для тестирования этих макетов.Это не противоречит тому, что я говорил ранее о том, чтобы не тестировать код других людей, потому что я был тем, кто написал макеты.Я хотел быть абсолютно уверен, что мои макеты были правильными.

Источник mock_arduino.cpp, который содержит код, дублирующий некоторые функции поддержки, предоставляемые библиотекой 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);
}

Я использую следующий макет для получения удобочитаемых выходных данных, когда мой код записывает двоичные данные на аппаратное последовательное устройство.

поддельный_сериал.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;

и, наконец, сама тестовая программа:

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

Этот пост достаточно длинный, поэтому, пожалуйста, обратитесь к мой проект на GitHub чтобы увидеть еще несколько тестовых примеров в действии.Я храню свои незавершенные работы в ветвях, отличных от master, поэтому проверьте эти ветви на наличие дополнительных тестов.

Я решил написать свои собственные облегченные тестовые процедуры, но также доступны более надежные фреймворки модульного тестирования, такие как CppUnit.

Я добился значительного успеха в модульном тестировании своего кода PIC, абстрагируясь от аппаратного доступа и высмеивая его в своих тестах.

Например, я абстрагирую PORTA с помощью

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

Тогда SetPortA можно легко подделать, не добавляя служебный код в версию PIC.

Как только аппаратная абстракция была протестирована некоторое время, я вскоре обнаружил, что обычно код переходит с тестовой установки на PIC и работает с первого раза.

Обновить:

Я использую #include seam для кода модуля, #включая код модуля в файл C ++ для тестовой установки и файл C для целевого кода.

В качестве примера я хочу мультиплексировать четыре 7-сегментных дисплея, один порт управляет сегментами, а второй выбирает дисплей.Код дисплея взаимодействует с дисплеями через SetSegmentData(char) и SetDisplay(char).Я могу смоделировать их в своей тестовой установке C ++ и проверить, что я получаю ожидаемые данные.Для цели, которую я использую #define так что я получаю прямое назначение без накладных расходов на вызов функции

#define SetSegmentData(x) {PORTA = x;}

Кажется , что эмульино справился бы с этой работой идеально.

Emulino - это эмулятор для платформы Arduino от Грега Хьюджилла.(Источник)

Репозиторий GitHub

симавр является AVR тренажёр используя avr-gcc.

Он уже поддерживает несколько микроконтроллеров ATtiny и ATmega, и, по словам автора, легко добавить еще несколько.

В примерах используется simduino, эмулятор Arduino.Он поддерживает запуск загрузчика Arduino и может быть запрограммирован с помощью avrdude через Socat ( Сокат ) (измененный Netcat ( Сетевой Кот )).

Вы можете выполнить модульное тестирование на Python с помощью моего проекта, ПиСимАВР. Поджоги используется для строительства и симавр для симуляции.

Пример:

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'

Начать тест:

$ nosetests pysimavr/examples/test_example.py
pysimavr.examples.test_example.test_atmega88 ... ok

Я не знаю ни одной платформы, которая могла бы протестировать код Arduino.

Тем не менее, существует Фритцинг платформа, которую вы можете использовать для моделирования оборудования, а затем для экспорта схем печатных плат и прочего.

Стоит проверить.

Мы используем платы Arduino для сбора данных в крупном научном эксперименте.Впоследствии нам приходится поддерживать несколько плат Arduino с различными реализациями.Я написал утилиты Python для динамической загрузки шестнадцатеричных изображений Arduino во время модульного тестирования.Код, найденный по ссылке ниже, поддерживает Windows и Mac OS X через файл конфигурации.Чтобы узнать, куда ваши шестнадцатеричные изображения помещаются Arduino IDE, нажмите клавишу shift, прежде чем нажимать кнопку сборки (воспроизведения).Нажмите клавишу shift при нажатии кнопки загрузить, чтобы узнать, где находится ваша avrdude (утилита загрузки из командной строки) в вашей системе / версии Arduino.В качестве альтернативы вы можете просмотреть прилагаемые файлы конфигурации и использовать свое местоположение установки (в настоящее время на Arduino 0020).

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

Эта программа позволяет автоматически запускать несколько модульных тестов Arduino.Процесс тестирования запускается на ПК, но тесты выполняются на самом оборудовании Arduino.Один набор модульных тестов обычно используется для тестирования одной библиотеки Arduino.(это

Форум Arduino: http://arduino.cc/forum/index.php?topic=140027.0

Страница проекта на GitHub: http://jeroendoggen.github.com/Arduino-TestSuite

Страница в индексе пакета Python: http://pypi.python.org/pypi/arduino_testsuite

Модульные тесты написаны с помощью "Библиотеки модульного тестирования Arduino".: http://code.google.com/p/arduinounit

Следующие шаги выполняются для каждого набора модульных тестов:

  • Прочитайте конфигурационный файл, чтобы узнать, какие тесты запускать
  • Скрипт компилирует и загружает эскиз Arduino, который содержит код модульного тестирования.
  • Модульные тесты выполняются на плате Arduino.
  • Результаты теста распечатываются через последовательный порт и анализируются скриптом Python.
  • Скрипт запускает следующий тест, повторяя описанные выше шаги для всех тестов, которые запрошены в файле конфигурации.
  • Скрипт выводит сводку, содержащую обзор всех неудачных / пройденных тестов в полном testsuite.

Держите аппаратно-специфичный код отдельно или абстрагированным от остального, чтобы вы могли тестировать и отлаживать этот более крупный "rest" на любой платформе, для которой у вас есть хорошие инструменты и с которой вы знакомы больше всего.

В принципе, постарайтесь собрать как можно больше конечного кода из как можно большего числа известных к работе строительных блоков.Тогда остальная работа, связанная с конкретным оборудованием, будет намного проще и быстрее.Вы можете завершить его, используя существующие эмуляторы и / или эмулирующие устройства самостоятельно.И тогда, конечно, вам нужно будет как-то протестировать реальную вещь.В зависимости от обстоятельств, это может быть или не быть очень хорошо автоматизируемым (т.е.кто или что будет нажимать кнопки и предоставлять другие входные данные?кто или что будет наблюдать и интерпретировать различные показатели и результаты?).

Джеймс У.Греннинг пишет замечательные книги, и эта посвящена модульному тестированию встроенного C-кода Разработка на основе тестирования для встроенного C.

Я использую Сирдуино при написании кода Arduino.Searduino - это симулятор Arduino и среда разработки (Makefiles, C-код ...), которая упрощает взлом на C / C ++ с помощью вашего любимого редактора.Вы можете импортировать эскизы Arduino и запускать их в симуляторе.

Скриншот Searduino 0.8: http://searduino .files.wordpress.com/2014/01/jearduino-0-8.png

Searduino 0.9 будет выпущен , и видео будет записано , как только будут завершены последние тесты ....через день или два.

Тестирование на симуляторе не следует рассматривать как настоящие тесты, но оно, безусловно, очень помогло мне в поиске глупых / логических ошибок (забыв сделать pinMode(xx, OUTPUT), и т.д.).

КСТАТИ:Я один из тех, кто разрабатывает Searduino.

Я построил arduino_ci для этой цели.Хотя он ограничен тестированием библиотек Arduino (а не автономных эскизов), он позволяет запускать модульные тесты либо локально, либо в системе CI (например, Travis CI или Appveyor).

Рассмотрим очень простую библиотеку в вашем каталоге библиотеки Arduino, называемую DoSomething, с do-something.cpp:

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

int doSomething(void) {
  return 4;
};

Вы бы провели модульное тестирование следующим образом (с помощью тестового файла под названием test/is_four.cpp или что-то подобное):

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

Вот и все.Если это assertEqual синтаксис и структура теста выглядят знакомо, это потому, что я перенял некоторые из Библиотека ArduinoUnit Мэтью Мердока , на который он ссылался в его ответ.

Видишь Reference.md для получения дополнительной информации о выводах ввода-вывода для модульного тестирования, часах, последовательных портах и т.д.

Эти модульные тесты компилируются и запускаются с использованием скрипта, содержащегося в ruby gem.Примеры того, как это настроить, см. В README.md или просто скопируйте из одного из этих примеров:

Есть проект под названием ncore, который обеспечивает собственное ядро для Arduino.И позволяет писать тесты для кода Arduino.

Из описания проекта

Собственное ядро позволяет вам компилировать и запускать эскизы Arduino на ПК, как правило, без каких-либо изменений.Он предоставляет собственные версии стандартных функций Arduino и интерфейс командной строки для предоставления входных данных для вашего эскиза, которые обычно поступают от самого оборудования .

Также на раздел "что мне нужно, чтобы это использовать"

Если вы хотите создать тесты, вам понадобится cxxtest из http://cxxtest.tigris.org.NCORE был протестирован с помощью cxxtest 3.10.1.

Если вы хотите выполнить модульное тестирование кода вне MCU (на рабочем столе), ознакомьтесь с libcheck:https://libcheck.github.io/check/

Я использовал его для тестирования своего собственного встроенного кода несколько раз.Это довольно надежный фреймворк.

Вы можете использовать эмулятор — вы можете перетащить микроконтроллер на схему и запустить свой код в Eclipse.Документация на веб-сайте рассказывает вам, как это настроить.

Используйте Proteus VSM с библиотекой Arduino для отладки вашего кода или его тестирования.

Это лучшая практика перед внедрением вашего кода, но будьте уверены в таймингах, потому что симуляция не выполняется в реальном времени так, как они выполняются на плате.

Попробуй Autodesk схемный симулятор.Это позволяет тестировать код Arduino и схемы со многими другими аппаратными компонентами.

В basic Arduino написан на C и C ++, даже библиотеки arduino написаны на C и C ++.Итак, проще говоря, просто обработайте код как C и C ++ и попробуйте выполнить модульное тестирование.Здесь под словом "обрабатывать" я подразумеваю, что вы должны изменить весь базовый синтаксис, такой как serial.println на sysout, pinmode на переменные, цикл void на цикл while(), который прерывается либо при нажатии клавиши, либо после некоторой итерации.

Я знаю, что это немного длительный процесс и не такой прямой.По моему личному опыту, как только вы с этим справляетесь, это оказывается более надежным.

-Нандха_Фрост

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top