【问题标题】:Helping getting started using Boost.Test帮助开始使用 Boost.Test
【发布时间】:2023-03-02 21:16:01
【问题描述】:

我正在尝试开始单元测试。我正在查看一些 C++ 框架并想尝试 Boost.Test。该文档似乎非常详尽,而且有点压倒性,尤其是单元测试的新手。所以这是我想要的一种情况:

假设我有 2 个课程,FooBar。我想为Foo 编写一套测试,为Bar 编写一套测试,最好在不同的文件中。只有当我使用命令行参数运行程序时,我才想运行测试。所以我的main() 应该是这样的:

int main(int argc, const char* argv[])
{
    if (argc == 1 && strcmp(argv[0], "-test") == 0)
        run_all_tests();
    else
        return program_main(argc, argv);
}

我认为test_foo.cpp 应该是这样的:

#include "foo.hpp"
#define BOOST_TEST_MODULE Foo test
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE( Foo_Test )

BOOST_AUTO_TEST_CASE( Foo1 )
{
    Foo f;
    BOOST_CHECK( f.isValid() );
}

BOOST_AUTO_TEST_CASE( Foo2 )
{
    Foo f;
    BOOST_CHECK( f.baz() == 5 );
}

BOOST_AUTO_TEST_SUITE_END()

但是,我不知道 (1) 运行测试的实际命令是什么,以及 (2) 如何实际告诉库我要运行每个测试。

那么,谁有使用过 Boost.Test 的经验?有人可以提供详细的帮助吗?非常感谢。

【问题讨论】:

    标签: c++ unit-testing boost


    【解决方案1】:

    在您的test_foo.cpp 中,宏添加了测试套件和测试用例 到一个全局列表:master_testsuite,这是所有测试的根 节点。你只需要编译所有的测试文件,比如 test_foo.cpp, test_boo.cpp 和一个跑步者,然后将它们全部链接到 on 可执行文件。

    函数unit_test_main用于运行master_testsuite中的测试。

    boost::unit_test::unit_test_main(
        &init_unit_test,
        argc,
        argv
    )
    

    基于您在包含之前定义的宏 &lt;boost/test/unit_test.h&gt;Boost.Test 可能已经生成了 main 为您服务。[1]生成的main 简单调用 unit_test_mainargcargvmain。建议 使用unit_test_main,因为它可以处理一些控制台参数, 喜欢run test by name

    unit_test_main 的第一个参数是一个钩子。根据 BOOST_TEST_ALTERNATIVE_INIT_API,定义不同。

    #ifdef BOOST_TEST_ALTERNATIVE_INIT_API
    typedef bool        (*init_unit_test_func)();
    #else
    typedef test_suite* (*init_unit_test_func)( int, char* [] );
    #endif
    

    您可以自定义挂钩中的master_testsuite。在第二 表单,返回值为新的主测试套件。

    [1] 如果定义了 BOOST_TEST_MAINBOOST_TEST_MAIN,但是 BOOST_TEST_NO_MAIN 不是。

    【讨论】:

      【解决方案2】:

      您可以从即菜单命令开始测试,但这并不是那么简单,遗憾的是没有很好的文档记录。更可悲的是 - 无法传递要创建日志文件的路径。我不得不自己添加这样一个命令行选项。不幸的是我还没有提交它。我的代码如下所示:

      #ifdef DEBUG
      
      #undef main
      #define BOOST_TEST_MAIN
      #include <boost/test/included/unit_test.hpp>
      
      int DoUnitTests()
      
      {
          char *args[] = {"", "--log_level=all", "--auto_start_dbg=yes"};
      
          bool result = ::boost::unit_test::unit_test_main(&init_unit_test_suite, sizeof(args) / sizeof(char*), args);
      
          MessageDlog("Unittests result: %s", result ? "ERRORS in Unittests" :  "Goooood!");
          return result;
      }
      
      #else
      int DoUnitTests()
      
      {
      }
      #endif
      

      【讨论】:

      • 你在说什么?请更具体。
      • 使用 Visual C++ 编译良好...您的链接甚至显示警告,而不是 g++ 中的错误,因此可以编译。
      • 好吧,它不应该编译。因为它是UB。
      【解决方案3】:

      BOOST.Test 非常灵活,您可以随心所欲。但是,既然您说您是单元测试的新手,那么您可能应该遵循标准的单元测试结构。

      这是为您要进行单元测试的每个项目都有一个单独的测试项目。然后包括构建测试项目所需的源代码和库。

      这更简洁,因为您的主项目中没有可能意外运行的测试逻辑,并且由于它们有自己的可执行文件,因此运行测试很容易。这种方法也适用于测试库。如果您遵循这种结构,您会发现大多数 BOOST.Test 默认设置都是开箱即用的,您只需担心编写测试和代码。

      【讨论】:

        【解决方案4】:

        没有像 NUnit 那样的独立测试运行器

        您只需将测试用例构建为单个 .exe 应用程序(如果您在 Windows 上)并运行它

        【讨论】:

        • 我不明白...你是怎么正常运行程序的(没有测试)?
        • 基本上您的 test_foo.cpp 应该构建为单个 .exe 程序并链接到包含 Foo 和 Bar 类的库。 boost.test 头文件之一已经定义了 main 函数,所以我认为您提出的建议不可行。
        • 其实有。它被称为console_test_runner。虽然这与 OP 问题无关,因为他已经有一个主要的。
        • 他们将其记录为被称为 boost_test_runner 但是的,它被称为 console_test_runner。我个人正在尝试研究如何将它集成到对象中,并且能够按照我的意愿运行测试,而不是通过 main 运行。
        【解决方案5】:

        试试我写的这个脚本,给定程序名称和类列表,将为每个类/模块生成makefile、项目骨架和测试套件骨架。它还进行了所有设置,以便每个类的测试套件可以单独运行,也可以作为一体化全局套件的一部分运行。

        它的电话是 makeSimple,可以在 sourceforge 上找到。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2010-10-07
          • 2013-04-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多