Googletest Eclipse C ++:如何让测试和生产都可执行?

时间:2015-07-09 17:58:33

标签: c++ eclipse googletest test-runner

我在Eclipse中有一个关于Googletest的基本问题。

我正在使用test-runner插件来运行Googletests。 但我需要指定一个运行单元测试的二进制文件(当然这是有意义的。)

问题在于,在我的项目中,我现在有两个主要功能,一个用于运行实际程序,另一个用于

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

运行谷歌测试。

每次我想跑一个我都会评论另一个,这当然是愚蠢的。

但是你用什么做法来处理这种情况呢?

2 个答案:

答案 0 :(得分:2)

Googletest C ++是一个单元测试框架。这意味着它用于测试 C ++ API的实现。它不用于测试程序

出于实际目的,您可以在C ++头文件中获得C ++ API。该 这种API的实现可能是:

  • 只是头文件本身。 (实施完全是内联的)
  • 头文件加上单个C ++源文件
  • 头文件加上一堆C ++源文件

总而言之,C ++ API的实现是一个头文件加 0个或更多源文件。

假设您的程序my_prog调用您或您的团队开发的API 用于管理小玩意儿。实现类似于:

gizmo.h
[gizmo_0.cpp,...gizmo_N.cpp]

其中[...]表示可选...

也许my_prog依赖于您或您的团队负责的其他API, 但我们只会坚持一个。 my_prog使用Gizmo API: -

  • 在某些源文件中使用#include "gizmo.h"
  • 编译[gizmo_0.cpp,...gizmo_N.cpp]源文件(如果有)。
  • 链接[gizmo_0.o,...gizmo_N.o]目标文件(如果有)。

gizmo_0.obj,等等,如果你在Windows上)

假设使用Googletest测试您的Gizmo API实现 确认此实施是否正确,与my_prog无关 或任何其他依赖它来管理小玩意的程序。所以结合 在 my_prog的实现中实现的单元测试是错误的: -

也许你的同事写了另一个也需要管理小玩意的程序 有了这个实现。也许写另一个。是谁写的 其他程序应该重复整合Gizmo单元测试的过程 进入它 - 同样的?不同的? - 并有条件地制定计划 编译为Gizmo测试工具或者它应该在现实生活中应该做什么?

你怎么知道Gizmo的实现并没有被某种方式纠缠在一起 my_prog独有的功能,或者某些功能的实现 my_prog以相同方式使用的其他API - 以便在您或某人时使用 否则尝试在另一个程序中重用它,它会中断或行为错误?

没有依赖于这个Gizmo实现的程序是放置的地方 它的单元测试。使my_prog有条件地编译不同的main函数,以便它可以 double作为你的Gizmo库的单元测试线束类似于切割一个洞 你的牛仔裤的裤裆让你的头穿过。

您应该对Gizmo库进行单元测试的方法是编写 的程序 这个库的测试工具,没有别的。这个程序,如gizmo_test,将会 使用Gizmo API的方式与任何其他程序使用它的方式相同,但是 仅用于测试Gizmo库。 gizmo_test所做的就是执行测试 通过调用它的API来调用Gizmo库。

作为第一个近似值,gizmo_test的GoogleTest配方是:

写一个头文件gizmo_test.h

其中

#include "gizmo.h"

其中

#include <gtest/gtest.h>

然后在其中写下您的Googletest测试用例

编写以下源文件gizmo_test.cpp

#include "gizmo_test.h"

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

在Eclipse或您使用的任何开发环境或构建系统中创建项目gizmo_test - 通过以下方式构建gizmo_test可执行文件:

  • 编译源文件gizmo_test.cpp + [gizmo_0.cpp,...gizmo_N.cpp]
  • 关联生成的目标文件gizmo_test.o + [gizmo_0.o,...gizmo_N.o],加上libgtest以及您的Gizmo库所依赖的任何其他库

您有两个项目。制作my_prog的制作人和制作gizmo_test的制作者。在您的开发环境或 构建系统,使my_prog的构建取决于gizmo_test的构建,以便在您更改任何影响的内容时 gizmo库和重建my_proggizmo_test首先重建。

这是第一次近似。你有没有注意到我开始谈论你的Gizmo ?这是什么 你有(或应该有)。在C ++和编程中,API的实现称为

也许你也注意到gizmo_test的食谱中有些脆弱,不便和浪费。您有相同的Gizmo源文件集 两个项目中[gizmo_0.cpp,...gizmo_N.cpp]。因此,您可以在两个项目中以不同方式编辑,编译和链接它们。他们将在两个项目中编译,或者以不同方式编译 这是错误,或相同,这是毫无意义的。

当然,如果这组源文件为空 - Gizmo库只是gizmo.h - 没有这样的问题。但如果它不是空的, 有。。

如您所知,在C ++中,我们不会通过在每个使用它的程序中构建源文件来使用库 - 除非它是一个仅限标头的库。 库本身构建到对象库(静态或动态)中,并且要使用它,程序只包含库“s”。 头文件和链接对象库。

程序应该如何使用你的Gizmo库。所以到最后的近似值: -

  • 制作一个项目libgizmo,用于构建Gizmo对象库(静态或动态,如您所见)。
  • 如上所述制作项目gizmo_test,但不是编译和链接[gizmo_0.cpp,...gizmo_N.cpp],而是链接libgizmo,并制作此项目 取决于libgizmo项目。
  • 现在制作一个项目my_prog,但不要编译和链接[gizmo_0.cpp,...gizmo_N.cpp],只需链接libgizmo,然后制作此项目 取决于gizmo_test项目。

因此,在构建使用Gizmo库的第一个程序时,您有三个项目。每个使用Gizmo库的后续程序都需要一个 更多项目,如my_prog项目。

Googletest旨在测试C ++ ,这就是您应该如何使用它。

现在,我对您的计划或您目前在项目中部署Googletest测试用例的方式一无所知。也许没有任何明确定义的API实现 那些测试用例应该运用,你可以将其分解为独立的库。可能这可能是因为你的程序非常简单 对其组件进行单元测试&#34;是不适用的,只要编写程序的黑盒测试就更明智了。更可能是因为你到目前为止失败了 设计一个能够进行单元测试的程序架构。如果您找到的是,则需要修复,然后以正确的方式应用Googletest。值得的 努力。

如果需要指出,单元测试不是程序测试,所以以及对程序所依赖的任何库进行单元测试,如果它们是您的责任,那么需要对您的程序进行黑盒测试。

答案 1 :(得分:0)

确实是一个有效的问题。我相信 Mike Kinghan 的详细回复解释了您应该如何使用 google-test,但没有什么是一成不变的,最后,您可以随心所欲地使用 google-test。

所以,既然我也遇到过类似的情况,我做的就比较简单了。

我修改了生产文件源代码,以便主函数从这里改变:

void main(void)

为此:

#ifndef TDD_ENABLED // TDD_ENABLED is defined only in the unit test project
    void main(void)
#else
    void main_app(void)
#endif

这样当你运行单元测试时,原来的'main'函数被转换为'main_app',你避免与google test的'main'发生冲突。当您运行原始生产代码项目时,'main_app' 函数应再次命名为 'main'。因此,从技术上讲,从您的生产代码的角度来看,没有任何变化。