Pregunta

Me gustaría poder realizar una prueba unitaria de mi código Arduino.Idealmente, podría ejecutar cualquier prueba sin tener que cargar el código en Arduino.¿Qué herramientas o bibliotecas pueden ayudarme con esto?

Hay un Emulador Arduino en desarrollo lo cual podría ser útil, pero aún no parece estar listo para su uso.

Estudio AVR de Atmel contiene un simulador de chip que podría ser útil, pero no veo cómo usarlo junto con el IDE de Arduino.

¿Fue útil?

Solución 2

En la ausencia de marcos de prueba unidad de pre-existentes para Arduino, he creado ArduinoUnit . Aquí está un simple boceto Arduino demostrar su uso:

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

Otros consejos

No ejecute pruebas unitarias en el dispositivo o emulador Arduino

El caso contra las pruebas basadas en dispositivos/emuladores/Sim de microcontroladores

Hay mucha discusión sobre lo que prueba de unidad medios y no lo soy Realmente tratando de hacer un argumento sobre eso aquí.Esta publicación es nodiciéndote que evites todo Pruebas prácticas en su objetivo final hardware.Estoy tratando de hacer un punto acerca de la optimización de su ciclo de retroalimentación de desarrollo mediante la eliminación del hardware de destino de sus pruebas más mundanas y frecuentes.Se supone que las unidades sometidas a prueba ser mucho más pequeño que todo el proyecto.

El propósito de las pruebas unitarias es probar la calidad de su propio código.Por lo general, las pruebas unitarias nunca deben probar la funcionalidad de factores fuera de su control.

Piensa en ello de esta manera:Incluso si tuviera que probar la funcionalidad de la biblioteca Arduino, el hardware del microcontrolador o un emulador, es absolutamente imposible para que los resultados de dichas pruebas le indiquen algo sobre la calidad de su propio trabajo.Por lo tanto, es mucho más valioso y eficiente escribir pruebas unitarias que no se ejecuten en el dispositivo de destino (o emulador).

Las pruebas frecuentes en el hardware de destino tienen un ciclo dolorosamente lento:

  1. Modifica tu código
  2. Compile y cargue en un dispositivo Arduino
  3. Observar el comportamiento y adivinar si su El código está haciendo lo que esperas.
  4. Repetir

El paso 3 es particularmente desagradable si espera recibir mensajes de diagnóstico a través del puerto serie pero su proyecto en sí necesita usar el único puerto serie de hardware de su Arduino.Si estaba pensando que la biblioteca SoftwareSerial podría ayudar, debe saber que hacerlo probablemente interrumpa cualquier funcionalidad que requiera una sincronización precisa, como generar otras señales al mismo tiempo.Este problema me ha pasado a mí.

Nuevamente, si probaras tu boceto usando un emulador y tus rutinas de tiempo crítico se ejecutaron perfectamente hasta que las subiste al Arduino real, entonces la única lección que aprenderás es que el emulador tiene fallas, y sabiendo esto aún revela nada sobre la calidad de tu propio trabajar.

Si es una tontería probar en el dispositivo o emulador, ¿qué debería ¿Sí?

Probablemente estés usando una computadora para trabajar en tu proyecto Arduino.Esa computadora es órdenes de magnitud más rápida que el microcontrolador.Escribe las pruebas para construir y ejecutar en tu computadora.

Recuerde, el comportamiento de la biblioteca Arduino y el microcontrolador debe ser se supone que es correcto o al menos consecuentemente incorrecto.

Cuando sus pruebas producen resultados contrarios a sus expectativas, es probable que tenga una falla en el código que se probó.Si el resultado de su prueba coincide con sus expectativas, pero el programa no se comporta correctamente cuando lo carga en Arduino, entonces sabrá que sus pruebas se basaron en suposiciones incorrectas y probablemente tenga una prueba defectuosa.En cualquier caso, se le habrá brindado información real sobre cuáles deberían ser sus próximos cambios en el código.La calidad de sus comentarios mejora desde "algo está roto" a "este código específico está roto".

