【gtest】Visual Studio 2019 单元测试学习Google Test
前言
记录在VS2019中使用自带的Google Test进行单元测试的方法和经验
项目介绍
总共2个项目,Work
为项目工程,TestWork
为Work
工程的单元测试工程,TestWork
依赖于Work
工程,但是Work
不依赖TestWork
,TestWork
是Work
的旁路辅助工程,用于对代码的检查和测试。
创建项目
- 创建C++的常规Work工程
- 新增创建Google Test的单元测试工程
创建完项目后,工程项目情况如下(可将TestWork设置为启动项目,右键TestWork->Set as Startup Project):
编写项目代码
准备测试类和常规函数
【工作项目】点击查看代码
/*** test.h文件内容 ***/
#pragma once
#include <string>
#include <windows.h>
#include <chrono>
int Snprintf(char* pBuf, int nBuf, const char* pFormat, ...);
std::string GbkToUtf8(const char* pSrc, int nLen);
std::string Utf8ToGbk(const char* pSrc, int nLen);
std::string GetFileText(const char* file);
void WriteFile(const char* file, const char* dat, size_t len);
/// <summary>
/// 时间差
/// </summary>
/// <param name="start"></param>
/// <param name="end"></param>
/// <returns></returns>
std::chrono::microseconds ClockSpan(std::chrono::steady_clock::time_point start, std::chrono::steady_clock::time_point end);
/// <summary>
/// 当前时间
/// </summary>
/// <returns></returns>
std::chrono::steady_clock::time_point GetNowClock();
/** utils.h文件内容 ***/
#pragma once
class utils
{
public:
int Add(int a, int b);
bool IsEmpty(const char* s);
};
单元测试项目设置
因为单元测试是辅助类项目,原Work
不依赖于单元测试项目,因此单元测试项目必须是无侵入式引用Work
项目,方式如下:
- 源代码引用,包括头文件,如:
#include "pch.h"
#include "..\text.h"
#include "..\utils.h"
也可通过设置【配置属性 - C/C++ - 常规 - 附加包含目录】配置项目目录,便于包含头文件
- 链接库引用,因原项目不一定式静态库,因此仅包含头文件时会在链接时找不到引用的函数符号,因此对于需要引用的函数,需要链接其定义的obj文件,TestWork项目【属性-链接器-输入-附加依赖项】,如:
编写单元测试代码
#include "pch.h"
#include "..\text.h"
#include "..\utils.h"
TEST(TestCaseName, TestName) {
EXPECT_EQ(1, 1);
EXPECT_TRUE(true);
}
TEST(Work, WorkUtil)
{
utils us;
EXPECT_TRUE(us.IsEmpty(NULL));
EXPECT_TRUE(us.IsEmpty(""));
EXPECT_TRUE(!us.IsEmpty(" "));
EXPECT_EQ(1, us.Add(1, 0));
EXPECT_EQ(2, us.Add(3, -1));
}
TEST(Work, WorkText)
{
char buf[256];
Snprintf(buf, sizeof(buf), "您好,China %d!", 2023);
EXPECT_EQ(0, strcmp(buf, "您好,China 2023!"));
std::string s;
std::string strGbk = "中国·西藏●默罕默德③代";
std::string strUtf8 = GbkToUtf8(strGbk.c_str(), strGbk.size());
EXPECT_EQ(0, strGbk.compare(Utf8ToGbk(strUtf8.c_str(), strUtf8.size())));
auto tNow = GetNowClock();
Sleep(100);
auto tNow100 = GetNowClock();
EXPECT_EQ(ClockSpan(tNow, tNow100).count(), 100);
}
执行结果:
Running main() from c:\a\_work\32\s\thirdparty\googletest\googletest\src\gtest_main.cc
[==========] Running 3 tests from 2 test cases.
[----------] Global test environment set-up.
[----------] 1 test from TestCaseName
[ RUN ] TestCaseName.TestName
[ OK ] TestCaseName.TestName (0 ms)
[----------] 1 test from TestCaseName (0 ms total)
[----------] 2 tests from Work
[ RUN ] Work.WorkUtil
[ OK ] Work.WorkUtil (1 ms)
[ RUN ] Work.WorkText
[ OK ] Work.WorkText (101 ms)
[----------] 2 tests from Work (103 ms total)
[----------] Global test environment tear-down
[==========] 3 tests from 2 test cases ran. (106 ms total)
[ PASSED ] 3 tests.
执行单元测试
单元测试生成的单元测试程序支持根据命令行参数设置执行参数,参数是gtest内置的,如:
D:\Code\Study\CPP\gtest\Work\Debug>TestWork.exe /?
Running main() from c:\a\_work\32\s\thirdparty\googletest\googletest\src\gtest_main.cc
This program contains tests written using Google Test. You can use the
following command line flags to control its behavior:
Test Selection:
--gtest_list_tests
List the names of all tests instead of running them. The name of
TEST(Foo, Bar) is "Foo.Bar".
--gtest_filter=POSTIVE_PATTERNS[-NEGATIVE_PATTERNS]
Run only the tests whose name matches one of the positive patterns but
none of the negative patterns. '?' matches any single character; '*'
matches any substring; ':' separates two patterns.
--gtest_also_run_disabled_tests
Run all disabled tests too.
Test Execution:
--gtest_repeat=[COUNT]
Run the tests repeatedly; use a negative count to repeat forever.
--gtest_shuffle
Randomize tests' orders on every iteration.
--gtest_random_seed=[NUMBER]
Random number seed to use for shuffling test orders (between 1 and
99999, or 0 to use a seed based on the current time).
Test Output:
--gtest_color=(yes|no|auto)
Enable/disable colored output. The default is auto.
--gtest_print_time=0
Don't print the elapsed time of each test.
--gtest_output=(json|xml)[:DIRECTORY_PATH\|:FILE_PATH]
Generate a JSON or XML report in the given directory or with the given
file name. FILE_PATH defaults to test_details.xml.
Assertion Behavior:
--gtest_break_on_failure
Turn assertion failures into debugger break-points.
--gtest_throw_on_failure
Turn assertion failures into C++ exceptions for use by an external
test framework.
--gtest_catch_exceptions=0
Do not report exceptions as test failures. Instead, allow them
to crash the program or throw a pop-up (on Windows).
Except for --gtest_list_tests, you can alternatively set the corresponding
environment variable of a flag (all letters in upper-case). For example, to
disable colored text output, you can either specify --gtest_color=no or set
the GTEST_COLOR environment variable to no.
For more information, please read the Google Test documentation at
https://github.com/google/googletest/. If you find a bug in Google Test
(not one in your own code or tests), please report it to
<googletestframework@googlegroups.com>.
执行目标案例过滤
执行以Work
开头的测试案例
D:\Code\Study\CPP\gtest\Work\Debug>TestWork.exe --gtest_filter=Work*
Running main() from c:\a\_work\32\s\thirdparty\googletest\googletest\src\gtest_main.cc
Note: Google Test filter = Work*
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from Work
[ RUN ] Work.WorkUtil
[ OK ] Work.WorkUtil (0 ms)
[ RUN ] Work.WorkText
[ OK ] Work.WorkText (100 ms)
[----------] 2 tests from Work (106 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (113 ms total)
[ PASSED ] 2 tests.