CC++编程-理论学习-考鼎录<单元测试>

CC++编程-理论学习-考鼎录<单元测试>,第1张

单元测试
  • 提纲
  • 单元测试的基本概念
    • 术语
  • 单元测试的重要性
  • 单元测试中什么最重要
  • 单元测试框架
    • 单元测试框架通常包含什么?
    • GLIB TESTING
    • GOOGLETEST

提纲
  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 
#include 
#include 
#include 

#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 
#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/

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/872827.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-13
下一篇 2022-05-13

发表评论

登录后才能评论

评论列表(0条)

保存