03-Google Test使用

1. Google Test简介

Google Test是一种比较方便的C++测试框架, 它能够帮助我们比较方便的进行测试代码的编写, 以及输出尽可能详细的失败信息。能够大大缩短我们测试代码的编写效率, 而且该框架的使用方法也比较简单, 能够降低我们学习新框架的负担。

2. vs2019上Google Test使用

在vs2019中,提供了Google Test项目模板,能够方便的为一个项目添加Google Test。

2.1主要过程

  • (1) 创建一个新解决方案,或者打开一个已有解决方案。在解决方案中保证已有一个项目。该项目需要测试的程序,生成.lib或.dll;
  • (2)在解决方案中添加一个Google Test项目,添加需测试项目的头文件目录和项目的引用;
  • (3)编写测试用例,进行测试;
  • (4)运行测试用例。

2.2 Demo

(1)创建一个新项目,设定配置类型为静态库(.lib),目标文件扩展名改为.lib
在这里插入图片描述
编写相关项目文件,文件说明如下:

--头文件
  --a_cstring.h
--源文件
  --a_cstring.cpp

a_cstring.h内容如下:

#ifndef _UTILS_A_CSTRING_HEADER_
#define _UTILS_A_CSTRING_HEADER_
class a_cstring
{
public:

	static char* a_strcpy(char* des, const char* src);
	static size_t a_strlen(const char* src);
	static char* a_strcat(char* des, const char* src);
	static int a_strcmp(const char* s1, const char* s2);
};
#endif 

a_cstring.cpp内容如下:

#include "a_cstring.h"


/**
 * @brief 字符串拷贝函数
 * @param des 目标字符串,长度必须要大于等于源字符串的长度
 * @param src 源字符串
 * @return 目标字符串首地址
*/
char* a_cstring::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_cstring::a_strlen(const char* src) {
	if (!src) return 0;

	size_t l = 0;

	while (*src != '\0') {
		++l;
		++src;
	}

	return l;
}

/**
 * @brief 将src字符串追加在des尾部,des和src内存区域需要不重叠,且des必须有足够大的空间来存放src
 * @param des 目标字符串
 * @param src 源字符串
 * @return 尾部追加过源字符串的目标字符串
*/
char* a_cstring::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,返回-1;s1<s2,返回-1;s1=s2,返回0;s2>s2,返回1;
*/
int a_cstring::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;
	}
}

(2)创建Google Test项目并添加对现有项目的引用
Google Test项目创建成功后,会下载对应lib或dll版本的Google Test。会存放在解决方案的根路径下的packages文件夹内。

添加我们要测试的项目的头文件路径
在这里插入图片描述

添加项目引用
在这里插入图片描述
(3)编写测试用例
默认生成的Google Tset测试项目目录:
在这里插入图片描述
其中,pch.h和pch.cpp文件是预编译头,如果不需要可以在test项目右键:属性->C/C+±>预编译头->预编译头修改为关闭。随后删除文件即可。

在test.cpp中编写测试用例(有需要可以建立新的cpp文件)。

#include "pch.h"

TEST(a_strcpy, nullptr) {

	char* a = "";

	EXPECT_STREQ(nullptr, a_cstring::a_strcpy(nullptr, nullptr));
	EXPECT_STREQ(nullptr, a_cstring::a_strcpy(a, nullptr));
	EXPECT_STREQ(nullptr, a_cstring::a_strcpy(nullptr, a));
}


TEST(a_strcpy, negative) {
	char a[6] = "aaaaa";
	char b[2] = "b";

	EXPECT_STRNE("baaaa", a_cstring::a_strcpy(a, b));
}

TEST(a_strcpy, positive) {
	char a[6] = "aaaaa";
	char b[2] = "b";

	EXPECT_STREQ("b", a_cstring::a_strcpy(a, b));
}

TEST(a_strlen, nullptr) {
	EXPECT_EQ(0, a_cstring::a_strlen(nullptr));
}

TEST(a_strlen, positive) {
	EXPECT_EQ(0, a_cstring::a_strlen(""));
	EXPECT_EQ(1, a_cstring::a_strlen("a"));
	EXPECT_EQ(2, a_cstring::a_strlen("ab"));
}

TEST(a_strcat, nullptr) {
	char a[] = "";
	EXPECT_STREQ(nullptr, a_cstring::a_strcat(nullptr, nullptr));
	EXPECT_STREQ(a, a_cstring::a_strcat(a, nullptr));
	EXPECT_STREQ(nullptr, a_cstring::a_strcat(nullptr, a));
}

TEST(a_strcat, positive) {
	char a[10] = "";
	char b[10] = "bbb";
	EXPECT_STREQ("", a_cstring::a_strcat(a, ""));
	EXPECT_STREQ("aaa", a_cstring::a_strcat(a, "aaa"));

	EXPECT_STREQ("bbb", a_cstring::a_strcat(b, ""));
	EXPECT_STREQ("bbbaaa", a_cstring::a_strcat(b, "aaa"));
}

TEST(a_strcmp, nullptr) {
	EXPECT_EQ(-2, a_cstring::a_strcmp(nullptr, nullptr));
	EXPECT_EQ(-2, a_cstring::a_strcmp("", nullptr));
	EXPECT_EQ(-2, a_cstring::a_strcmp(nullptr, ""));
}

TEST(a_strcmp, LT) {
	EXPECT_EQ(-1, a_cstring::a_strcmp("", "a"));
	EXPECT_EQ(-1, a_cstring::a_strcmp("a", "ab"));
	EXPECT_EQ(-1, a_cstring::a_strcmp("ab", "abc"));
}

