c++ - Google Test Discovery在Mac OS X上两次添加并运行了我所有的测试

标签 c++ macos googletest

我会尽量简短,但要简洁。

我一直在移植我公司使用的Google测试框架(以及一组测试),从Windows到Mac OS。而且,除了由于某种原因在MAC上构建/运行测试外,几乎所有其他功能都可以工作... Google Test两次包含了每个定义的测试。

在MAC上,我的Makefile输出“main_test”,如果我使用--gtest_list_tests选项,可以快速显示该问题,您可以看到我愚蠢的测试列表都被第二次重复了。

$ ./main_test --gtest_list_tests
BEGINNING Google Test!
sman_drift_test.
  slow_forward
  medium_back
  slow_forward
  medium_back
motor_self_test/motor_test.
  self_test/0  # GetParam() = "rev"
  self_test/1  # GetParam() = "fwd"
  self_test/0  # GetParam() = "rev"
  self_test/1  # GetParam() = "fwd"

在Windows上的VS中编译的完全相同的源文件产生了我的“unit_test_d.exe”文件,如果我从“cmd” shell 运行相同的--gtest_list_tests选项,则会得到以下信息:
>unit_test_d.exe --gtest_list_tests
BEGINNING Google Test!
sman_drift_test.
  slow_forward
  medium_back
motor_self_test/motor_test.
  self_test/0  # GetParam() = "rev"
  self_test/1  # GetParam() = "fwd"

我的 Helm 机_test.cpp文件中只有这些测试的一个副本,同样在motor_self_test.cpp文件中也是如此。
TEST_F(sman_drift_test, slow_forward) 
{
     // Do my test stuff...
}

TEST_F(sman_drift_test, medium_back) 
{
     // Do my test stuff...
}

我已经为此困扰了几天...而且我已经消除了很多可能的选择。基本上包括我所有的公司代码。

我最初遵循此Web链接上的MAC设置说明:
http://hack.limbicmedia.ca/installing-google-test/

注意:我应该注意……按照这些说明进行操作时,我确实更改了目录并使用了我们树中已经存在的“gtest”文件(版本列在底部),所以可能我可能弄乱了文件位置,或者在重新编译我们已经下载的源代码时将其作为构建选项,并将这些目录放置在正确的位置。希望不会。我们的原始库与Windows的VS 2015兼容...我使用cmake构建了相同的源文件,并安装了上面链接中列出的步骤。我在/ usr / local / inc和lib中确实有gtest.h和libgtest.a,所以包含路径的东西应该是good(?)。

并按照说明运行示例代码。同样,...我看到相同的问题...注意:我也确实注释掉了“TEST(FactorialTest,Zero)”案例,只是为了验证注释掉1个测试...确实消除了两个实例。它做到了。但是您可以看到...“负”和“正”两个都被添加了两次,以及所有三个“IsPrime()”测试都被添加了。
$ ./sample1 --gtest_list_tests
Running main() from gtest_main.cc
FactorialTest.
  Negative
  Positive
  Negative
  Positive
IsPrimeTest.
  Negative
  Trivial
  Positive
  Negative
  Trivial
  Positive

同样,实际运行测试会导致运行重复测试。样本中有6个测试用例,FactorialTest中有3个,IsPrimeTest中有3个。您可以看到它正在每组两次构建/运行...每组6个,共12个:
$ ./sample1
Running main() from gtest_main.cc
[==========] Running 12 tests from 2 test cases.
[----------] Global test environment set-up.
[----------] 6 tests from FactorialTest
[ RUN      ] FactorialTest.Negative
[       OK ] FactorialTest.Negative (0 ms)
[ RUN      ] FactorialTest.Zero
[       OK ] FactorialTest.Zero (0 ms)
[ RUN      ] FactorialTest.Positive
[       OK ] FactorialTest.Positive (0 ms)
[ RUN      ] FactorialTest.Negative
[       OK ] FactorialTest.Negative (0 ms)
[ RUN      ] FactorialTest.Zero
[       OK ] FactorialTest.Zero (0 ms)
[ RUN      ] FactorialTest.Positive
[       OK ] FactorialTest.Positive (0 ms)
[----------] 6 tests from FactorialTest (0 ms total)

