VS2015中构建并使用GooleTest
1.首先去GitHub下载googletest-1.8.x版本
下载地址:https://github.com/google/googletest
在分支中找到1.8.x版本:
2.下载完成后解压到并进入目录(以下是本人的解压路径)
使用VS2015打开sln文件:
3.编译对应的lib(以x64为例,32位同理)
Debug 64位项目属性配置, 配置完后生成项目:
Release 64位:
为了方便可以将生成的lib复制或剪切到一个单独的文件夹中,例如我的就是将其复制到我新建的build文件夹中:
4.在项目中使用
创建一个VC++控制台项目,打开属性管理器即可一次配置全局使用, 以Debug x64为例配置如下:
项目结构及代码如下:
// Sample.hpp
#pragma once
// 简单粗暴实现的几个C风格字符串相关函数
/**
* @brief 字符串拷贝
* @param des 目标字符串,长度必须要 >= 源字符串的长度 + 1
* @param src 源字符串
* @return 目标字符串首地址
*/
char* a_strcpy(char* des, const char* src) {
if (!des || !src) return nullptr;
char* address = des;
while (*src != '\0') {
*des = *src;
des++;
src++;
}
*des = '\0';
return address;
}
/**
* @brief 字符串长度计算
* @param src 字符串
* @return 字符串长度
*/
size_t a_strlen(const char* src) {
if (!src) return 0;
size_t len = 0;
while (*src != '\0') {
++len;
++src;
}
return len;
}
/**
* @brief 将src字符串追加在des尾部, 用户需保证des和src内存区域不重叠且des必须有足够大的空间来存放src
* @param des 目标字符串
* @param src 源字符串
* @return 尾部追加过源字符串的目标字符串
*/
char* a_strcat(char* des, const char* src) {
if (!des) return nullptr;
if (!src) return des;
char* address = des;
while (*des != '\0') {
des++;
}
while (*src != '\0') {
*des = *src;
des++;
src++;
}
*des = '\0';
return address;
}
/**
* @brief 字符串比较
* @param s1 字符串1
* @param s2 字符串2
* @return s1或s2为nullptr,返回-2; s1<s2,返回-1; s1=s2,返回0; s2>s2,返回1;
*/
int a_strcmp(const char* s1, const char* s2) {
if (!s1 || !s2) return -2;
while (*s1 != '\0' && *s2 != '\0') {
if (*s1 < *s2) {
return -1;
}
else if (*s1 == *s2) {
s1++;
s2++;
}
else if (*s1 > * s2) {
return 1;
}
}
if (*s1 == '\0' && *s2 != '\0') {
return -1;
}
else if (*s1 == '\0' && *s2 == '\0') {
return 0;
}
else if (*s1 != '\0' && *s2 == '\0') {
return 1;
}
}
// Test.cpp
#include <iostream>
#include <gtest/gtest.h> // GoogleTest
#include "Sample.hpp" // 需要测试的Function
TEST(a_strcpy, nullptr) {
char* a = "";
EXPECT_STREQ(nullptr, a_strcpy(nullptr, nullptr));
EXPECT_STREQ(nullptr, a_strcpy(a, nullptr));
EXPECT_STREQ(nullptr, a_strcpy(nullptr, a));
}
TEST(a_strcpy, negative) {
char a[6] = "aaaaa";
char b[2] = "b";
EXPECT_STRNE("baaaa", a_strcpy(a, b));
}
TEST(a_strcpy, positive) {
char a[6] = "aaaaa";
char b[2] = "b";
EXPECT_STREQ("b", a_strcpy(a, b));
}
TEST(a_strlen, nullptr) {
EXPECT_EQ(0, a_strlen(nullptr));
}
TEST(a_strlen, positive) {
EXPECT_EQ(0, a_strlen(""));
EXPECT_EQ(1, a_strlen("a"));
EXPECT_EQ(2, a_strlen("ab"));
}
TEST(a_strcat, nullptr) {
char a[] = "";
EXPECT_STREQ(nullptr, a_strcat(nullptr, nullptr));
EXPECT_STREQ(a, a_strcat(a, nullptr));
EXPECT_STREQ(nullptr, a_strcat(nullptr, a));
}
TEST(a_strcat, positive) {
char a[10] = "";
char b[10] = "bbb";
EXPECT_STREQ("", a_strcat(a, ""));
EXPECT_STREQ("aaa", a_strcat(a, "aaa"));
EXPECT_STREQ("bbb", a_strcat(b, ""));
EXPECT_STREQ("bbbaaa", a_strcat(b, "aaa"));
}
TEST(a_strcmp, nullptr) {
EXPECT_EQ(-2, a_strcmp(nullptr, nullptr));
EXPECT_EQ(-2, a_strcmp("", nullptr));
EXPECT_EQ(-2, a_strcmp(nullptr, ""));
}
TEST(a_strcmp, LT) {
EXPECT_EQ(-1, a_strcmp("", "a"));
EXPECT_EQ(-1, a_strcmp("a", "ab"));
EXPECT_EQ(-1, a_strcmp("ab", "abc"));
}
TEST(a_strcmp, EQ) {
EXPECT_EQ(0, a_strcmp("", ""));
EXPECT_EQ(0, a_strcmp("a", "a"));
EXPECT_EQ(0, a_strcmp("ab", "ab"));
}
TEST(a_strcmp, GT) {
EXPECT_EQ(1, a_strcmp("a", ""));
EXPECT_EQ(1, a_strcmp("ab", "a"));
EXPECT_EQ(1, a_strcmp("abc", "ab"));
}
int main(int argc, char* argv[])
{
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
测试结果:
5.GoogleTest的一些基本测试操作
断言:gtest中采用了大量的宏来包装断言,按照其使用方法可以分为两类:
- ASSERT系列(ASSERT_&系列,当检查点失败时,退出当前函数,并非推出当前案例)
- EXPECT系列(EXPECT_*系列的断言,当检查点失败时,继续往下执行)
按照常用功能可以依次分为12类,较常用的有以下几类:
- 布尔值比较
- 数值型数据比较
- 字符串比较
- 浮点数比较
- 近似数比较
- 异常检测
- 自定义格式函数与参数检查
具体如下:
- 布尔值比较
ASSERT系列 | EXPECT系列 | 通过条件 |
---|---|---|
ASSERT_TRUE(condition) | EXPECT_TRUE(condition) | condition == true |
ASSERT_FALSE(condition) | EXPECT_FALSE(condition) | condition == false |
- 数值型数据比较
ASSERT系列 | EXPECT系列 | 通过条件 |
---|---|---|
ASSERT_EQ (expected, actual) | EXPECT_EQ (expected, actual) | expected == actual |
ASSERT_NE (val1, val2) | EXPECT_NE (val1, val2) | val1 != val2 |
ASSERT_LT (val1, val2) | EXPECT_LT (val1, val2) | val1 < val2 |
ASSERT_LE (val1, val2) | EXPECT_LE (val1, val2) | val1 <= val2 |
ASSERT_GT (val1, val2) | EXPECT_GT (val1, val2) | val1 > val2 |
ASSERT_GE (val1, val2) | EXPECT_GE (val1, val2) | val2 >= val2 |
- 字符串比较
ASSERT系列 | EXPECT系列 | 通过条件 |
---|---|---|
ASSERT_STREQ (str1, str2) | EXPECT_STREQ (str1, str2) | 两个C字符串内容相同(char * or wchar_t *) |
ASSERT_STRNE (str1, str2) | EXPECT_STRNE (str1, str2) | 两个C字符串内容不同(同时支持char *和wchar_t *类型) |
ASSERT_STRCASEEQ (str1, str2) | EXPECT_STRCASEEQ (str1, str2) | 两个C字符串内容相同,忽略大小写(只支持char *类型) |
ASSERT_STRCASENE (str1, str2) | EXPECT_STRCASENE (str1, str2) | 两个C字符串内容不同,忽略大小写(只支持char *类型) |
- 浮点数比较
ASSERT系列 | EXPECT系列 | 通过条件 |
---|---|---|
ASSERT_FLOAT_EQ (val1, val2) | EXPECT_FLOAT_EQ (val1, val2) | the two float values are almost equal |
ASSERT_DOUBLE_EQ (val1, val2) | EXPECT_DOUBLE_EQ (val1, val2) | the two double values are almost equal |
- 近似数比较
ASSERT系列 | EXPECT系列 | 通过条件 |
---|---|---|
ASSERT_NEAR (val1, val2, abs_error) | EXPECT_NEAR (val1, val2, abs_error) | 两个数值val1和val2的绝对值差不超过abs_error |
- 异常检查
ASSERT系列 | EXPECT系列 | 通过条件 |
---|---|---|
ASSERT_THROW (statement, exception_type) | EXPECT_THROW (statement, exception_type) | 抛出指定类型异常 |
ASSERT_THROW(statement) | EXPECT_THROW(statement) | 抛出任意类型异常 |
ASSERT_NO_THROW(statement) | EXPECT_NO_THROW(statement) | 不抛出异常 |
- 函数值与参数检查(目前最多只支持5个参数)
ASSERT系列 | EXPECT系列 | 通过条件 |
---|---|---|
ASSERT_PRED1(pred1, val1) | EXPECT_PRED1(pred1, val1) | pred1(val1) returns true |
ASSERT_PRED2(pred2, val1, val2) | EXPECT_PRED2(pred2, val1, val2) | pred2(val1, val2) returns true |
- Windows HRESULT
ASSERT系列 | EXPECT系列 | 通过条件 |
---|---|---|
ASSERT_HRESULT_SUCCEEDED(expression) | EXPECT_HRESULT_SUCCEEDED(expression) | expression is a success HRESULT |
ASSERT_HRESULT_FAILED(expression) | EXPECT_HRESULT_FAILED(expression) | expression is a failure HRESULT |
- 自定义格式函数与参数检查(目前最多支持5个参数)
ASSERT系列 | EXPECT系列 | 通过条件 |
---|---|---|
ASSERT_PRED_FORMAT1(pred1, val1) | EXPECT_PRED_FORMAT1(pred1, val1) | pred1(val1) is successful |
ASSERT_PRED_FORMAT1(pred1, val1, val2) | EXPECT_PRED_FORMAT1(pred1, val1, val2) | pred2(val1, val2) is successful |