Separate test cases across multiple files in google test
I'm new in google test C++ framework. It's quite开发者_如何学Python easy to use but I'm wondering how to separate the cases into multiple test files. What is the best way?
Include the .cpp files directly is an option. Using a header seems that does nothing...
Any help is welcome
Create one file that contains just the main to run the tests.
// AllTests.cpp
#include "gtest/gtest.h"
int main(int argc, char **argv)
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Then put the tests into other files. You can put as many tests as you like in a file. Creating one file per class or per source file can work well.
// SubtractTest.cpp
#include "subtract.h"
#include "gtest/gtest.h"
TEST(SubtractTest, SubtractTwoNumbers)
{
EXPECT_EQ(5, subtract(6, 1));
}
This does require that all tests can share the same main. If you have to do something special there, you will have to have multiple build targets.
Not looking for credits or points. I'm new to stackoverflow and don't have the the reputation to add comments. @jkoendev's answer despite being technically correct makes an incorrect statement "I think the main missing point in the other answer is that you need to #include the test files." Not true, you just need to link all the CPP files together.
For example in CMAKE
add_executable(${PROJECT_NAME}
${sources}
${headers})
along with a
file(GLOB_RECURSE sources
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
links all the cpp files. You don't need to include any of the test files in the main file.
I think the main missing point in the other answer is that you need to #include
the test files.
Here is my way to split the tests:
- Put the tests in .h files potentially with header guards, although not needed if you take care.
- Have one main program as defined below that includes the test headers
- A Makefile that compiles + links the main test program.
Do not use the same name for a test twice across all files!
// main_test.cc
#include <gtest/gtest.h>
#include "test_a.h"
#include "test_b.h"
#include "test_c.h"
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
Use the Makefile from googletest and add the rules:
# compiles main test program
main_test.o : main_test.cc test_a.h test_b.h test_c.h $(GTEST_HEADERS)
$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $< -o $@
# links test program
main_test : main_test.o
$(CXX) $(LDFLAGS) -L$(GTEST_LIB_DIR) $^ -lgtest_main -lpthread -o $@
I use a naming convention to order the tests by alphabetic letters:
// test_a.h
#include "some_class.h"
TEST(SomeClass, aName)
{
library::SomeClass a("v", {5,4});
EXPECT_EQ(a.name(), "v");
}
TEST(SomeClass, bSize)
{
library::SomeClass a("v", {5,4});
EXPECT_EQ(a.size(0), 5);
EXPECT_EQ(a.size(1), 4);
}
Then you can run individual tests with
./main_test --gtest_filter=SomeClass.a*
I have faced same problem recently.
I archived my test_cases.o
and main.o
into static library (test_main.a
), then link them with other libraries to final executable.
I notice that it can't find the test cases if I link test_main.a
.
g++ -o test test_main.a -lgtest -lpthread -lXXX
However, if I link the objects separately, it works!
g++ -o test test_cases.o main.o -lgtest -lpthread -lXXX
And I have found the answer in this post Why create a .a file from .o for static linking?
There is one important difference in the final link step. Any object files that you linked will be included in the final program. Object files that are in libraries are only included if they help resolve any undefined symbols in other object files. If they don't, they won't be linked into the final executable.
I suspected it is related to the design of Google Test.
The RUN_ALL_TESTS()
macro run all instances of test class dynamically, which means it got the test cases during run time.
As a result, it's not necessary to link instances of test class, so the linker won't link test_case.o
.
To add to @jkoendev, you can include all header files in one go by generating a single file with all the unit test files. If you isolate your unit test files under a test_cases
directory, you can do this:
// CMakeLists.txt
file(GLOB_RECURSE headers
${CMAKE_CURRENT_SOURCE_DIR}/test_cases/*.h)
set(testcases testcases.hpp)
file(TOUCH ${testcases})
file(WRITE ${testcases} "")
foreach(file IN LISTS headers)
file(APPEND ${testcases} "#include \"${file}\"\n")
endforeach()
Then just include the generated file in main_test.cc
// main_test.cc
#include <gtest/gtest.h>
#include "testcases.hpp"
...
This, of course, runs the responsibility of keeping the test_cases
clean and without conflicting files, along with handling an auto generated file that could potentially cause debugging pains.
精彩评论