[----------] 6 tests from IsPrimeTest
[ RUN      ] IsPrimeTest.Negative
[       OK ] IsPrimeTest.Negative (0 ms)
[ RUN      ] IsPrimeTest.Trivial
[       OK ] IsPrimeTest.Trivial (0 ms)
[ RUN      ] IsPrimeTest.Positive
[       OK ] IsPrimeTest.Positive (0 ms)
[ RUN      ] IsPrimeTest.Negative
[       OK ] IsPrimeTest.Negative (0 ms)
[ RUN      ] IsPrimeTest.Trivial
[       OK ] IsPrimeTest.Trivial (0 ms)
[ RUN      ] IsPrimeTest.Positive
[       OK ] IsPrimeTest.Positive (0 ms)
[----------] 6 tests from IsPrimeTest (0 ms total)

[----------] Global test environment tear-down
[==========] 12 tests from 2 test cases ran. (0 ms total)
[  PASSED  ] 12 tests.

我对此问题进行了很多研究,并且认为这不是到我自己的库或目标文件的链接问题。

当然,问题可能与Google Test的某些构建选项以及由它创建/安装的库(-lgtest)有关。是否有可能被链接两次(?),或者在Google测试中某处设置了某种定义或参数,提示“两次运行所有测试”?注意:此问题不是“./sample_test --gtest_repeat = 2”选项。这将我重复的测试重复两次,因此它们每次运行4次。

最后,这可能是一个潜在的提示……而我首先是如何摆脱这个兔子洞的……是当我使用完整的代码堆栈时,而不是在连接到的“样本”时……串行端口并维护我的串行句柄结构...如您所见...一旦我使用地址(0x6d009f0)和文件描述符FD [3]设置了指针,我就把它弄丢了...或更可能有一个使用测试的“重复”实例定义的另一个实例(如NULL)。

另外,奇怪的是它在哪里变为NULL ...然后又回到哪里。流程如下所示:
Start Google Test
 - Do Init.  IE: Establish and init Serial port (init, open, config port)
    - Pointer GOOD Addr(0x6d009f0) FD[3]
    - Get Device Serial Number (Works)
 - Begin servo_drift_test
    - Do "SetUpTestCase()" Init Code
       - Set Device Mode to 2, required for this "set" of tests.
       - Pointer GOOD  Addr(0x6d009f0) FD[3]
    - Run First Test Case *** Now I presume this is the "duplicate" case
       - Pointer LOST Addr(0)... NULL (Not initialized)
       - TEST instance ONE FAILS
    - Run Second Test Case *** This appears to have the matching memory space as the original init and setup code!!!
       - Runs a SUCCESSFUL "get_params" command.
       - Pointer GOOD  Addr(0x6d009f0) FD[3]
       - TEST instance TWO PASSED
    - Servo Drift Test "TearDownTestCase()"
       - Nothing To Do Here
 - Complete Test Summary

如您所见,它运行了2个测试用例的实例……尽管在这个非常简单的精简示例中只有1个“测试”。我试图尽力清除它,但仍显示调试打印。 :)

我发现测试用例的“SetUp”只运行一次……并且运行得很好是很奇怪的。但是同一测试的两个实例,显然一个不在同一个内存空间中。这可能是Google测试如何添加“测试”与“测试集”的症状。但是我想这暗示了整个问题。
  $ ./main_test port=/dev/cu.usbserial-FTFMEXDK
unit_test version: 6.00.00
  Set Port String[64]: /dev/cu.usbserial-FTFMEXDK <---
  Global Port String: /dev/cu.usbserial-FTFMEXDK <---
using serial port /dev/cu.usbserial-FTFMEXDK
SUCCESS - GET_PORT_BY_NAME
             PORT - Struct Addr port2print[6d009f0]
                  - Name: /dev/cu.usbserial-FTFMEXDK
                  - Baudrate: -1
                  - Bits: -1
                  - Parity: -1
                  - Stopbits: -1
                  - FD[-1]

SUCCESS - SP_OPEN in Mode[3]
             PORT - Struct Addr port2print[6d009f0]
                  - Name: /dev/cu.usbserial-FTFMEXDK
                  - Baudrate: 9600
                  - Bits: 8
                  - Parity: -1
                  - Stopbits: 1
                  - FD[3]

SUCCESS - SET_BAUDRATE 460800
             PORT - Struct Addr port2print[6d009f0]
                  - Name: /dev/cu.usbserial-FTFMEXDK
                  - Baudrate: 460800
                  - Bits: 8
                  - Parity: 0
                  - Stopbits: 1
                  - FD[3]



  WRITE
    - [29]: sys_config get_smart_sn
  PROXY RECEIVE START
 TOK[19] EXP[19] ==>  0x00000000  1 0 E 2 0 1 1 7 0 6 2 7 0 0 1 4 8 R  
Target ALIVE, unit serial no: '10E20117062700148R'


BEGINNING Google Test!
Note: Google Test filter = *.slow_forward
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from sman_drift_test
             PORT - Struct Addr port2print[6d009f0]
                  - FD[3]
  WRITE
    - [24]: sys_config set_mode  2 
  PROXY RECEIVE START
 TOK[1] EXP[1] ==>  0x00000000   

[ RUN      ] sman_drift_test.slow_forward
             PORT - Struct Addr port2print[0]
                  - NULL PORT Structure!!! 

          ERROR - comm port initialization failed
servo_drift_test.cpp:485: Failure
Failed
UNABLE TO COMMUNICATE WITH DEVICE


[  FAILED  ] sman_drift_test.slow_forward (15013 ms)
[ RUN      ] sman_drift_test.slow_forward
              - PreTestFlags[0x7]
             PORT - Struct Addr port2print[6d009f0]
                  - FD[3]

  WRITE
    - [17]: sman get_params 
  PROXY RECEIVE START
 TOK[13] EXP[13] ==>  0x00000000  1 0 0 -1471 1 0 0 0 0 0 1 75000  

[       OK ] sman_drift_test.slow_forward (29114 ms)
[----------] 2 tests from sman_drift_test (44127 ms total)

[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (45607 ms total)
[  PASSED  ] 1 test.
[  FAILED  ] 1 test, listed below:
[  FAILED  ] sman_drift_test.slow_forward

但是,这是我的Makefile(如果有人愿意看的话)(我在非Windows串行连接代码中使用“libserialport” ...理想情况下,它将在许多平台上构建)。就我所知,Makefile可以运行和构建。我正在使用它来构建,一切正常。注意:在此示例中,我确实更改了“rpclibstuff”的名称,因为实际名称是我们产品的一部分...因此出于安全原因将其隐藏。 :)因此,如果存在与“rpclibstuff”有关的语法错误,则可能仅在此示例中。 :)一种
$ cat Makefile 
# Include directories for rpc .h files
RPCINC=../../../Common/rpc/inc/
RPCSRC=../../../Common/rpc/src/

# Include directory for the "system_mode.h" include
TAINC=../../../Tensioner/application/inc/

# Direcroty path for libserialport
LSDIR=../libserialport/

all: main_test

main_test: rpclibstuff.a 
    g++ -std=c++11 -stdlib=libc++ main.cpp servo_drift_test.cpp motor_test.cpp -lgtest -lpthread -o main_test -I $(RPCINC) -I $(LSDIR) -L. -lrpclibstuff -lserialport

rpclibstuff.a: rpc_util.o rpc_proxy.o rpc_proxy_util.o rpc_dispatch_util.o
    ar rcs librpclibstuff.a rpc_dispatch_util.o rpc_proxy.o rpc_proxy_util.o rpc_util.o


# gcc "-c" option compiles source files without linking.
rpc_util.o: $(RPCSRC)rpc_util.c
    gcc -c $(RPCSRC)rpc_util.c -o rpc_util.o -I $(RPCINC) -I $(TAINC)

