我使用的是C++98,除了标准库之外,我只能访问旧版本的Boost(谢天谢地,它有Boost Test)。文档虽然令人生畏,冗长,我只是不知道从哪里开始。
我有一些用Java进行单元测试的经验(我正在寻找C++中的单元测试),我见过test
包含与src
包分开的单元测试代码的包,我还看到了你把单元测试放在哪里?以及使用Boost和Eclipse进行单元测试。他们的建议各不相同,并提出了将测试代码与生产代码分开或将它们放在一起的不同打包结构的理由。
在我开始研究 Boost Test 之前,我在 Eclipse 中创建了这个结构(可能是错误的):
-- ProjectName
|-- Debug
|-- src
|-- test
我编写了另一个主要方法来运行测试函数。Eclipse 不喜欢这样,因为我在同一个项目中有两个主要方法。我在项目属性中摸索,没有找到任何有用的东西可以在构建时将生产代码与测试代码分开(实际上是链接)。我的临时解决方法是在终端中使用g++
并临时编译我的"测试"代码。
我在 Boost::Test -- 生成 Main()? 上发现了一些建议,Boost 实际上生成了自己的 main 方法,所以这是我目前对单元测试的攻击计划,特别是对于已经可用的测试工具库。
- 组织C++单元测试的传统方式是什么?
- 如何开始使用提升测试?(已安装加速)
- 在 Eclipse 中,我是否需要更改任何内容才能在 IDE 中独立于生产代码运行 Boost 单元测试?(IntelliJ 和 Java 的一个好处是,它只需单击一下即可自动运行您喜欢的任何主要方法)——这里的目标是能够在 Eclipse 中构建和运行我的测试。
- 我的测试应该放在一个单独的 Eclipse 项目中吗?(这是在回答我链接的第二个 SO 问题时提出的)
编辑:我发现这篇文章是为了介绍Boost Test,但它没有讨论如何在IDE设置中处理它。
我自己想出了如何做到这一点,我将为其他刚开始使用C++并需要测试其代码的人记录我的解决方案。目前我找不到任何地方的好介绍。以下是我使用的资源(并发现有用):
- C++ 使用Boost Test进行单元测试,它以比Boost文档更好的方式引入Boost Test。
- 你把你的单元测试放在哪里?它讨论了用C++进行测试的最传统方法。
- Eclipse g++ 中的单元测试,讨论允许测试的 Eclipse 构建配置
测试的C++约定与其他编码语言类似,只需在项目下名为test
的目录中编写测试即可。使用 Boost Test 需要链接单元测试框架:-l boost_unit_test_framework
Eclipse 中:
右键单击您的项目,转到属性、C/C++ 生成、设置、工具设置、GCC C++链接器、库,然后添加库名称
boost_unit_test_framework
(如果需要多线程,请在名称中添加-mt
;此外,一旦测试构建配置存在,您可以返回并选择该配置来链接库 - 这将减少其他构建的可执行文件的大小)。
为了能够在 Eclipse 中独立于主方法运行单元测试,我们需要建立一个新的构建配置。这样,Eclipse 就知道在执行测试时使用 main 方法排除源文件。
单击"项目"、"生成配置"、"管理...",然后选择"新建..."并称其为测试(或
test
以外的其他内容)。选择现有配置,以便从生产版本继承属性。
接下来,我们需要区分构建配置,以便在构建它们时,它们实际上对应于生产和测试构建。
右键单击"
test
"、"资源配置"、"从生成中排除...",然后选择代表生产版本的生成(即"调试"和/或"发布")。完成后,使用 main 方法右键单击源文件,并将其从测试版本中排除。
我们仍然需要改变一些事情。我们目前还没有任何测试代码,但我们仍然无法运行我们的测试版本,我们的测试版本也不会知道src
中存在的资源,因为 Eclipse 不会自动包含这些源文件。它们对于您的测试代码几乎不可见test
.
右键单击您的项目,转到"属性"、"C/C++ 生成"、"设置"、"工具设置"、"GCC C++编译器"、"包含",然后添加路径
/.../workspace/ProjectName
。
现在,为了能够在 Eclipse 中运行您的测试版本,它需要知道您希望 IDE 运行哪个可执行文件。
单击"运行"、"运行配置...",然后查看当前运行配置,通过指定调试版本名称"调试生成"、C/C++ 应用程序名称"调试/Artifact_Name"和生成配置"调试"来合并这些设置。接下来,创建一个新的运行配置,并将其称为"测试生成",将 C/C++ 应用程序设置为"测试/Artifact_Name",并确保生成配置为"测试"。
现在,您可以通过选择"活动"生成配置或运行正确的运行配置,在运行生产代码和测试代码之间切换。
最后,下面是设置完所有这些后使用提升测试进行单元测试的示例:
//unit_tests.cpp
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE someModuleName
#include <boost/test/unit_test.hpp>
#include <src/some_object.h>
struct template_objects {
some_object x;
template_objects() {
BOOST_TEST_MESSAGE("Setting up testing objects");
}
~template_objects() {
BOOST_TEST_MESSAGE("Tearing down testing objects");
}
}
BOOST_FIXTURE_TEST_SUITE(testSuiteName, template_objects)
BOOST_AUTO_TEST_CASE(testCase1) {
x.update();
BOOST_CHECK(x.is_up_to_date());
}
BOOST_AUTO_TEST_CASE(testCase2) {
BOOST_CHECK(x.is_not_up_to_date());
}
BOOST_AUTO_TEST_SUITE_END()
这演示了有关使用升压测试的一些关键事项:
- 建议定义
BOOST_TEST_DYN_LINK
;在包含任何Boost的库之前,您需要定义一种链接测试框架的方法。 - 你必须给"模块"命名,而不必是文件名
- 为了在进入测试用例之前自动设置和拆卸对象,Boost Test具有夹具,允许您多次调用对象的预先存在状态
struct
是对这些装置进行分组,这意味着您的对象应该有一个定义良好的构造函数和析构函数用于自动作用域(如果您没有调用new
,则不需要在拆解中delete
)
测试- 套件只是对测试用例进行逻辑分组的一种方式(我还没有测试过,但您可以将套件分解为多个文件以获得更好的逻辑分离)
其他花絮:要使 Boost 测试更详细,请转到测试版本的运行配置,并添加参数--log_level=test_suite
。