我希望能够单元测试我的Arduino代码。理想情况下,我可以运行任何测试,而无需将代码上传到Arduino。哪些工具或库可以帮助我做到这一点?
目前正在开发的Arduino模拟器可能很有用,但似乎还没有准备好使用。
Atmel的AVR Studio包含一个芯片模拟器,可能很有用,但我不知道如何将它与Arduino IDE结合使用。
我希望能够单元测试我的Arduino代码。理想情况下,我可以运行任何测试,而无需将代码上传到Arduino。哪些工具或库可以帮助我做到这一点?
目前正在开发的Arduino模拟器可能很有用,但似乎还没有准备好使用。
Atmel的AVR Studio包含一个芯片模拟器,可能很有用,但我不知道如何将它与Arduino IDE结合使用。
当前回答
通过抽象出硬件访问并在测试中模拟它,我在单元测试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;}
其他回答
试试Autodesk电路模拟器。它允许用许多其他硬件组件测试Arduino代码和电路。
通过抽象出硬件访问并在测试中模拟它,我在单元测试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;}
如果您有兴趣运行INO草图并检查串行输出,我在我的Arduino NMEA校验和项目中有一个工作实现。
下面的脚本获取该文件,并使用Arduino CLI将其编译为HEX文件,然后加载到SimAVR中,SimAVR对其进行计算并打印串行输出。由于所有Arduino程序都永远运行,没有真正杀死自己的选项(exit(0)不起作用),我让草图运行几秒钟,然后将捕获的输出与预期的输出进行区分。
下载并提取Arduino CLI(在本例中,版本为0.5.0 -撰写本文时的最新版本):
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
现在你可以更新索引并安装相应的核心:
./arduino-cli core update-index
./arduino-cli core install arduino:avr
假设你的草图名为nmea-checksum。ino,获取ELF和HEX,运行:
./arduino-cli compile -b arduino:avr:uno nmea-checksum.ino
接下来,SimAVR运行HEX(或ELF) -我从源代码构建,因为最新版本不适合我:
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
成功的编译将为您提供simavr/run_avr,您可以使用它来运行草图。就像我说的,暂停它,否则它永远不会终止:
cd simavr
timeout 10 ./run_avr -m atmega168 -f 16000000 ../../nmea-checksum.ino.arduino.avr.uno.elf &> nmea-checksum.ino.clog || true
生成的文件将有ANSI颜色代码控制字符包装串行输出,以摆脱这些:
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
现在你所需要做的就是将这个文件与一个已知的好文件进行比较:
diff nmea-checksum.ino.log ../../nmea-checksum.ino.test
如果没有差异,diff将以代码0退出,否则脚本将失败。
你可以在我的项目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
We are using Arduino boards for data acquisition in a large scientific experiment. Subsequently, we have to support several Arduino boards with different implementations. I wrote Python utilities to dynamically load Arduino hex images during unit testing. The code found on the link below supports Windows and Mac OS X via a configuration file. To find out where your hex images are placed by the Arduino IDE, hit the shift key before you hit the build (play) button. Hit the shift key while hitting upload to find out where your avrdude (command line upload utility) is located on your system / version of Arduino. Alternatively, you can look at the included configuration files and use your install location (currently on Arduino 0020).
http://github.com/toddstavish/Python-Arduino-Unit-Testing