在现有项目中创建CPPUnit测试需要什么.cpp和.h文件?

时间:2011-11-17 09:29:34

标签: c++ visual-studio unit-testing visual-c++ cppunit

我想在我的应用程序中添加一些测试但是我不知道如何做到这一点以及需要什么。我只能通过创建测试本身来运行基本测试,但我不能通过将其添加到项目中来实现。如果我创建了自己的测试项目,那么这些测试是有效的。

Test1.h

#pragma once
#include <C:\cppunit-1.12.1\cppunit-1.12.1\include\cppunit\extensions\HelperMacros.h>
class Test1 : public CPPUNIT_NS::TestCase
{
        CPPUNIT_TEST_SUITE(Test1);
        CPPUNIT_TEST(testStringAssert);
        CPPUNIT_TEST_SUITE_END();

public:

    Test1(void);
    ~Test1(void);

    void testStringAssert ();
};

Test1.cpp

#include "Test1.h"
#include "string"

CPPUNIT_TEST_SUITE_REGISTRATION(Test1);

Test1::Test1(void)
{
}

Test1::~Test1(void)
{
}
void Test1::testStringAssert(){
    std::string s1 = "1234567";
    std::string s2 = "1234567";
    CPPUNIT_ASSERT_EQUAL(s1, s2);

}

CPPUnitMain.cpp(取自CPPUnit示例文件夹)

#include <cppunit/CompilerOutputter.h>
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TestRunner.h>
#include <cppunit/TextTestProgressListener.h>
#include <cppunit/BriefTestProgressListener.h>
#include <cppunit/XmlOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <stdexcept>
#include <fstream>


int 
main( int argc, char* argv[] )
{
  // Retreive test path from command line first argument. Default to "" which resolve
  // to the top level suite.
  std::string testPath = (argc > 1) ? std::string(argv[1]) : std::string("");

  // Create the event manager and test controller
  CPPUNIT_NS::TestResult controller;

  // Add a listener that colllects test result
  CPPUNIT_NS::TestResultCollector result;
  controller.addListener( &result );        

  // Add a listener that print dots as test run.
#ifdef WIN32
  CPPUNIT_NS::TextTestProgressListener progress;
#else
  CPPUNIT_NS::BriefTestProgressListener progress;
#endif
  controller.addListener( &progress );      

  // Add the top suite to the test runner
  CPPUNIT_NS::TestRunner runner;
  runner.addTest( CPPUNIT_NS::TestFactoryRegistry::getRegistry().makeTest() );   
  try
  {
    CPPUNIT_NS::stdCOut() << "Running "  <<  testPath;
    runner.run( controller, testPath );

    CPPUNIT_NS::stdCOut() << "\n";

    // Print test in a compiler compatible format.
    CPPUNIT_NS::CompilerOutputter outputter( &result, CPPUNIT_NS::stdCOut() );
    outputter.write(); 

// Uncomment this for XML output
    std::ofstream file( "tests.xml" );
    CPPUNIT_NS::XmlOutputter xml( &result, file );
    xml.setStyleSheet( "report.xsl" );
    xml.write();
    file.close();
  }
  catch ( std::invalid_argument &e )  // Test path not resolved
  {
    CPPUNIT_NS::stdCOut()  <<  "\n"  
                            <<  "ERROR: "  <<  e.what()
                            << "\n";
    return 0;
  }

  return result.wasSuccessful() ? 0 : 1;
}

1 个答案:

答案 0 :(得分:2)

开始时有点复杂。我用过的最好的方法是建立两个项目之间的关系,原始的真实项目(我称之为RealProject)和测试项目(我将这个称为TestProject。)你的真实代码将继续存在在您的RealProject.vcproj中,但您需要添加第二个项目来存放您的测试代码。

打开包含RealProject的解决方案文件。在解决方案中创建一个新项目,并将其命名为TestProject。在测试项目中,您将添加CppUnit测试代码和主要功能(如上所述)。如果你现在建立它,它应该失败。添加将要链接的所需属性。打开TestProject属性,在Linker / Input屏幕中,编辑Additional Dependencies字段。从CppUnit添加适当的.LIB文件(如TestRunner.lib)在继续之前,获取上面构建和链接的示例代码。仔细考虑一下。

现在,再次打开TestProject属性,在Linker / Input屏幕中编辑Additional Dependencies值。在此列表中,添加包含要测试的代码的实际项目的目标文件。例如,如果RealProject有一个包含你要测试的方法的Foo.cpp,你可以添加$(SolutionDir)RealProject \ Debug \ obj \ Foo.obj这当然是假设这是你的目标文件的正确相对路径。对于不同的构建,您可能有不同的路径,例如release,x64或其他。首先使用一个版本,然后应用您新发现的知识,使其他版本正确构建。

现在将一个测试套件类添加到TestProject(称之为FooTest.cpp)以测试Foo.cpp模块中的方法。确保它构建,链接和运行。您现在正在对第一个代码进行单元测试!恭喜!

您可能希望在源代码更改时重建测试。右键单击TestProject项目文件夹,然后选择Project Dependencies。在RealProject前面添加一个复选标记。现在,如果您选择TestProject并构建它,它将确保首先构建RealProject。

如果您想要执行此操作并忘记它,可以使用通配符整个目标文件夹,如下所示:

$(SolutionDir)RealProject\Debug\obj\*.obj

这样,您添加到RealProject的每个模块都可以编写单元测试而不会弄乱项目设置。

这样做的一个优点是它始终在测试您的实际的,事实的,已编译的代码。编译器没有“假装”,没有为了测试目的而对源代码进行第二次编译,这是对您的实时代码的有效测试。另一个优点是,通过将测试代码保存在单独的项目中,您不会意外地发送单元测试。它们是在一个完全独立的文件夹中编译的,您不会将其打包并交付给您的客户。

老实说,我希望它比这更容易。我希望它内置于IDE中,并自动管理所有簿记和参考资料。任何使测试更容易的事情都会增加开发人员实际使用它的机会。