我希望能够单元测试我的Arduino代码。理想情况下,我可以运行任何测试,而无需将代码上传到Arduino。哪些工具或库可以帮助我做到这一点?

目前正在开发的Arduino模拟器可能很有用,但似乎还没有准备好使用。

Atmel的AVR Studio包含一个芯片模拟器,可能很有用,但我不知道如何将它与Arduino IDE结合使用。


当前回答

看起来乳香就能完美地完成这项工作。

Emulino是Greg Hewgill为Arduino平台开发的模拟器。(源)

GitHub库

其他回答

你可以使用仿真——你可以在图表上拖放微控制器,然后在Eclipse中运行你的代码。网站上的文档会告诉你如何设置。

通过抽象出硬件访问并在测试中模拟它,我在单元测试PIC代码方面取得了相当大的成功。

例如,我用抽象PORTA

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

然后SetPortA可以很容易地模拟,而不需要在PIC版本中添加开销代码。

一旦硬件抽象被测试了一段时间,我很快发现代码通常会从测试平台到PIC,并且第一次就能工作。

更新:

对于单元代码,我使用#include seam,对于测试平台,在c++文件中使用#include单元代码,对于目标代码使用C文件。

作为一个例子,我想复用四个7段显示器,一个端口驱动段和第二个选择显示。显示代码通过SetSegmentData(char)和SetDisplay(char)与显示进行接口。我可以在我的c++测试平台中模拟这些,并检查我是否得到了我期望的数据。对于目标,我使用#define,这样就可以直接赋值,而不需要调用函数

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

为此我搭建了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_4 .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语法和测试结构看起来很熟悉,那是因为我采用了Matthew Murdoch的ArduinoUnit库 他在回答中提到了。

见参考。关于单元测试I/O引脚,时钟,串行端口等的更多信息。

这些单元测试是使用ruby gem中包含的脚本编译和运行的。有关如何设置的示例,请参阅README。或者从这些例子中复制一个:

一个测试Queue实现的实际示例 另一个Queue项目上的另一组测试 这是一个复杂的例子,模拟了一个通过SoftwareSerial连接控制交互设备的库,作为Adafruit FONA库的一部分 上面显示的DoSomething示例库,用于测试arduino_ci本身

在没有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是用C和c++编写的,甚至Arduino的库也是用C和c++编写的。因此,简单地说,只需将代码处理为C和c++,并尝试进行单元测试。这里,通过“句柄”这个词,我的意思是你改变所有的基本语法,如串行。Println到sysout, pinmode到变量,void循环到while()循环,该循环在keystock或某些迭代后中断。

我知道这是一个漫长的过程,不那么直接。根据我个人的经验,一旦你开始使用它,它就会变得更可靠。

-Nandha_Frost