【问题标题】:c++ Using boost testc++使用boost测试
【发布时间】:2011-08-09 02:06:18
【问题描述】:

如何将以下代码转换为使用 boost 单元测试框架:

#include <iostream>
#include <fstream>

#include "graph.hh"

int main(int argc, char **argv) {
  const char* ifile = argv[1];

  Graph gp;
  gp.read_xml(ifile);

  std::cout << "Checking number of nodes and edges..."  << std::endl;
  int nodes_expected = 16;
  if(nodes_expected != gp.nodes()) {
    std::cout << "Test Failed." << std::endl;
    std::cout << "Expected: " << nodes_expected << std::endl;
    std::cout << "Result: " << gp.nodes() << std::endl;
  }
  int edges_expected = 15;
  if(edges_expected != gp.edges()) {
    std::cout << "Test Failed." << std::endl;
    std::cout << "Expected: " << edges_expected << std::endl;
    std::cout << "Result: " << gp.edges() << std::endl;
  }
  return 0;
}

我已阅读 (Boost Test) 上的文档,但它没有告诉我如何从命令行获取参数。否则,我可能会使用 BOOST_CHECK_EQUAL。

【问题讨论】:

  • 你的测试不是针对一些特殊的ifile吗?如果是,则以后几乎不需要更改它,您只需硬编码路径即可。
  • 测试应该是完全独立的,如果您需要为其提供参数,情况就不再如此。如果您需要使用不同的文件进行测试,请编写一个方法 doTest(string filename) 并创建几个测试用例,这些用例使用不同的硬编码参数调用此方法。这样,您的代码库或持续集成工具的每个其他用户都将能够运行所有测试,而无需了解如何执行此操作。对我来说,其他所有事情听起来都不像是单元测试。
  • 所有ifiles 都包含一般功能。我正在尝试创建一个测试套件来测试这些功能。其他测试套件更具体,我为这些套件设置了硬编码值。

标签: c++ unit-testing boost


【解决方案1】:
#include <boost/test/included/unit_test.hpp>
#include <fstream>
#include "graph.hh"
using namespace boost::unit_test;

BOOST_AUTO_TEST_CASE( test_num_of_nodes )
{
  Graph gp;
  gp.read_xml( framework::master_test_suite().argv[1] );

  BOOST_MESSAGE( "Checking number of nodes and edges..." );

  BOOST_CHECK_EQUAL(16, gp.nodes());
  BOOST_CHECK_EQUAL(15, gp.edges());
}

【讨论】:

  • 我相信这是我一直在寻找的东西,但是,现在我遇到了 boost 和 tinyxml 的问题。我的 read_xml 函数使用 tinyxml,它似乎正在运行一些 demo.xml 而不是我传递的文件。
【解决方案2】:

在 boost 单元测试套件中,您不会按照您所描述的方式创建一个简单的程序。你不编写测试工具,你编写测试套件,由许多功能(每个测试用例一个)构建而成。这些函数不从命令行获取参数。

您编写的测试用例函数将是以下之一:

  • 空函数(无参数)
  • 一元函数(一个参数)
  • 针对模板类构建(以提供模板参数)

因此,您需要从单独的硬编码文件路径解析参数(将参数写入第二个文件,而不是在命令行上传递它们),然后将它们传递给一元函数测试用例,或者干脆放弃并将文件路径硬编码到测试套件,可能每个测试用例(函数)一个文件。

单元测试套件以这种方式设计,以便它们可以在标准测试运行程序或任意运行程序中运行,这可能会采用自己的命令行参数,并且需要特别注意支持自定义命令行参数。

测试运行器为您提供了很多可插拔的灵活性以满足您未来的需求(标准化测试运行、过滤、日志记录等),但您必须放弃一些类似程序的灵活性才能实现。

【讨论】:

    【解决方案3】:

    我认为最好的解决方案是将 ifile 嵌入 xxd 之类的程序中(查看 -include 选项),请参阅 http://linuxcommand.org/man_pages/xxd1.html

    这将为您提供一个包含 char 数组的文件,您可以在其中 #include 。

    【讨论】:

    • ifile?为什么包含字符数组有帮助?
    • @phresnel 这将避免在运行时加载文件的整个问题。这也将使测试更加独立。
    • 我明白了;你指的是一个变量名。如果您引用代码,最好使用this style ;)(已删除反对票)
    【解决方案4】:

    现在您可以使用在 Boost::test 中添加的自定义命令行参数,例如

    #define BOOST_TEST_MODULE runtime_configuration1
    #include <boost/test/included/unit_test.hpp>
    using namespace boost::unit_test;
    
    BOOST_AUTO_TEST_CASE(test_accessing_command_line)
    {
        BOOST_TEST_REQUIRE( framework::master_test_suite().argc == 3 );
        BOOST_TEST( framework::master_test_suite().argv[1] == "--specific-param" );
        BOOST_TEST( framework::master_test_suite().argv[2] == "'additional value with quotes'" );
        BOOST_TEST_MESSAGE( "'argv[0]' contains " << framework::master_test_suite().argv[0] );
    }
    

    来自https://www.boost.org/doc/libs/1_70_0/libs/test/doc/html/boost_test/runtime_config/custom_command_line_arguments.html

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-23
      • 2011-06-21
      • 2012-04-10
      • 1970-01-01
      • 2019-06-14
      • 1970-01-01
      相关资源
      最近更新 更多