Cómo crear y ejecutar pruebas en su PC

Lo primero que debes hacer es identifique sus objetivos de prueba.Piensa en qué partes de tu propio código desea probar y luego asegúrese de construir su programa de tal manera que pueda aislar partes discretas para las pruebas.

Si las piezas que desea probar llaman a alguna función de Arduino, deberá proporcionar reemplazos de maquetas en su programa de prueba.Esto es mucho menos trabajo de lo que parece.En realidad, sus maquetas no tienen que hacer nada más que proporcionar entradas y salidas predecibles para sus pruebas.

Cualquier código propio que desee probar debe existir en archivos fuente distintos del boceto .pde.No te preocupes, tu boceto aún se compilará incluso con algún código fuente fuera del boceto.Cuando realmente se pone manos a la obra, en el archivo de boceto se debe definir poco más que el punto de entrada normal de su programa.

¡Todo lo que queda es escribir las pruebas reales y luego compilarlas usando su compilador C++ favorito!Probablemente esto se ilustra mejor con un ejemplo del mundo real.

Un ejemplo de trabajo real

Uno de mis proyectos favoritos encontrado aquí tiene algunas pruebas simples que se ejecutan en la PC.Para enviar esta respuesta, simplemente repasaré cómo hice una maqueta de algunas de las funciones de la biblioteca Arduino y las pruebas que escribí para probar esas maquetas.Esto no es contrario a lo que dije antes acerca de no probar el código de otras personas porque fui yo quien escribió las maquetas.Quería estar muy seguro de que mis maquetas fueran correctas.

Fuente de mock_arduino.cpp, que contiene código que duplica algunas funciones de soporte proporcionadas por la biblioteca 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);
}

Utilizo la siguiente maqueta para producir resultados legibles cuando mi código escribe datos binarios en el dispositivo serie de hardware.

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;

y finalmente, el programa de prueba real:

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

Esta publicación es lo suficientemente larga, así que consulte mi proyecto en GitHub para ver más casos de prueba en acción.Mantengo mis trabajos en progreso en ramas distintas a la maestra, así que revisa esas ramas también para ver si hay pruebas adicionales.

Elegí escribir mis propias rutinas de prueba ligeras, pero también hay disponibles marcos de pruebas unitarias más sólidos como CppUnit.

Tengo un considerable éxito unidad de prueba mi código PIC abstrayendo el acceso al hardware y burlándose de él en mis pruebas.

Por ejemplo, I PORTA abstracto con

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

Entonces SetPortA fácilmente puede ser burlado, sin añadir código de arriba en la versión PIC.

Una vez que la abstracción de hardware ha sido probado desde hace tiempo que pronto encontrará que por lo general va el código del banco de pruebas para el PIC y trabaja por primera vez.

Actualización:

utilizo una costura # include para el código de la unidad, #including el código de unidad en un archivo de C ++ para la instalación de prueba, y un archivo de C para el código de destino.

Como ejemplo quiero multiplexar cuatro displays de 7 segmentos, un puerto de conducción de los segmentos y una segunda selección de la pantalla. Las interfaces de código de visualización con las pantallas a través de SetSegmentData(char) y SetDisplay(char). Puedo burlarse de estos en mi banco de pruebas C ++ y comprobar que consigo los datos que espero. Para el objetivo utilizo #define de modo que consiga una asignación directa sin la sobrecarga de una llamada de función

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

Parece que emulino haría el trabajo a la perfección.

  

Emulino es un emulador de la plataforma Arduino por Greg Hewgill. ( Fuente )

GitHub repositorio

simavr es un AVR simulador usando avr-gcc.

Ya es compatible con algunos ATtiny y microcontroladores ATMEGA, y - según el autor - es fácil de añadir un poco más

.

En los ejemplos se encuentra simduino, un emulador Arduino. Se admite la ejecución el cargador de arranque Arduino y puede ser programado con avrdude través Socat (A modificada Netcat ).

