谷歌测试中跨多个文件的单独测试用例

发布于 2024-12-04 16:21:14 字数 116 浏览 1 评论 0原文

我是谷歌测试 C++ 框架的新手。它很容易使用,但我想知道如何将案例分成多个测试文件。最好的方法是什么?

直接包含 .cpp 文件是一个选项。使用标头似乎没有任何作用...

欢迎任何帮助

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

半寸时光 2024-12-11 16:21:14

创建一个仅包含运行测试的主文件的文件。

// AllTests.cpp
#include "gtest/gtest.h"

int main(int argc, char **argv)
{
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
}

然后将测试放入其他文件中。您可以在一个文件中放置任意数量的测试。为每个类或每个源文件创建一个文件可以很好地工作。

// SubtractTest.cpp
#include "subtract.h"
#include "gtest/gtest.h"

TEST(SubtractTest, SubtractTwoNumbers)
{
    EXPECT_EQ(5, subtract(6, 1));
}

这确实要求所有测试可以共享同一个 main。如果你必须在那里做一些特殊的事情,你将必须有多个构建目标。

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.

青衫负雪 2024-12-11 16:21:14

不寻找学分或积分。我是 stackoverflow 的新手,没有资格添加评论。 @jkoendev 的答案尽管在技术上是正确的,但却做出了错误的陈述“我认为另一个答案中的主要缺失点是你需要 #include 测试文件。”不正确,您只需将所有 CPP 文件链接在一起即可。

例如,在 CMAKE 中,

add_executable(${PROJECT_NAME} 
    ${sources}
    ${headers})

带有

file(GLOB_RECURSE sources
    ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)

所有 cpp 文件的链接。
您不需要在主文件中包含任何测试文件。

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 2024-12-11 16:21:14

我认为另一个答案中的主要缺失点是您需要 #include 测试文件。

这是我分割测试的方法:

  1. 将测试放在 .h 文件中,可能带有标头保护,但如果您小心的话,则不需要。
  2. 有一个如下定义的主程序,其中包括测试标头
  3. 一个编译+链接主测试程序的 Makefile。

不要在所有文件中使用相同的名称两次进行测试!

// 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();
}

使用 googletest 中的 Makefile 并添加规则:

#  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 
lt; -o $@
# links test program
main_test : main_test.o
    $(CXX) $(LDFLAGS) -L$(GTEST_LIB_DIR) $^ -lgtest_main -lpthread -o $@

我使用命名约定按字母顺序对测试进行排序:

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

然后您可以使用以下命令运行单独的测试

./main_test --gtest_filter=SomeClass.a*

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 
lt; -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*
傲影 2024-12-11 16:21:14

我最近遇到了同样的问题。

我将 test_cases.omain.o 归档到静态库 (test_main.a) 中,然后将它们与其他库链接到最终的可执行文件。

我注意到,如果我链接 test_main.a,它就找不到测试用例。

g++ -o test test_main.a -lgtest -lpthread -lXXX

但是,如果我单独链接对象,它就可以工作!

g++ -o test test_cases.o main.o -lgtest -lpthread -lXXX

我在这篇文章中找到了答案 为什么要创建.a来自 .o 的文件用于静态链接?

最后的链接步骤有一个重要的区别。您链接的任何目标文件都将包含在最终程序中。仅当库中的对象文件有助于解析其他对象文件中的任何未定义符号时,才会包含它们。如果不这样做,它们将不会链接到最终的可执行文件中。

我怀疑这与Google Test的设计有关。

RUN_ALL_TESTS() 宏动态运行测试类的所有实例,这意味着它在运行时期间获取测试用例。

因此,不需要链接测试类的实例,因此链接器不会链接 test_case.o

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.

鹊巢 2024-12-11 16:21:14

要添加到 @jkoendev,您可以通过生成包含所有单元测试文件的单个文件来一次性包含所有头文件。如果您将单元测试文件隔离在 test_cases 目录下,则可以执行以下操作:

// 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()

然后只需将生成的文件包含在 main_test.cc

// main_test.cc
#include <gtest/gtest.h>

#include "testcases.hpp"
...

这当然会运行以下责任:保持 test_cases 干净并且没有冲突的文件,同时处理可能导致调试困难的自动生成的文件。

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.

月朦胧 2024-12-11 16:21:14

假设您有一个名为 MyProject 的项目。进一步假设在此项目中,您有两个要测试的不同文件 A.cpp 和 B.cpp(及其相应的标头 A.hpp 和 B.hpp)。

为了保持简洁,需要有两个单独的文件 A.cc 来测试 A.cpp 和 B.cc 来测试 B.cpp。

您需要设置 CMakeLists.txt(如下所示)才能将所有这些编译为单个测试可执行文件。然后,Google 测试将从该单个可执行文件中发现测试。

下面 CMakeLists.txt 代码片段中的注释将解释这一切是如何完成的:

#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)

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)
惯饮孤独 2024-12-11 16:21:14

如果您使用的方法很简单:

  1. 使用测试文件创建可执行文件
  2. 链接 GoogleTest 和其他库等。
  3. 包括任何目录
  4. 在 CMakeLists.txt 中使用 gtest_discover_tests(//NameOfExecutable) 发现测试
  5. 现在执行以下操作有了所有测试文件,你就完成了!在构建文件中运行 ctest,所有测试都应该运行。

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.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文