I'm testing a huge piece of software and would like to use Catch for this task. I'm using the "single include" version 1.9, integrating it in Visual Studio 2012 update 4 and using C++04 standard.
As you will see below, I use three ".cpp" files. Each of them reference:
#define Assert(x) REQUIRE(x)
);Assert(2 == getNumber())
).More details on the files content below.
This configuration works, but one of the test file is growing bigger by the day and I would like to split it in 3, or more. Now, say that I do the following:
test.cpp
and move it in a new file test2.cpp
;this error pops up when I run the tests:
=============================
No tests ran
error: TEST_CASE( "test 2" ) already defined.
First seen at c:\tests\catchtest2\catchtest2\test2.cpp(3)
Redefined at c:\tests\catchtest2\catchtest2\test2.cpp(3)
where test2.cpp
is the new file.
If I move the content back to test.cpp
it all works, but working with tests thousands of lines long is almost harder than working on the project itself, and the dimension could grow 3, 4 times bigger still.
Is there a way to split the tests in multiple files?
-- NOTES --
I reckon including Catch in a header and using the including header instead of catch.cpp
directly is not a good idea, but I successfully used this configuration with 3 (exactly 3) included .cpp
test files, and am unable to use this with 4 files.
I remember reading that it was somehow related to the line at which the components were defined, but I can also move the code so that the test cases are defined at different lines and the behaviour doesn't change.
I also tried to "clean and rebuild", because it may well be that dirty data is kept in the compiler / linker's caches, but to no avail.
I couldn't create an actual MWE right now, so I gave you a sketch of the test setup as accurate as I thought it could be needed. I'm more than willing to provide additional details or try and build an actual MWE and share it.
Any idea is appreciated!
My "working" code looks like this:
main.cpp
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
#include "test1.cpp"
#include "test2.cpp"
#include "test3.cpp"
int main( int argc, char* argv[] )
{
cleanDir("c:\\temp");
init (argv);
int result = Catch::Session().run( argc, argv );
return ( result < 0xff ? result : 0xff );
}
test1.cpp
#include "unitTestSuite.h"
#include "utils.h"
#include "systemundertest.h"
using namespace system::under::test;
my_test_case("test 1") {
my_section("does X") {
// tests...
}
}
my_test_case("test 2") {
my_section("does Y") {
// tests...
}
}
unitTestSuite.h
#ifndef UNIT_TEST_SUITE
#define UNIT_TEST_SUITE 1
#include "catch.hpp"
#define my_test_case(x) TEST_CASE("Testing: " x)
... // here is also a namespace with some unit test specific utils
#endif
utils.h
#ifndef _UTILS_
#define _UTILS_
// some global variables declared here and defined in utils.cpp
// template functions defined in the header
// non-template functions defined in utils.cpp
// a test generation namespace with some template functions and some non-template functions defined in utils.cpp
#endif
After the "split":
test1.cpp
#include "unitTestSuite.h"
#include "utils.h"
#include "systemundertest.h"
using namespace system::under::test;
my_test_case("test 1") {
my_section("does X") {
// tests...
}
}
test1.2.cpp
#include "unitTestSuite.h"
#include "utils.h"
#include "systemundertest.h"
using namespace system::under::test;
my_test_case("test 2") {
my_section("does Y") {
// tests...
}
}
main.cpp
#define CATCH_CONFIG_RUNNER
#include "catch.hpp"
#include "test1.cpp"
#include "test1.2.cpp"
#include "test2.cpp"
#include "test3.cpp"
int main( int argc, char* argv[] )
{
cleanDir("c:\\temp");
init (argv);
int result = Catch::Session().run( argc, argv );
return ( result < 0xff ? result : 0xff );
}
program output:
=============================
No tests ran
error: TEST_CASE( "test 2" ) already defined.
First seen at c:\tests\catchtest2\catchtest2\test1.2.cpp(3)
Redefined at c:\tests\catchtest2\catchtest2\test1.2.cpp(3)
Don’t include the cpp files, just add them to the project. Your main.cpp file only needs the first two lines (a define and an include).