【发布时间】:2018-07-25 02:03:20
【问题描述】:
我会尽量保持简短,但要简洁。
我一直在移植我的公司从 Windows 到 mac os 使用的 google 测试框架(和一套测试)。除了在 MAC 上构建/运行测试时出于某种原因,我几乎所有东西都可以正常工作……Google 测试将我定义的每个测试都包含了两次。
在 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"
在我的servo_drift_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”文件(版本列在底部),所以我可能有在重新编译我们已经下载的源代码并将这些目录放置在正确的位置时,搞砸了文件放置,或者可能是构建选项。希望不会。我们的原始库是使用 VS 2015 for Windows 编译的...我使用上面链接中列出的 cmake 和安装步骤构建了相同的源文件。我在 /usr/local/inc 和 lib 中确实有 gtest.h 和 libgtest.a,所以包含路径的东西应该很好(?)。
并按照它的指示运行示例代码。同样......我看到同样的问题......注意:我确实注释掉了“TEST(FactorialTest,Zero)”案例,只是为了验证注释掉1个测试......真的确实消除了两个实例。它确实做到了。但是您可以看到...“负”和“正”都被添加了两次,以及所有 3 个“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) 有关。有可能它被链接了两次(?),或者在谷歌测试中是否有某种定义或参数设置说“运行我所有的测试两次”?注意:这个问题不是“./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 Test 如何添加“测试”与“测试集”的症状。但我猜这是对整体问题的暗示。
$ ./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”相关的语法错误,则可能只是在此示例中。 :)a
$ 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
附加背景: 我的公司给了我一段代码,这是一个谷歌测试框架(v1.7.0)和一整套通过串行连接到我们产品的测试套件。几年来没有人看过这个,而且它都是基于 Windows 的。构建基于 Windows 的“unit_test_d.exe”文件输出。我能够显着构建和扩展它,并且该项目是在 VS 2015 中构建的......我能够将它转发并在 VS 2017 v15.6.7 中打开/构建项目
然后我被赋予将整个项目移植到 mac 的任务,这样我们就可以与我们已经为我们的产品现有的 BLE(蓝牙)引擎进行接口。同样,从 mac 终端继续测试,而不需要 windows 虚拟机或 windows 盒子。我已经成功移植了代码,所以它仍然可以在两个平台上运行(很多 #ifdef _WIN32 或 #ifdef APPLE),我现在可以在 Windows 和 mac 上的 VS 中构建项目带有终端外壳的 os x。
如果其中任何一个措辞不正确,我们深表歉意。 :)
对于这个问题的任何帮助将不胜感激。抱歉这篇文章的长度,但我想在第一次提供尽可能多的具体信息! :) 谢谢!!!
【问题讨论】:
-
我对 Google Test 完全不熟悉,所以可能还不太熟悉,但是:它可以同时测试 32 位和 64 位架构吗?
-
我担心周围有“奇怪”的库,所以我有一个朋友在工作(之前从未构建过任何谷歌测试)遵循“示例教程”以及干净的环境:@ 987654322@ 它在他的机器/设置上做同样的事情,发现/添加每个测试运行两次。我们都在运行 macOS High Sierra V10.13.6 环境: $ env TERM_PROGRAM=Apple_Terminal SHELL=/bin/bash LIBRARY_PATH=/usr/local/lib CPLUS_INCLUDE_PATH=/usr/local/include SHLVL=1
标签: c++ macos googletest