使用 gtest 进行 Arduino 单元测试
Arduino unit testing using gtest
我一直在玩我购买的一个小型 Arduino 机器人,发现代码中有几个错误 运行(我可能已经放在那里了哈哈)并且想将 gtest 应用到用于定位错误的代码。问题是#include "Arduino.h" 不是我可以在我的电脑上 运行 的东西。这是我很难从我的代码中分离出来的东西。
我想在我的测试文件夹中构建一个测试可执行文件,它可以 运行 在我的 PC 上,但仍将大部分功能代码保留在上面的目录中,以便 Arduino IDE 可以构建以及。任何帮助将不胜感激。
结构:
<Folder>
-ArduinoBuild.ino
-Class.h
-Class.cpp
-<test folder>
--test.cpp
--CMakeList.txt
这就是问题开始的地方,Arduino.h引入build
Class.h
#ifndef CLASS_H_
#define CLASS_H_
#include "Arduino.h"
class Class{
public:
int Some_Attribute = 0;
void member_function();
};
#endif
Class.cpp
#include "Class.h"
void Class::member_function(){
Some_Attribute = Some_ArduinoFunc(this->Some_Attribute);
}
现在,如果我可以从我的构建中得到 Arduino.h,我可以在我的测试脚本中放置虚拟函数来弥补差距,但我想在构建过程中的某个地方保留 Arduino.h这样我就不必在每次为我的 Arduino 构建时都添加它。我尝试了几件事,其中之一是将 #include "Arduino.h" 移动到 .ino 文件,希望在构建时它会流到 Class.h/cpp 文件Arduino,但失败了。
test.cpp
// Class_test.cpp
#include <gtest/gtest.h>
#include "../Class.cpp"
TEST(buildbin, member_function) {
Class car;
car.member_function(1);
ASSERT_EQ(1, car.Some_Attribute);
}
再次感谢您的帮助,感谢您的宝贵时间。
POST 解决方案更新:
这是我必须在 parent 文件夹中输入脚本的示例 header:
#ifndef ARDUINO
#include<cmath>
#define floor std::round
void delay(int i){}
#endif
要访问文件以模仿库文件,您需要做的就是:
#include "test/FakeLib.XX"
使用宏。
您可以使用 #ifdef
... #endif
有选择地包含代码。示例:
#ifdef ARDUINO_VERSION
#include "Arduino.h"
#endif
void setup() {
// no setup
}
void loop() {
#ifdef ARDUINO_VERSION
digitalWrite(1, HIGH);
#else
printf("Setting pin 1 high\n");
#endif
}
还有 #ifndef
做相反的事情,它只包含 ARDUINO_VERSION 没有 定义的代码。
现在您可能会问,编译器如何知道它是否是 ARDUINO_VERSION?好问题。基于 this 线程,Arduino 似乎会为您定义 ARDUINO
,因此您可以使用 #ifdef ARDUINO
。或者,由于您应该更好地控制测试的编译方式,您可以使用 #ifdef TEST_VERSION
然后使用 -DTEST_VERSION
选项编译测试。
我一直在玩我购买的一个小型 Arduino 机器人,发现代码中有几个错误 运行(我可能已经放在那里了哈哈)并且想将 gtest 应用到用于定位错误的代码。问题是#include "Arduino.h" 不是我可以在我的电脑上 运行 的东西。这是我很难从我的代码中分离出来的东西。
我想在我的测试文件夹中构建一个测试可执行文件,它可以 运行 在我的 PC 上,但仍将大部分功能代码保留在上面的目录中,以便 Arduino IDE 可以构建以及。任何帮助将不胜感激。
结构:
<Folder>
-ArduinoBuild.ino
-Class.h
-Class.cpp
-<test folder>
--test.cpp
--CMakeList.txt
这就是问题开始的地方,Arduino.h引入build
Class.h
#ifndef CLASS_H_
#define CLASS_H_
#include "Arduino.h"
class Class{
public:
int Some_Attribute = 0;
void member_function();
};
#endif
Class.cpp
#include "Class.h"
void Class::member_function(){
Some_Attribute = Some_ArduinoFunc(this->Some_Attribute);
}
现在,如果我可以从我的构建中得到 Arduino.h,我可以在我的测试脚本中放置虚拟函数来弥补差距,但我想在构建过程中的某个地方保留 Arduino.h这样我就不必在每次为我的 Arduino 构建时都添加它。我尝试了几件事,其中之一是将 #include "Arduino.h" 移动到 .ino 文件,希望在构建时它会流到 Class.h/cpp 文件Arduino,但失败了。
test.cpp
// Class_test.cpp
#include <gtest/gtest.h>
#include "../Class.cpp"
TEST(buildbin, member_function) {
Class car;
car.member_function(1);
ASSERT_EQ(1, car.Some_Attribute);
}
再次感谢您的帮助,感谢您的宝贵时间。
POST 解决方案更新: 这是我必须在 parent 文件夹中输入脚本的示例 header:
#ifndef ARDUINO
#include<cmath>
#define floor std::round
void delay(int i){}
#endif
要访问文件以模仿库文件,您需要做的就是:
#include "test/FakeLib.XX"
使用宏。
您可以使用 #ifdef
... #endif
有选择地包含代码。示例:
#ifdef ARDUINO_VERSION
#include "Arduino.h"
#endif
void setup() {
// no setup
}
void loop() {
#ifdef ARDUINO_VERSION
digitalWrite(1, HIGH);
#else
printf("Setting pin 1 high\n");
#endif
}
还有 #ifndef
做相反的事情,它只包含 ARDUINO_VERSION 没有 定义的代码。
现在您可能会问,编译器如何知道它是否是 ARDUINO_VERSION?好问题。基于 this 线程,Arduino 似乎会为您定义 ARDUINO
,因此您可以使用 #ifdef ARDUINO
。或者,由于您应该更好地控制测试的编译方式,您可以使用 #ifdef TEST_VERSION
然后使用 -DTEST_VERSION
选项编译测试。