是否可以在main中以类似于Boost.MinimalTestFacility的方式调用Boost.UnitTest测试
Is it possible to envoke Boost.UnitTest tests within main in a way similar to the Boost.MinimalTestFacility?
我正在扩展一个用于计算流体动力学的库,所以我正在处理遗留代码。应用程序有时涉及初始化非常大的对象,其中大多数是相互依赖的。初始化取决于存储在目录中的配置和输入文件。
与我自己的测试黑客库相比,尝试使用测试框架应该是有意义的,因为有各种测试用例和家族以及测试,我可以从拥有测试树和闪亮的报告 + 自动化测试的能力中受益。
但是,在尝试在程序的特定点调用特定测试时,我遇到了一个问题。当我尝试使用谷歌测试时,这个问题已经发生了 - 请参阅这个问题。
下面是使用 Boost.Test 的问题模型:
#define BOOST_TEST_MODULE hugeObjectEvenTest
#define BOOST_TEST_NO_MAIN
#include <boost/test/included/unit_test.hpp>
#include<random>
#include<iostream>
BOOST_AUTO_TEST_SUITE (hugeObjectEvenTest)
BOOST_AUTO_TEST_CASE (test1)
{
BOOST_CHECK(hugeObject.value() % 2 == 0);
}
BOOST_AUTO_TEST_SUITE_END()
class HugeClass
{
int value_ = 0;
public:
HugeClass() = default;
HugeClass(int x) : value_(x) {};
int value () { return value_; }
void setValue (int val) { value_ = val; }
};
int main(int argc, const char *argv[])
{
HugeClass hugeObject;
std::random_device rd;
std::default_random_engine e1(rd());
std::uniform_int_distribution<int> dist(0,100);
for(int i = 0; i < 10; ++i)
{
hugeObject.setValue(dist(e1));
std::cout << hugeObject.value() << std::endl;
}
return 0;
}
这只是一个数值求解器应用程序的模型,就像这里找到的那样。
我认为我需要的是一个能够参考hugeObject
的全球固定装置。
与hugeObject
一样的实例在模拟循环(使用 for 循环建模)内进行修改(使用随机数生成建模)。
我想做的只是在main中的特定点执行特定的测试,并从拥有测试树以及使用测试框架的所有其他好处中受益。类似于最小测试设施的功能。
这在Boost.Test中可能吗?与谷歌测试一样,选择特定的测试可以通过在执行期间进行解析来完成。这对我的问题没有任何用处。我已经使用GTest和BoostTest进行单元测试,其中夹具的初始化是本地的,不依赖于main(argc,argv,配置和输入文件),我没有问题。
编辑:我可能会为此感到愤怒,但在处理遗留代码时,我相信以某种方式能够通过 const refs 访问 main 中的对象(以确保测试不会修改对象)是有益的,以比从夹具类继承更简单的方式。就我而言,这样做意味着一天的工作,而使用最小测试框架时放置在 main 中的简单BOOST_TEST_REQUIRE。当然,使用最小的框架,我没有测试树等,所以我回到了我开始的地方:在我自己的黑客测试库中。
执行此操作的一种可能方法是执行自己的手动测试注册,将要一起执行的测试分离到套件中并手动运行它们。例如:
using namespace boost::unit_test;
void test1() { std::cout << "Running test 1n"; }
void test2() { std::cout << "Running test 2n"; }
void test3() { std::cout << "Running test 3n"; }
void init_test_tree() {
test_suite *ts1 = BOOST_TEST_SUITE( "suite_a");
ts1->add( BOOST_TEST_CASE( &test1 ) );
ts1->add(BOOST_TEST_CASE( &test2 ));
framework::master_test_suite().add(ts1);
test_suite *ts2 = BOOST_TEST_SUITE( "suite_b");
ts2->add( BOOST_TEST_CASE( &test3 ) );
framework::master_test_suite().add(ts2);
}
bool empty_init() { return true; }
int main( int argc, char *argv[] ) {
init_test_tree();
std::cout << "Run suite an";
framework::run( framework::master_test_suite().get("suite_a"));
std::cout << "Run suite bn";
framework::run( framework::master_test_suite().get("suite_b"));
std::cout << "Run the treen";
// pass empty initialization function as we've already constructed the test tree
return unit_test_main(&empty_init, argc, argv);
}
手动注册自己的测试用例是乏味、无聊且容易出错的,我不推荐这样做。 相反,您可以简单地定义自己的main()
,而不是让Boost.Test为您提供它。 编写如下所示的main
:
HugeClass hugeObject;
boost::unit_test::test_suite *init_function(int argc, char *argv[])
{
// create test cases and suites and return a pointer to any enclosing
// suite, or 0.
return 0;
}
int main(int argc, const char *argv[])
{
std::random_device rd;
std::default_random_engine e1(rd());
std::uniform_int_distribution<int> dist(0,100);
for(int i = 0; i < 10; ++i)
{
hugeObject.setValue(dist(e1));
std::cout << hugeObject.value() << std::endl;
}
return boost::unit_test::unit_test_main(init_function, argc, argv);
}
如果这样做,您将获得:
- 自动测试用例注册
- 使用测试套件
- 在 Boost 的任何部分运行之前先在
main()
中执行任何特殊操作的能力.Test 运行
编写自己的 main 的一个烦人的副作用是:init_function的签名是不同的,具体取决于您是与静态版本的 Boost.Test 还是共享库(动态)版本的 Boost.Test 链接。 这些差异在我的 Boost.Test 文档重写中讨论了静态库和共享库的部分。
- 使用boost :: asio :: strand以这种方式安全吗?
- 如何将 boost::beast 中的序列化数据转换为字符串,以便我可以以 FIFO 方式处理它?
- 使用boost :: Beast进行CPU重的REST API,我是否应该使用异步或同步方式来实现它们以期望延迟
- G++ 和 boost 中 regex_replace() 替换字符串中''的不同处理方式
- boost binary_oarchive 对于不同的编译器,其工作方式不同
- 如何以有效的方式使用boost mpi广播功能
- 除了 boost 之外,获取目录中C++目录中所有文件的跨平台方式
- Cythonic 方式包装 boost::geometry::P oint accessors
- 是否可以在main中以类似于Boost.MinimalTestFacility的方式调用Boost.UnitTest测试
- 以 C++11 方式重写 boost 风味代码(Boost.Bind、Boost.Function)
- 如何使用Boost.在睡眠方面,以类似于Unity3D Coroutine的方式使用Coroutine
- 在 Boost Python 中公开模板化基类的最佳方式
- 调用boost::python::call的更智能方式
- 更改boost::property_tree读取将字符串转换为bool的方式
- 如何以"二维方式"使用 boost::variant 定义异构 std::map
- 以最快的方式搜索boost multi_index容器
- 如何以无序和可变的方式使用boost::bimap
- 如何在boost中以编程方式获得测试结果
- 使用Boost/ c++以二进制格式序列化对象的首选方式
- 如何遍历boost::fusion关联结构并以通用方式访问键