Usted puede probar la unidad en Python con mi proyecto, PySimAVR . Arscons se utiliza para la construcción y simavr para la simulación.

Ejemplo:

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'

Prueba de inicio:

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

No estoy al tanto de cualquier plataforma que puede probar el código de Arduino.

Sin embargo, no es la Fritzing plataforma , que se puede utilizar para modelar el hardware y más tarde en los diagramas de exportación de PCB y otras cosas.

Merece la pena echar.

Estamos utilizando placas Arduino para la adquisición de datos en un gran experimento científico. Posteriormente, hay que apoyar varias placas Arduino con diferentes implementaciones. Escribí utilidades Python para cargar dinámicamente imágenes hexagonales Arduino durante las pruebas unitarias. El código que se encuentra en el siguiente enlace es compatible con Windows y Mac OS X a través de un archivo de configuración. Para averiguar cuál es su hexagonales imágenes se colocan por el IDE Arduino, pulsa la tecla de mayúsculas antes de golpear el botón Generar (reproducción). Golpear la tecla de mayúsculas, mientras que golpear carga para averiguar dónde se encuentra su avrdude (línea de comando de la utilidad de carga) en su sistema / versión de Arduino. Alternativamente, se puede ver en los archivos de configuración incluido y su ubicación de instalación (actualmente en Arduino 0020).

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

