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

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

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


当前回答

你可以在我的项目PySimAVR中使用Python进行单元测试。Arscons用于构建,simavr用于模拟。

例子:

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

其他回答

试试Autodesk电路模拟器。它允许用许多其他硬件组件测试Arduino代码和电路。

为此我搭建了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本身

如果你想在MCU之外(在桌面上)进行单元测试,请检查libcheck: https://libcheck.github.io/check/

我用它测试了几次我自己的嵌入式代码。这是一个非常健壮的框架。

通过抽象出硬件访问并在测试中模拟它,我在单元测试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;}

你可以在我的项目PySimAVR中使用Python进行单元测试。Arscons用于构建,simavr用于模拟。

例子:

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