2011-11-17 45 views
0

我正在寻找添加一些测试到我的应用程序,但我不知道如何做到这一点以及需要什么。我已经能够通过创建测试本身来运行基本测试,但是我不能通过将其添加到项目来执行测试。如果我为测试创建了自己的项目,那么这些测试是有效的。在现有项目中创建CPPUnit测试需要什么.cpp和.h文件?

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; 
} 

回答

2

它稍微复杂上手。我用过的最好的方法是建立两个项目之间的关系,最初的真实项目(我称之为RealProject)和一个测试项目(我将称之为一个TestProject)。你的真实代码将继续存在在你的RealProject.vcproj中,但你需要添加第二个项目来存放你的测试代码。

打开包含RealProject的解决方案文件。在您的解决方案中创建一个新项目,并将其命名为TestProject。在测试项目中,您将添加CppUnit测试代码和主函数(如上所述)。如果你现在建立它,它会失败。添加将使其链接的所需属性。打开TestProject属性,并在链接器/输入屏幕中编辑其他依赖项字段。从CppUnit添加适当的.LIB文件(如TestRunner.lib)在继续之前,请在构建之上获取示例代码并正确链接。小步骤思考。

现在,再次打开TestProject属性,并在链接器/输入屏幕中编辑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中,并会自动管理所有的簿记和参考资料。任何使测试更容易的方法都会提高开发人员实际使用它的几率。

相关问题