简体   繁体   中英

What .cpp and .h files are needed to create CPPUnit tests in an existing project?

I'm looking to add some tests to an application of mine however I do not know how to do this and what is needed. I have been able to run a basic test by just creating the test itself but I cannot do this by adding it to a project. Here is the tests that worked if I created my own project for tests.

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 (taken from the CPPUnit examples folder)

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

It's slightly complicated to get started. The best way that I've used is to establish a relationship between two projects, the original real project (I'll call it RealProject) and a test project (I'll call this one TestProject.) Your real code will continue to live in your RealProject.vcproj, but you need to add the second project to house your test code.

Open the solution file that contains your RealProject. Create a new project in your solution, and name it TestProject. In the test project, you will add your CppUnit test code and your main function (as you have above). If you build it now, it should fail. Add the needed properties that will get it to link. Open the TestProject properties, and in the Linker/Input screen, edit the Additional Dependencies field. Add the appropriate .LIB file from CppUnit (like TestRunner.lib) Get your example code above building and linking correctly before you proceed. Think in small steps.

Now, open the TestProject properties again, and in the Linker/Input screen edit the Additional Dependencies value. In this list, add the object files of the real project that contain the code you want to test. For example, if RealProject has a Foo.cpp containing some methods you want to test, you would add $(SolutionDir)RealProject\\Debug\\obj\\Foo.obj That's assuming that is the correct relative path to your object files, of course. You might have different paths for different builds, such as release, x64, or whatever. Get one version working first, then apply your newfound knowledge to make the other versions build properly.

Now add a test suite class to TestProject (call it FooTest.cpp) to test the methods in your Foo.cpp module. Make sure it builds, links, and runs. You're now unit testing your first code! Congratulations!

You probably want to have the tests rebuilt when the source code changes. Right click on the TestProject project folder and pick Project Dependencies. Add a checkmark in front of RealProject. Now, if you pick TestProject and build it, it will make sure that RealProject is built first.

If you want to do this once and forget about it, you can wildcard the entire object file folder, like this:

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

That way every module you add to RealProject can have a unit test written without messing with Project settings.

One advantage to this is that it's always testing your actual, factual, compiled code. There is no "faking" the compiler out, no second compile of your source code for testing purposes, it's a valid test of your live code. Another advantage is that by keeping the test code in a separate project, you would not accidentally ship your unit tests. They're compiled in a completely separate folder, one that you would not package and deliver to your customers.

I honestly wish it were a lot easier than this. I wish this was built into the IDE, and would automatically manage all the bookkeeping and references and stuff. Anything to make testing easier will improve the chances that developers will actually use it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM