IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> C/C++编程-理论学习-考鼎录<单元测试> -> 正文阅读

[C++知识库]C/C++编程-理论学习-考鼎录<单元测试>

提纲

  1. 单元测试的基本概念和重要性
  2. 单元测试可以无处不在
  3. 单元测试中什么最重要?
  4. 编码生成测试用例
  5. 单元测试框架
  6. 实例研究

单元测试的基本概念

  1. 软件质量的第一责任人是程序员,而非测试员
  2. 单元测试用来保证软件的基本质量,通过测试单个接口或者模块(一组接口)的基本功能来确保:
    • 正确性:确保程序按照预期工作,尤其满足特定的边界条件
    • 性能:确保空间复杂度和性能复杂度在预期范围内
    • 无重大缺陷:确保无内存泄露、缓冲区溢出等重要缺陷

术语

  1. 测试:用于验证接口或者模块是否按照预期工作的活动/行为/代码
  2. 测试用例:用于测试特定功能的实例;一个测试用例通常包含一组输入数据以及对应的预期结果
  3. 测试套件(test suite):对多个测试用例的分组
  4. 测试方法(test method):如何测试某个接口或者模块,也就是如何设计和使用测试用例
  5. 测试框架(testing framework):专用于自动化单元测试的软件框架,如Glib Testing,GoogleTest等

单元测试的重要性

  1. 近几年各种开源基础软件的安全性漏洞造成的破坏性越来越大
    • 2014年Openssl漏洞
    • 2021年log4j漏洞
  2. 绝大多数开源软件缺乏基本的单元测试
    • 开发者太过自信,不重视测试的重要性
    • 急着开源后被动等待用户提issue的“开源协作”模式容易产生低质量代码

单元测试中什么最重要

  1. 测试用例:如何用尽可能少的测试用例覆盖尽可能多的边界条件?
  2. 测试方法:如何设计测试方法,使之
    • 可以自动生成测试用例?或者,
    • 可以自动生成预期结果?或者,
    • 测试用例可由其他人无需编码即可维护?
/**
* 编码生成测试用例
* 分解自然数质数因子的函数
*/

#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <assert.h>

#define DEFSZ_FACTORS	4

unsigned int *prime_factors(unsigned int natural, zise_t *nr_factors)
{
	unsigned int *factors = NULL;
	size_t sz = DEFSZ_FACTORS;
	
	assert(nr_factors);

	if(natural < 2)
	{
		goto failed;
	}
	factors = malloc(sz * sizeof(unsigned int));
	if (factors == NULL)
	goto failed;
	
	*nr_factors = 0;
	for(unsigned int u =2; u <=natural; u++)
	{
		if(natural % u == 0)
		{
			do{ natural = natural /u; }
			while(natural % u == 0)
		}
		if(*nr_factors >= sz)
		{
			sz += DEFSZ-FACTORS;
			facotrs = realloc(factors, sizeof(unsigned int))
			if (factors == NULL)
			goto failed;
		}
		factors[*nr_factors] = u;
		*nr_factors = *nr_factors + 1;
	}
	return factors;

failed:
	if(factors)
		free(factors);
	*nr_factors = 0;
	return NULL;
}



/**
* 我们利用已知的质数反向计算结果,然后来测试分解函数的正确性
*/

#ifdef ENABLE_UNIT_TEST

#define SZ_TABLE(array)sizeof(array)/sizeof(array[0])

//所有小于20的质数
static unsigned int primes_under_20[] = 
{
	235711131719
}struct prime_factors{
	unsigned int natural;
	unsigned int nr_factors;
	unsigned int factors[SZ_TABLE(primes_under_20)];
};

单元测试框架

  1. 单元测试框架只是一个辅助性工具
  2. 不能解决如何测试的问题
  3. 也不能自动生成测试用例

单元测试框架通常包含什么?

  1. 定义一个测试的便利方法
  2. 将测试用例组织成测试套件的便利方法
  3. 各种方便对比运行结果和预期结果的断言宏
  4. 测试报告(是否通过、运行时长等信息)

GLIB TESTING

  1. 使用夹具(Fixtures)的概念,用于封装测试对象以及测试数据。每一次测试前后,分别执行夹具的设置(set up)和拆卸(tear down)操作。
  2. 使用类似路径的形式定义测试套件和测试用例:/myobject/test1。
/* GLIB TESTING 提供的断言宏 */
3. g_assert_true()
4. g_assert_cmpint(),g_assert_cmpuint()
5. g_assert_cmpfloat(),
	g_assert_cmpfloat_with_epsilon()
6. g_assert_cmphex(),g_assert_cmpstr(),
	g_assert_cmpmem(),
	and a_assert_cmpvariant()

/* GLIB TESTING示例 */
#include <glib.h>
#inlcude <locale.h>

typedef struct{
	MyObject *obj;
	OtherObject *helper;
}MyObjectFixture;

static void my_object_fixture_set_up(MyObjectFixture *fixture, gconstpointer user_data)
{
	fixture->obj = my_object_new();
	my_object_set_propl(fixture->obj, "some-value");
	my_object_do_some_complex_setup(fixture->obj, user_data);

	fixture->helper = other_object_new();
}

static void 
my_object_fixture_tear_down(MyObjectFixture *fixture, gconstpointer user_data)
{
	g_clear_object(&fixture->helper);
	g_clear_object(&fixture->obj);
}

static test_my_object_test1(MyObjectFixture *fixture, gconstpointer user_data)
{
	g_assert_cmpstr(my_object_get_property(fixture->obj), ==,xxx);
}

static test_my_object_test2(MyObjectFixture *fixture, gconstpointer user_data)
{
	
	my_objcet_do_some_work_using_helper(fixture->helper, fixture->helper);
	g_assert_cmpstr(my_object_get_property(fixture->obj), ==,xxx);
}

// 调用
int main (int argc, char *argv[])
{
	setlocale(LC_ALL, "");
	g_test_int(&argc, &argv, NULL);

	//define the tests
	g_test_add("/my-object/test1", MyObjectFixture, "some-user",
				mu_object_fixture_set_up, test_my_object_test1,
				my_object_fixture_tear_down);
	g_test_add("/my-object/test2", MyObjectFixture, "some-user",
				mu_object_fixture_set_up, test_my_object_test2,
				my_object_fixture_tear_down);

	return g_test_run();
}

GOOGLETEST

  1. Google 的C++测试(testing )和模拟(mocking)框架,也可以用来测试c接口和模块
  2. 比GLib Testing 更加完善更强大
  3. 文档:http://goole.github.io/googletest/
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-05-14 09:47:23  更:2022-05-14 09:47:47 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 19:11:37-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码