rpc_proxy.o: $(RPCSRC)rpc_proxy.c
    gcc -c $(RPCSRC)rpc_proxy.c -o rpc_proxy.o -I $(RPCINC)

rpc_proxy_util.o: $(RPCSRC)rpc_proxy_util.c
    gcc -c $(RPCSRC)rpc_proxy_util.c -o rpc_proxy_util.o -I $(RPCINC)

rpc_dispatch_util.o: $(RPCSRC)rpc_dispatch_util.c
    gcc -c $(RPCSRC)rpc_dispatch_util.c -o rpc_dispatch_util.o -I $(RPCINC)

clean:
    rm *.o *.a main_test

其他背景:
我的公司给了我一堆代码,这是一个Google测试框架(v1.7.0)和一整套测试,这些测试通过串行连接到我们的产品进行接口(interface)。几年来没有人看过,而且都是基于Windows的。构建基于Windows的“unit_test_d.exe”文件输出。我能够对其进行重大构建和扩展,并且该项目是在VS 2015中构建的。。。我能够将其移植并在VS 2017 v15.6.7中打开/构建该项目。

然后,我得到了将整个项目移植到mac的任务,因此我们可以与我们已经为我们的产品提供的BLE(蓝牙)引擎接口(interface)。同样,要继续从Mac终端进行测试,而不需要Windows VM或Windows Box。我已经成功移植了代码,因此它仍然可以在两个平台上运行(很多#ifdef _WIN32或#ifdef APPLE ),现在我可以在Windows上的VS以及带有终端的mac os x上构建项目贝壳。

应用程序学,如果其中任何一个都不是正确的措辞。 :)

在此问题上的任何帮助将不胜感激。很抱歉,这篇文章太长了,但是我想提供尽可能多的具体信息! :)
谢谢!!!

最佳答案

我本来以为这可能是我的编译器(gcc / g++)的问题,因为当我在XCODE中构建时,该问题已消失。

但是,XCODE所做的只是将输出文件“sample1”放在不同的位置。原来我正在运行文件的实际位置无关紧要。我可以从test / src /目录运行它,并且所有测试都重复了,当我从/ use / local / bin /(XCODE放在其中)运行它时,它运行正常。另外...将(完全相同的)文件从一个位置移动到另一个位置,然后执行它会导致工作或不工作...这取决于我从中运行文件的位置。

运行测试文件时,我可以使用 Activity 监视器(mac)查看“打开文件/端口” ...,然后从一个位置运行时将其范围缩小为一个神秘的库,但从另一个位置运行时却没有。

该库是/usr/lib/libprelaod.dylib

我在“dgagent”文件夹中找到了这个库(并复制到/ usr / lib ...两者都具有相同的时间/日期标记),我认为它是Digital Guardian产品的一部分...我的公司已经安装在我的机器上。

我不知道该库中的内容,也不知道为什么它会使Google Test可执行文件两次运行所有测试。我也不知道为什么将可执行文件移动到其他位置会影响运行测试的次数,以及为什么在编译/构建时未执行该操作。

但事实证明,我不在乎。我现在将输出的测试文件放在/ usr / local / bin /中,然后从那里运行它,效果很好。

无论如何,我想发布对此的更新,以防其他人看到类似的问题……或者只是想回答一下为什么会发生这种情况。 :)

谢谢,
Ĵ

关于c++ - Google Test Discovery在Mac OS X上两次添加并运行了我所有的测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51509831/

相关文章:

c++ - 为什么当我输入一个字符时我的程序有一个无限循环?

c++ - TinyXML2 - 在 XML 中间插入元素

c++ - 必须 size() == end() - begin()? Actor 阵容呢?

macos - 如何修复 Dyld 错误消息 : with Core-Plot MacOSX

c++ - 多次调用单个测试 - Google 测试

c++ - `shared_ptr` 是如何实现协变的?

macos - Octave 在 mac osx 上安装包失败(段错误)

objective-c - 如何在 Xcode 上为第 3 方 CLI 进行代码设计和启用强化运行时?

c++ - 为 arm64 交叉编译 googletest

c++ - gmock 多个模拟实例,但只有一个有效