65.9K
CodeProject 正在变化。 阅读更多。
Home

C++ 的最小单元测试库

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.87/5 (6投票s)

2005年3月4日

2分钟阅读

viewsIcon

48588

downloadIcon

355

非常小(一个头文件)的工具,用于支持 C++ 中的单元测试。

引言

Minitest 是一个帮助进行单元测试的库。它提供了一组非常小的功能(一个宏,两个函数)。
  • 宏 (MINITEST) 用于定义一个测试。
  • 以随机顺序执行所有测试(以发现测试之间的可能依赖关系)。
  • 仅执行最后修改的源文件中的测试(以缩短编辑-编译-测试循环)。

使用示例

#include <minitest.hpp>
#include <assert.h>

#ifndef NDEBUG

MINITEST
{
   assert(...);
} 

MINITEST
{
  ...
  assert(...);
  assert(...);
}

#endif //!NDEBUG

int main()
{
  minitest::execute_all_tests(); // execute all tests in random order
}

测试可以放在多个翻译单元(*.cpp 文件)中。

背景

已经有相当多的 C++ 测试框架(例如,请参阅此处)。 此处提供的库不提供与其他库一样多的功能,希望它易于使用且易于修改。

当无法添加 *.cpp 文件的大型框架时,或者在采用大型框架之前创建测试套件的第一步,或者为应用程序创建第二组独立的测试时,可以使用该库。

使用代码

创建测试用例

#include <minitest.hpp>

#ifdef DO_TESTING

// create test(s) on top level in *.cpp file (i.e. not within function)
MINITEST
{
  AClass object; // can be created?
} 

MINITEST
{
  if (pDatabase) {
    pDatabase->do_internal_test();    
  } else {
    assert(false);
  }
}
#endif //DO_TESTING

只有一个宏 - 测试的定义。 要进行实际检查,请使用 assert() 或您喜欢的调试工具。

执行所有测试

函数 minitest::execute_all_tests(bool) 以随机或固定顺序运行测试,并返回有关通过的测试数量和可能出现故障的测试的详细信息(有关详细信息,请参阅头文件中的结构 minitest::result)。

#include <iostream>
#include <minitest.hpp>

int main() 
{
   // run all tests in random order
   minitest::execute_all_tests(); 

   // run all tests in the same order as before 
   // (e.g. if a failure happens and we want to repeat it)
   minitest::execute_all_tests(false); 
   
  // run all tests (randomly) and evaluate result
  minitest::result res = minitest::execute_all_tests();
  if (res.all_tests_succeeded) 
  {
    std::cout << "All " << res.sucessful_tests_count << " tests OK.\n";
  } 
  else 
  {
    std::cout << "Only first " << res.sucessful_tests_count << " test(s) OK\n"
              << "The test in file " << res.failed_test_file << ", line " 
              << res.failed_test_line << " threw an exception.\n";
    // failed test can re re-run again
    res.failed_test();
  }
}

随机执行顺序

rand()(由 std::random_shuffle() 内部使用)用于模拟测试的随机性。 为了重复相同的测试序列,请执行以下操作之一:

  • 调用 minitest::execute_all_tests(false),将不会进行随机化 - 将保留上次执行的顺序。
  • 设置并记住随机数生成器的种子(通过 srand()),并在需要时再次设置它。

仅执行最后更改的源文件中的测试

如果运行测试花费的时间太长,您可能希望仅运行受源代码中最近更改影响的测试。 该库为此提供支持。

#include <minitest.hpp>

int main() 
{
  // execute tests from 3 source files modified last
  minitest::result res = minitest::test_last_changed_files(3);
  if (res.all_tests_succeeded) {
    // as before
  }
}

该库会检查所有源文件的的时间戳,选择最后修改的 N 个文件,并仅执行这些文件中的测试。 这应该有助于加快编辑-编译-测试循环并保持专注。

但是,应该不时运行所有测试:这里不处理模块之间的依赖关系!

处理 DLL

main() 中调用 minitest::execute_all_functions() 将不会运行 DLL 中的测试。 您需要添加一个辅助函数,例如:

// pseudocode
void complete_app_test() 
{
  minitest::execute_all_tests(); // in main executable
  foreach( just_loaded_DLLs ) {
    invoke_execute_all_tests( a_dll );
  }
}

int main() 
{
  complete_app_test();
}

这种麻烦是由于库的头文件仅实现造成的。

依赖性和可移植性

需要 STL。 该库使用来自 Boost 的几个头文件。 如果需要,可以使用简短的手写等效项替换这些头文件。

该库已使用 VC6、BCB6 和 Intel C++ 进行测试。 我预计它也能在 Posix 系统上工作。

历史

  • 2005 年 3 月 2 日:提交版本 1.0
© . All rights reserved.