Separate test cases across multiple files in google test
Asked Answered
H

7

37

I'm new in google test C++ framework. It's quite 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

Hanzelin answered 16/9, 2011 at 11:24 Comment(0)
D
44

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.

Dasher answered 20/2, 2012 at 22:34 Comment(3)
If you're working with google-test in Xcode (possibly with Objective-C++ as well) and your tests are not running after splitting your test suite in different .cpp files, go to your google-test powered C++ target in Xcode and activate Perform Single-Object prelink in the build options.Brufsky
Doesn't work for me. When running the executable Alltests SubtractTest is not invoked. Is SubtractTest.cpp being built as an executable or library?Rarefy
the missing information is how to build it to include these separate files?Siamese
H
8

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.

Hazlett answered 6/6, 2020 at 20:45 Comment(0)
C
5

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:

  1. Put the tests in .h files potentially with header guards, although not needed if you take care.
  2. Have one main program as defined below that includes the test headers
  3. 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*
Calciferol answered 19/3, 2019 at 11:14 Comment(0)
P
2

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.

Pricilla answered 11/7, 2019 at 3:14 Comment(0)
L
0

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.

Lentissimo answered 20/10, 2022 at 21:23 Comment(0)
R
0

Assume you have a project called MyProject. Further assume that in this project, you have two different files A.cpp and B.cpp (with their corresponding headers A.hpp and B.hpp) that you want to test.

To keep things clean, want to have two separate files A.cc to test A.cpp and B.cc to test B.cpp.

You need to setup your CMakeLists.txt (as shown below) to be able to compile all these into a single test executable. Google tests will then discover tests from that single executable.

The comments in the code snippet from CMakeLists.txt below will explain how all this is accomplished:

#Create variables that reference all the files relevant to A
set(A_SOURCES A.cpp ATest.cc)
set(A_HEADERS A.hpp)

#Create variables that reference all the files relevant to B    
set(B_SOURCES B.cpp BTest.cc)
set(B_HEADERS B.hpp)

#Create the the single test executable MyProjectTests that will use
# all the files referenced from the variables above
add_executable(
  MyProjectTests ${A_SOURCES} ${A_HEADERS} ${B_SOURCES} ${B_HEADERS}
)

#Link google test libraries into that executable MyProjectTests
target_link_libraries(
  MyProjectTests
  GTest::gtest_main
)

include(GoogleTest)
#Tell gtest to look for tests in the MyProjectTests executable
gtest_discover_tests(MyProjectTests)
Royall answered 3/7, 2023 at 23:15 Comment(0)
B
0

If you are using its simple as:

  1. Creating an excutable with your test file
  2. Linking GoogleTest and your other libraries etc.
  3. Including any directories
  4. Discovering the test using gtest_discover_tests(//NameOfExecutable) in your CMakeLists.txt
  5. Now do this with all test files and your done! Run ctest in your build file, and all tests should run.
Bad answered 17/9, 2023 at 0:39 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.