TEST(a_strcmp, EQ) {
	EXPECT_EQ(0, a_cstring::a_strcmp("", ""));
	EXPECT_EQ(0, a_cstring::a_strcmp("a", "a"));
	EXPECT_EQ(0, a_cstring::a_strcmp("ab", "ab"));
}

TEST(a_strcmp, GT) {
	EXPECT_EQ(1, a_cstring::a_strcmp("a", ""));
	EXPECT_EQ(1, a_cstring::a_strcmp("ab", "a"));
	EXPECT_EQ(1, a_cstring::a_strcmp("abc", "ab"));
}

pch.h内容如下:

#pragma once

#include "gtest/gtest.h"
#include "a_cstring.h"

(4)运行测试用例
在解决方案管理器中点击GoogleTest项目,右键设为启动项目,随后点击运行即可。
在这里插入图片描述
或者在菜单栏->测试->测试资源管理器中进行测试。
在这里插入图片描述
打印输出如下:
在这里插入图片描述

3. GoogleTest的断言/宏

Google Test采用一系列的断言(assertion)来进行代码测试,这些宏有点类似于函数调用。
当断言失败时Google Test将会打印出assertion时的源文件和出错行的位置,以及附加的失败信息,
用户可以直接通过“<<”在这些断言宏后面跟上自己希望在断言命中时的输出信息。
测试宏可以分为两大类:ASSERT_和EXPECT_,这些成对的断言功能相同,但效果不同。其中ASSERT_*将会在失败时产生致命错误并中止当前调用它的函数执行。EXPECT_版本的会生成非致命错误,不会中止当前函数,而是继续执行当前函数。通常情况应该首选使用EXPECT_,因为ASSERT_*在报告完错误后不会进行清理工作,有可能导致内容泄露问题。

3.1 基本断言

Fatal assertionNonfatal assertionVerifies
ASSERT_TRUE(condition)EXPECT_TRUE(condition)condition is true
ASSERT_FALSE(condition)EXPECT_FALSE(condition)condition is false

3.2 二值比较

Fatal assertionNonfatal assertionVerifies
ASSERT_EQ(val1,val2)EXPECT_EQ(val1,val2)val1 == val2
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)val1 >= val2

3.3 字符串比较

Fatal assertionNonfatal assertionVerifies
ASSERT_STREQ(str1,str2)EXPECT_STREQ(str1,str2)the two C strings have the same content
ASSERT_STRNE(str1,str2)EXPECT_STRNE(str1,str2)the two C strings have different content
ASSERT_STRCASEEQ(str1,str2)EXPECT_STRCASEEQ(str1,str2)the two C strings have the same content, ignoring case
ASSERT_STRCASENE(str1,str2)EXPECT_STRCASENE(str1,str2)the two C strings have different content, ignoring case

4. 测试用例类型

4.1TEST测试用例

TEST是基本的测试方式, 我们传进测试函数的名字, 调用ASSERT_XX或者EXPECT_XX来测试函数的执行结构和我们预期的是否一致,,demo如下:

TEST(TestCaseName, TestName) {
  EXPECT_EQ(1, 1);
  EXPECT_TRUE(true);
}

4.2 TEST_F测试用例

有时候我们希望传入的参数是一个class的对象, 并且该对象在传入之前进行了一定的出配置, 并且有好几个函数的测试都需要用到相同的配置, 为了避免重复, Googletest 提供了TEST_F 的测试方式,demo如下:

#include "log.h"
#include "gtest/gtest.h"
class LogTest : public ::testing::Test {
public:
    std::string GetLevelStr() {
        return mlog::GetLevelStr();
    }
protected:
    virtual void SetUp()
    {
        log_ptr = new mlog::Log(mlog::kInfo);
    }
    virtual void TearDown()
    {
        delete log_ptr;
    }
private:
    mlog::Log* log_ptr;
};

TEST_F(LogTest, TestLog)
{
    std::string levelStr = GetLevelStr();
    std::string expected = "Info";
    ASSERT_STRCASEEQ(levelStr.c_str(), expected.c_str());  
 }                                            
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
本系统的研发具有重大的意义,在安全性方面,用户使用浏览器访问网站时,采用注册和密码等相关的保护措施,提高系统的可靠性,维护用户的个人信息和财产的安全。在方便性方面,促进了校园失物招领网站的信息化建设,极大的方便了相关的工作人员对校园失物招领网站信息进行管理。 本系统主要通过使用Java语言编码设计系统功能,MySQL数据库管理数据,AJAX技术设计简洁的、友好的网址页面,然后在IDEA开发平台中,编写相关的Java代码文件,接着通过连接语言完成与数据库的搭建工作,再通过平台提供的Tomcat插件完成信息的交互,最后在浏览器中打开系统网址便可使用本系统。本系统的使用角色可以被分为用户和管理员,用户具有注册、查看信息、留言信息等功能,管理员具有修改用户信息,发布寻物启事等功能。 管理员可以选择任一浏览器打开网址,输入信息无误后,以管理员的身份行使相关的管理权限。管理员可以通过选择失物招领管理,管理相关的失物招领信息记录,比如进行查看失物招领信息标题,修改失物招领信息来源等操作。管理员可以通过选择公告管理,管理相关的公告信息记录,比如进行查看公告详情,删除错误的公告信息,发布公告等操作。管理员可以通过选择公告类型管理,管理相关的公告类型信息,比如查看所有公告类型,删除无用公告类型,修改公告类型,添加公告类型等操作。寻物启事管理页面,此页面提供给管理员的功能有:新增寻物启事,修改寻物启事,删除寻物启事。物品类型管理页面,此页面提供给管理员的功能有:新增物品类型,修改物品类型,删除物品类型

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

逍遥俊子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值