代码之家  ›  专栏  ›  技术社区  ›  Steve314

如何使我的单元测试适应cmake和ctest?

  •  20
  • Steve314  · 技术社区  · 14 年前

    问题是我正在改用cmake。使用cmake流意味着使用源代码外的构建,这意味着将结果转储到共享的源代码/构建文件夹中并随源代码一起对其进行版本控制的便利性实际上不起作用。

    喜欢

    这是可能的,还是我应该采取完全不同的方法?

    显然,我 忽略ctest,把我一直做的事情改编成源代码外的构建。例如,我可以在所有构建都存在的地方对我的文件夹进行版本设置(当然可以自由使用'ignore'。这正常吗?可能不会,因为每个构建最终都会有一个单独的预期结果副本。

    另外,对于使用cmake/ctest进行单元测试的推荐方法,我们也非常感激。我在cmake上浪费了不少时间,不是因为它不好,而是因为我不知道如何最好地使用它。

    bool Check_Results (std::ostream              &p_Stream  ,
                        const char                *p_Title   ,
                        const char               **p_Expected,
                        const std::ostringstream  &p_Actual   )
    {
      std::ostringstream l_Expected_Stream;
    
      while (*p_Expected != 0)
      {
        l_Expected_Stream << (*p_Expected) << std::endl;
        p_Expected++;
      }
    
      std::string l_Expected (l_Expected_Stream.str ());
      std::string l_Actual   (p_Actual.str ());
    
      bool l_Pass = (l_Actual == l_Expected);
    
      p_Stream << "Test: " << p_Title << " : ";
    
      if (l_Pass)
      {
        p_Stream << "Pass" << std::endl;
      }
      else
      {
        p_Stream << "*** FAIL ***" << std::endl;
        p_Stream << "===============================================================================" << std::endl;
        p_Stream << "Expected Results For: " << p_Title << std::endl;
        p_Stream << "-------------------------------------------------------------------------------" << std::endl;
        p_Stream << l_Expected;
        p_Stream << "===============================================================================" << std::endl;
        p_Stream << "Actual Results For: " << p_Title << std::endl;
        p_Stream << "-------------------------------------------------------------------------------" << std::endl;
        p_Stream << l_Actual;
        p_Stream << "===============================================================================" << std::endl;
      }
    
      return l_Pass;
    }
    

    一个典型的单元测试现在看起来像。。。

    bool Test0001 ()
    {
      std::ostringstream l_Actual;
    
      const char* l_Expected [] =
      {
        "Some",
        "Expected",
        "Results",
        0
      };
    
      l_Actual << "Some" << std::endl
               << "Actual" << std::endl
               << "Results" << std::endl;
    
      return Check_Results (std::cout, "0001 - not a sane test", l_Expected, l_Actual);
    }
    

    std::ostream& ,因此它可以转储到实际的结果流。

    1 回复  |  直到 14 年前
        1
  •  19
  •   richq luc    14 年前

    我将使用CMake的独立脚本模式来运行测试并比较输出。通常对于单元测试程序,您可以编写 add_test(testname testexecutable) ,但您可以运行任何命令作为测试。

    如果您编写一个脚本“runtest.cmake”并通过它执行单元测试程序,那么runtest.cmake脚本可以做任何它喜欢的事情,包括使用 cmake -E compare_files 实用程序。在CMakeLists.txt文件中需要以下内容:

    enable_testing()
    add_executable(testprog main.c)
    add_test(NAME runtestprog
        COMMAND ${CMAKE_COMMAND}
        -DTEST_PROG=$<TARGET_FILE:testprog>
        -DSOURCEDIR=${CMAKE_CURRENT_SOURCE_DIR}
        -P ${CMAKE_CURRENT_SOURCE_DIR}/runtest.cmake)
    

    runtest.cmake 可能是:

    execute_process(COMMAND ${TEST_PROG}
                    RESULT_VARIABLE HAD_ERROR)
    if(HAD_ERROR)
        message(FATAL_ERROR "Test failed")
    endif()
    
    execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files
        output.txt ${SOURCEDIR}/expected.txt
        RESULT_VARIABLE DIFFERENT)
    if(DIFFERENT)
        message(FATAL_ERROR "Test failed - files differ")
    endif()
    

    第一个 execute_process 执行\u进程 有效运行 cmake -E compare_files output.txt expected.txt

    但这不能打印出差异;CMake中没有隐藏完整的“diff”实现。目前,您使用Subversion查看哪些行已更改,因此一个明显的解决方案是将最后一部分更改为:

    if(DIFFERENT)
        configure_file(output.txt ${SOURCEDIR}/expected.txt COPYONLY)
        execute_process(COMMAND svn diff ${SOURCEDIR}/expected.txt)
        message(FATAL_ERROR "Test failed - files differ")
    endif()