单元测试Arduino类

Unit testing an Arduino Class

本文关键字:Arduino 单元测试      更新时间:2023-10-16

我目前正在研究一个嵌入式系统项目,我们正在使用Arduino Uno进行硬件原型设计。到目前为止,我们需要能够从温度传感器(TMP36)获得可靠的温度读数,并且我已经设法为这个特定的传感器编写了一个库/类。你可以在这里找到它:
TMP36.h

#include <Arduino.h>
class TMP36
{
    public:
        TMP36(int pino);
        float getTempC();
        void setLimSup(float a);
        void setLimInf(float a);
        void testLimSup();
        void testLimInf();
    private:
        float _limSup;
        float _limInf;
        int _pino;
        float _tensao;
        float getTensao();
};

TMP36.cpp

#include "Arduino.h"
#include "TMP36.h"
#include "ArduinoUnit.h"
TMP36::TMP36 (int pino)
{
    _pino = pino;
}
float TMP36::getVoltage()
{
    return (analogRead(_pino) * 0.004882814);
}
float TMP36::getTempC ()
{  
    _tensao = getVoltage();
    return (_tensao - 0.5) * 100.0;
}
void TMP36::setLimSup(float a)
{
    _limSup = a;
}
void TMP36::setLimInf(float a)
{
    _limInf = a;
}
void TMP36::testeLimSup()
{
    test(okLimSup)
    {
        float reading = getTempC();
        AssertLessOrEqual(reading, _limSup);
    }
}
void TMP36::testeLimInf()
{
    test()
    {
        float reading = getTempC();
        assertMoreOrEqual(reading, _limInf);
    }
}

为了能够测试getTempC是否在传感器范围内,我一直在与ArduinoUnit 2混淆,但是在编译此代码时:

#include "TMP36.h"
TMP36 tmp36(0);
void setup() {
  Serial.begin(9600);
}
void loop() {
  float temp;
  temp = tmp36.getTempC();
  Serial.println(temp);
  delay(1000);
}

在Arduino IDE上,我得到以下错误:

In file included from /media/pedro/Storage/Linux/Arduino/arduino-1.6.11/libraries/TMP36/TMP36.cpp:3:0:
/media/pedro/Storage/Linux/Arduino/arduino-1.6.11/libraries/TMP36/TMP36.cpp: In member function 'void TMP36::testeLimSup()':
/media/pedro/Storage/Linux/Arduino/arduino-1.6.11/libraries/ArduinoUnit/ArduinoUnit.h:591:164: error: qualified-id in declaration before '(' token
 #define test(name) struct test_ ## name : TestOnce { test_ ## name() : TestOnce(F(#name)) {}; void once(); } test_ ## name ## _instance; void test_ ## name :: once() 
                                                                                                                                                                    ^
/media/pedro/Storage/Linux/Arduino/arduino-1.6.11/libraries/TMP36/TMP36.cpp:34:2: note: in expansion of macro 'test'
  test(okLimSup)
  ^
/media/pedro/Storage/Linux/Arduino/arduino-1.6.11/libraries/TMP36/TMP36.cpp: In member function 'void TMP36::testeLimInf()':
/media/pedro/Storage/Linux/Arduino/arduino-1.6.11/libraries/ArduinoUnit/ArduinoUnit.h:591:164: error: qualified-id in declaration before '(' token
 #define test(name) struct test_ ## name : TestOnce { test_ ## name() : TestOnce(F(#name)) {}; void once(); } test_ ## name ## _instance; void test_ ## name :: once() 
                                                                                                                                                                    ^
/media/pedro/Storage/Linux/Arduino/arduino-1.6.11/libraries/TMP36/TMP36.cpp:45:2: note: in expansion of macro 'test'
  test()
  ^
/media/pedro/Storage/Linux/Arduino/arduino-1.6.11/libraries/TMP36/TMP36.cpp:50:1: error: expected '}' at end of input
 }
 ^
exit status 1
Error compiling for board Arduino/Genuino Uno.

由于这是我第一次进行单元测试,我不太确定错误是什么意思,所以我需要帮助来修复它们。

谢谢!

好的,而不是试图在类内进行单元测试,我设法使它们在setup()loop()函数之外。下面是带有示例输出的工作代码:

//TMP36.h
#include <Arduino.h>
#include <ArduinoUnit.h>
class TMP36
{
    public:
        TMP36(int pino, float limInf, float limSup); //implementado
        float getTempC(); //implementado
        void setLimSup(float a);//implementado
        void setLimInf(float a);//implementado
        void testeLimSup();
        void testeLimInf();
        float getLimSup();
        float getLimInf();
    private:
        float _limSup; //setado pelo setLimSup;
        float _limInf; //setado pelo setLimInf;
        int _pino; //setado pelo construtor
        float _tensao; //retorno do getTempC;
        float getTensao();
};

/***************************/

//TMP36.cpp
#include "Arduino.h"
#include "TMP36.h"
#include "ArduinoUnit.h"
TMP36::TMP36 (int pino, float limInf, float limSup)
{
    pinMode(pino, OUTPUT);
    _pino = pino;
    _limInf = limInf;
    _limSup = limSup;
}
float TMP36::getTensao()
{
    return (analogRead(_pino) * 0.004882814);
}
float TMP36::getTempC ()
{   
    _tensao = getTensao();
    return (_tensao - 0.5) * 100.0;
}
void TMP36::setLimSup(float a)
{
    _limSup = a;
}
void TMP36::setLimInf(float a)
{
    _limInf = a;
}
float TMP36::getLimSup() {return _limSup; }
float TMP36::getLimInf() {return _limInf; }

/***************************/

//sketch.ino
#include <ArduinoUnit.h>
#include "TMP36.h"
TMP36 tmp36(0, -40, 125);
test(upLimOK)
{
  float a = tmp36.getLimSup();
  float b = tmp36.getTempC();
  assertLessOrEqual(b, a);
}
test(downLimOK)
{
  float a = tmp36.getLimInf();
  float b = tmp36.getTempC();
  assertMoreOrEqual(b, a);
}
void setup() {
  Serial.begin(9600);
}
void loop() {
  float temp;
  temp = tmp36.getTempC();
  Serial.print("TMP36 Reading: ");
  Serial.println(temp);
  delay(1000);
  Test::run();
}
样本输出:

TMP36 Reading: 26.66
TMP36 Reading: 26.66
Test downLimOK passed.
Test upLimOK passed.
Test summary: 2 passed, 0 failed, and 0 skipped, out of 2 test(s).

使用arduino_ci(充分披露,我是作者),您可以在没有硬件存在的情况下完成此操作。因为我采用了ArduinoUnit的测试宏集,所以它将与您现在拥有的测试代码有更多的相似之处。

您最终将测试代码放在名为test/的新目录中,因此test/limits.cpp可能看起来像这样

#include <ArduinoUnitTests.h>
#include "TMP36.h"
TMP36 tmp36(0, -40, 125);
unittest(upLimOK)
{
  float a = tmp36.getLimSup();
  float b = tmp36.getTempC();
  assertLessOrEqual(b, a);
}
unittest(downLimOK)
{
  float a = tmp36.getLimInf();
  float b = tmp36.getTempC();
  assertMoreOrEqual(b, a);
}
unittest_main()

要执行单元测试,您需要在本地设置测试运行器,或者如果您想使其成为拉取请求过程的一部分,请使用GitHub Action。