Este programa permite un funcionamiento automatizado de varias pruebas de unidad de Arduino. El proceso de prueba se inicia en el PC, pero las pruebas se ejecutan en el hardware real Arduino. Un conjunto de pruebas de unidad se utiliza típicamente para probar una biblioteca Arduino. (Esto

Foro Arduino: http://arduino.cc/forum/index.php?topic = 140.027,0

página del proyecto GitHub: http://jeroendoggen.github.com/Arduino-TestSuite

Página en el índice de paquetes Python: http://pypi.python.org/pypi/arduino_testsuite

Las pruebas unitarias se escriben con la "Biblioteca de pruebas unitarias Arduino": http://code.google. com / p / arduinounit

Los siguientes pasos se realizan para cada conjunto de pruebas de unidad:

  • Leer el archivo de configuración para averiguar que pone a prueba a ejecutar
  • El script compila y carga un boceto Arduino que contiene el código de la unidad de pruebas.
  • Las pruebas de unidad se ejecutan en la placa Arduino.
  • Los resultados de la prueba se imprimen sobre el puerto de serie y se analizaron por la secuencia de comandos Python.
  • El script comienza la próxima prueba, repetir los pasos anteriores para todas las pruebas que se solicitan en el fichero de configuración.
  • El script muestra un resumen que muestra una visión general de todas las pruebas fallidas / aprobada en el banco de pruebas completo.

Mantener código específico del hardware separado o abstraído del resto para que pueda probar y depurar que más grande "descanso" en cualquier plataforma para la que tiene buenas herramientas y con el que está familiarizado más.

Básicamente, tratar de construir la mayor cantidad de código final del mayor número de bloques de construcción conocida al trabajo como sea posible. El trabajo específico del hardware restante será mucho más fácil y más rápido. Usted puede terminar mediante el uso de emuladores existentes y / o dispositivos de su propia emulación. Y luego, por supuesto, tendrá que poner a prueba la realidad de alguna manera. Dependiendo de las circunstancias, que pueden o no estar muy bien automatizables (es decir, quién o qué va a presionar los botones y proporcionar otras entradas? ¿Quién o qué va a observar e interpretar diversos indicadores y salidas?).

James W. Grenning escribe grandes libros y éste es de las pruebas unitarias incrustado código C desarrollo basado en pruebas para C Embedded .

Estoy utilizando Searduino al escribir código de Arduino. Searduino es un simulador de Arduino y un entorno de desarrollo (Makefile, código C ...) que hace que sea fácil de cortar en C / C ++ usando su editor favorito. Puede importar bocetos Arduino y ejecutarlos en el simulador.

Captura de Searduino 0,8: http: // searduino. files.wordpress.com/2014/01/jearduino-0-8.png

Searduino 0.9 será lanzado y un vídeo se grabará en cuanto la dura se realizan pruebas .... en un día o dos.

Las pruebas en el simulador no debe ser considerado como pruebas reales, pero sin duda me han ayudado mucho en la búsqueda de errores estúpidos / lógicas (olvidando que hacer pinMode(xx, OUTPUT), etc.).

Por cierto: yo soy una de las personas que desarrollan Searduino

.

arduino_ci para este propósito. Aunque se limita a probar bibliotecas Arduino (y bocetos no independientes), que permite a las pruebas de unidad que se ejecutan de forma local o en un sistema de IC (como Travis CI o Appveyor).

Considere una biblioteca muy simple en su directorio de la biblioteca de Arduino, llamado DoSomething, con do-something.cpp:

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

int doSomething(void) {
  return 4;
};

Se había unidad de prueba de la siguiente manera (con un archivo de prueba llamada test/is_four.cpp o algo así):

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

Eso es todo. Si esa estructura sintáctica assertEqual y la prueba parece familiar, es porque he adoptado algunas de de Matthew Murdoch ArduinoUnit biblioteca  que se hace referencia en su respuesta .

Reference.md para obtener más información de las pruebas unitarias I pins E / S, el reloj, puertos serie, etc.

Estas pruebas unitarias se compilan y ejecutan utilizando un script contenida en una gema de rubíes. Para ver ejemplos de cómo poner esto en marcha, consulte la README.md o simplemente copiar de uno de estos ejemplos:

Hay un proyecto llamado NCORE , que proporciona núcleo nativo para Arduino. Y le permite escribir pruebas para el código de Arduino.

A partir de la descripción del proyecto

  

El núcleo nativo le permite compilar y ejecutar bocetos en el Arduino   PC, generalmente sin la modificación. Proporciona versiones nativas de   Arduino funciones estándar, y una interepreter de línea de comandos para dar   entradas a su boceto que normalmente son emitidas desde el hardware   sí mismo.

También en la rel="nofollow"> href="https://github.com/maniacbug/ncore#what-do-i-need-to-use-it"

  

Si usted quiere construir las pruebas, necesitará CxxTest de    http://cxxtest.tigris.org . NCORE ha sido probado con 3.10.1 CxxTest.

Si desea código de prueba de unidad exterior MCU (en el escritorio), echa un vistazo a libcheck: https://libcheck.github.io/check/

Lo utilicé para probar mi propio código incrustado par de veces. Es bastante robusto marco.

Puede utilizar emulare - se puede arrastrar y soltar un microcontrolador en un diagrama y ejecutar el código en Eclipse. La documentación en el sitio web le indica cómo configurarlo.

Uso de Proteus VSM con una biblioteca de Arduino para depurar su código o ponerla a prueba.

Es una buena práctica antes de obtener su código de a bordo, pero asegúrese con períodos de tiempo debido a que la simulación no se ejecuta en tiempo real a medida que corren en el tablero.

Trate simulador de circuitos Autodesk . Permite probar el código de Arduino y circuitos con muchos otros componentes de hardware.

En Arduino básica se escribe con C y C ++, incluso librerías de Arduino están escritas en C y C ++. Por lo tanto, en términos simples, simplemente manejar el código como C y C ++ y trate de hacer la prueba de la unidad. En este caso, por la palabra "mango" me refiero a cambiar toda la sintaxis básica como Serial.println a SYSOUT, pinMode a varaibles, void loop al bucle while () que se rompe, ya sea en Keystock o después de alguna iteración.

Sé que esto es poco un proceso largo y no tan recta forward.On mi experiencia personal, una vez que llegue a hacer con él, esto resulta ser más fiable.

-Nandha_Frost

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top