!REDIRECT “https://docs.px4.io/master/zh/test_and_ci/unit_tests.html“
单元测试
我们鼓励开发人员在开发的每个模块时编写单元测试,包括添加新功能,修复错误和重构。
PX4提供了以下几种编写单元测试的方法:
- 使用Google Test (“GTest”)进行单元测试 - 最小程度的内部依赖
- 使用GTest的功能测试 - 依赖parameters和 uORB和消息
- 软件在环(SITL)单元测试。 这些测试需要运行在完整的SITL环境中, 运行起来更慢,更难调试,所以建议尽可能使用GTest代替。
写一个GTest单元测试
Tip: 一般来说,如果你需要访问更高级的GTest工具、SITL的数据结构或者需要链接parameters
或 uorb
库,你应改用功能测试。
创建新的单元测试步骤如下:
- 单元测试分成三个部分:设置、运行、检查结果。 每个单元测试都应该测试一个特定行为或设置案例,如果测试失败,则很明显你的测试代码有错误。 请尽可能遵循这些标准。
- Copy and rename the example unit test AttitudeControlTest to the directory the code to be tested is in.
- 将新文件到该目录的
CMakeLists.txt
文件中。 文件看起来像px4_add_unit_gtest(SRC MyNewUnitTest.cpp LINKLIBS <library_to_be_tested>)
- 添加你想要的测试功能。 这包括了添加所需的头文件、新测试(每个测试都应该有单独的名称),并加入相关逻辑,运行测试代码并验证其行为是否符合预期。
- 如果需要添加新的依赖库,只要在如上所说的CMakeLists文件中
LINKLIBS
后面加入库的名字。
可以通用 make tests
命令来运行所有测试,然后在 build/px4_sitl_test/unit-MyNewUnit
目录中找到二进行制文件。 也可以直接通过调试器中运行。
写一个GTest功能测试
当测试或测试的组件依赖参数、uORB 消息、或更高级的GTest功能的时候,应当使用GTest功能测试。 Additionally, functional tests can contain local usage of STL data structures (although be careful of platform differences between e.g. macOS and Linux).
创建一个新的功能测试步骤如下:
- 一般来说(与单元测试类似)功能测试应分为三个部分:设置,运行,检查结果。 每个测试都应该包括一个特定行为或是设置案例,如果测试失败,则很明显有错误。 请尽可能遵循这些标准。
- Copy and rename the example functional test ParameterTest to the directory the code to be tested is in.
- 将ParameterTest 重命名为更符合你正在测试的代码功能。
- 将新文件添加到目录里面的
CMakeLists.txt
。 文件内容看起来像px4_add_functional_gtest(SRC MyNewFunctionalTest.cpp LINKLIBS <library_to_be_tested>)
- 添加你想要的测试功能。 这包括了,添加特定的头文件、新测试(每个测试都应该使用不同的命名),并设置相关逻辑,运行测试代码并验证是否符合预期。
- 如果需要添加新的依赖库,只要在如上所说的CMakeLists文件中LINKLIBS后面加入库的名字。
可以通用make tests
命令来运行所有测试,然后在 build/px4_sitl_test/functional-MyNewFunctional
目录中找到二进行制文件。 也可以直接通过调试器中运行。 It can be run directly in a debugger, however be careful to only run one test per executable invocation using the —gtest_filter=\
写一个软件在环(SITL)单元测试
当需要所有的飞行控制组件:驱动、时间或者更多时,应该SITL单元测试。 这些测试运行较慢(每个模块至少1秒+),同时难以测试,所以仅在必要时使用它们。
创建一个新的SITL单元测试步骤如下:
- Examine the sample Unittest-class.
- Create a new .cpp file within tests with name test_[description].cpp.
- 在 test_[description].cpp 中包括基本 unittest-class
<unit_test.h>
以及为新功能编写测试所需的所有文件。 - 在 test_[description].cpp 中创建一个继承自
UnitTest
的类[Description]Test
。 - 在
[Description]Test
类中,声明公共方法virtual bool run_tests()
。 - 在
[Description]Test
类中,声明测试相关特征所需的所有私有方法(test1()
,test2()
,…)。 - 在 test_ [description].cpp 中实现
run_tests()
方法,其中将运行每个测试[1,2,…]。 - 在 test_ [description].cpp 中,实现各种测试。
在 test_ [description].cpp 的底部声明测试。
ut_declare_test_c(test_[description], [Description]Test)
下面是一个模板:
#include <unit_test.h>
#include "[new feature].h"
...
class [Description]Test : public UnitTest
{
public:
virtual bool run_tests();
private:
bool test1();
bool test2();
...
};
bool [Description]Test::run_tests()
{
ut_run_test(test1)
ut_run_test(test2)
...
return (_tests_failed == 0);
}
bool [Description]Test::test1()
{
ut_[name of one of the unit test functions](...
ut_[name of one of the unit test functions](...
...
return true;
}
bool [Description]Test::test2()
{
ut_[name of one of the unit test functions](...
ut_[name of one of the unit test functions](...
...
return true;
}
...
ut_declare_test_c(test_[description], [Description]Test)
Note that
ut_[name of one of the unit test functions]
corresponds to one of the unittest functions defined within unit_test.h.Within tests_main.h define the new test:
extern int test_[description](int argc, char *argv[]);
Within tests_main.c add description name, test function and option:
```cpp … } tests[] = { {… {“[description]”, test_[description], OPTION}, … }
OPTION
can beOPT_NOALLTEST
,OPT_NOJIGTEST
or0
and is considered if within px4 shell one of the two commands are called:pxh> tests all
or
pxh> tests jig
If a test has option
OPT_NOALLTEST
, then that test will be excluded when callingtests all
. The same is true forOPT_NOJITEST
when commandtest jig
is called. 选项“0”表示从不排除测试,这是大多数开发人员想要使用的。- Add the test
test_[description].cpp
to the CMakeLists.txt.
## 本地机器上的测试
运行完整的 GTest 单元测试列表 GTest 功能测试和 SITL 单元测试脚本:
```bash
make tests
单独的 GTest 测试二进制文件处于build/px4_sitl_test/
目录中,可以直接在大多数IDE的调试器中运行。
使用以下命令对ctest名称使用正则表达式对要运行的测试子集进行筛选:
make tests TESTFILTER=<filter expression>
例如:
make tests TESTFILTER=unit
only run GTest unit testsmake tests TESTFILTER=sitl
only run simulation testsmake tests TESTFILTER=Attitude
only run theAttitudeControl
test