单元测试和集成测试
来源:互联网 发布:live2d有mac版本的吗 编辑:程序博客网 时间:2024/05/19 06:47
单元测试和集成测试
Unit
: 单元测试,保证每一个类能够正常工作 UI
: UI测试,也叫做集成测试,从业务层的角度保证各个业务可以正常工作。
0. 单元测试
准则:
保持测试的单一性
无耦合
概念:
在计算机编程中,单元测试(英语:
Unit Testing
)又称为模块测试, 是针对程序模块的最小单位来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。 – 维基百科
优点:
避免低级错误
减少调试时间
增加可维护性
方便重构代码
缺点:
开发和维护成本高。
不能完全替代人工测试。
单元测试适合范围:
业务变动不频繁
业务属于核心功能
1. XCTest
- (void)setUp { [super setUp]; //初始化的代码,在测试方法调用之前调用}- (void)tearDown { // 释放测试用例的资源代码,这个方法会每个测试用例执行后调用 // 如测试踢人接口后,需要在结束时将对应成员拉回群里,以保证下次的单元测试能够正常进行。 [super tearDown];}// 判断这个类是否存在- (void)testStackExist { XCTAssertNotNil([TestStack class], @"不存在");}// 判断这类是否能创建- (void)testStackCanCreate { TestStack *stack = [TestStack new]; XCTAssertNotNil(stack, @"不能创建");}- (void)testPushANumberAndGetIt { TestStack *stack = [TestStack new]; [stack push:2.0]; double topN = [stack pop]; XCTAssertEqual(topN, 2.0, @"怎么不相等呢");// [stack push:6.0];// double topN2 = [stack pop];// XCTAssertEqual(topN2, 2.0, @"怎么不相等呢");}- (void)testPerformanceExample { // 测试性能例子 [self measureBlock:^{ // 需要测试性能的代码 }];}
- 常用断言
XCTFail(format…) 生成一个失败的测试; XCTAssertNil(arg1, format...) 为空判断,arg1为空时通过,反之不通过; XCTAssertNotNil(arg1, format…) 不为空判断,arg1不为空时通过,反之不通过; XCTAssert(expression, format...) 当expression求值为TRUE时通过; XCTAssertTrue(expression, format...) 当expression求值为TRUE时通过; XCTAssertFalse(expression, format...) 当expression求值为False时通过; XCTAssertEqualObjects(arg1, arg2, format...) 判断相等,[arg1 isEqual: arg2] 值为True时通过,其中一个不为空时,不通过; XCTAssertNotEqualObjects(arg1, arg2, format...) 判断不等,[arg1 isEqual: arg2]值为False时通过, XCTAssertEqual(arg1, arg2, format...) 判断相等(当arg1和arg2是 C语言标量、结构体或联合体时使用,实际测试发现NSString也可以); XCTAssertNotEqual(arg1, arg2, format...) 判断不等(当arg1和arg2是 C语言标量、结构体或联合体时使用); XCTAssertEqualWithAccuracy(arg1, arg2, accuracy, format...) 判断相等,(double或float类型)提供一个误差范围,当在误差范围(+/-accuracy)以内相等时通过测试; XCTAssertNotEqualWithAccuracy(arg1, arg2, accuracy, format...) 判断不等,(double或float类型)提供一个误差范围,当在误差范围以内不等时通过测试; XCTAssertThrows(expression, format...) 异常测试,当expression发生异常时通过;反之不通过;(很变态) XCTAssertThrowsSpecific(expression, specificException, format...) 异常测试,当expression发生specificException异常时通过;反之发生其他异常或不发生异常均不通过; XCTAssertThrowsSpecificNamed(expression, specificException, exception_name, format...) 异常测试,当expression发生具体异常、具体异常名称的异常时通过测试,反之不通过; XCTAssertNoThrow(expression, format...) 异常测试,当expression没有发生异常时通过测试; XCTAssertNoThrowSpecific(expression, specificException, format...) 异常测试,当expression没有发生具体异常、具体异常名称的异常时通过测试,反之不通过; XCTAssertNoThrowSpecificNamed(expression, specificException, exception_name, format...) 异常测试,当expression没有发生具体异常、具体异常名称的异常时通过测试,反之不通过
2. 第三方测试框架
- OCMock
- Kiwi 老牌测试框架
- specta
- Quick 支持swift
mock 表示一个模拟对象, 它是对现有类的行为一种模拟(或是对现有接口实现的模拟)
stub 追踪方法的调用,在方法调用的时候返回指定的值。
mock 与 stub 最大的区别在于 stub 只是简单的方法替换,而不涉及新的对象,被 stub 的对象可以是业务代码中真正的对象。而 mock 行为本身产生新的(不可能在业务代码中出现的)对象,并遵循类的定义相应某些方法。
3. Kiwi
#import <Kiwi/Kiwi.h>#import "YppNetworkService.h"SPEC_BEGIN(YppNetworkServiceSpec)describe(@"YppNetworkService", ^{ context(@"提审 环境测试: ", ^{ it(@"APP_STORE 应该 等于 1 ", ^{ [[theValue(APP_STORE) should] equal:theValue(1)]; }); it(@"ApiVersion 应该 等于 61 ", ^{ [[kApiVersion should] equal:@"61"]; }); it(@"app version 应该 等于 3.3.9 ", ^{ NSDictionary *infoDictionary = [[NSBundle mainBundle] infoDictionary]; NSString *app_Version = [infoDictionary objectForKey:@"CFBundleShortVersionString"]; [[app_Version should] equal:@"3.5.1"]; }); });});SPEC_END
describe
: 行为描述(Specs), 描述需要测试的对象内容 context
: 描述测试上下文 it
中的是测试的本体,描述了这个测试应该满足的条件, 实际的测试写在it里,是由一个一个的期望(Expectations)来进行描述的,期望相当于传统测试中的断言,要是运行的结果不能匹配期望,则测试失败
it有两个参数:
* 行为描述* 行为的测试代码
三者共同构成了Kiwi测试中的行为描述。
其他关键词:
beforeAll(aBlock)
- 当前scope内部的所有的其他block运行之前调用一次afterAll(aBlock)
- 当前scope内部的所有的其他block运行之后调用一次beforeEach(aBlock)
- 在scope内的每个it之前调用一次,对于context的配置代码应该写在这里afterEach(aBlock)
- 在scope内的每个it之后调用一次,用于清理测试后的代码specify(aBlock)
- 可以在里面直接书写不需要描述的测试pending(aString, aBlock)
- 只打印一条log信息,不做测试。这个语句会给出一条警告,可以作为一开始集中书写行为描述时还未实现的测试的提示。xit(aString, aBlock)
- 和pending一样,另一种写法。因为在真正实现时测试时只需要将x删掉就是it,但是pending语意更明确,因此还是推荐pending-
由于有context的存在,以及其可以嵌套的特性,测试的流程控制相比传统测试可以更加精确。我们更容易把before和after的作用区域限制在合适的地方。
在Kiwi中期望都由should
或者shouldNot
开头,并紧接一个或多个判断的的链式调用,大部分常见的是be或者haveSomeCondition的形式
注意:
- 对于 Kiwi 的 stub,需要注意的是它不是永久有效的,在每个 it block 的结尾 stub 都会被清空,超出范围的方法调用将不会被 stub 截取到。 2.
4. 让你的代码更容易单元测试
测试的准确性和工作量很大程度上依赖于开发人员的代码质量。
通常,为了单元测试的准确性,我们在写函数(方法)的时候会借鉴一些函数式编程的思想。其中最重要的一个思想就是 —- pure function(纯函数)
何为Pure function? 就是如果一个函数的输入一样,那么输出一定一样。
比如,这样的一个函数就不是pure function。因为它依赖于外部变量value的值。
static NSInteger value = 0;- (NSInteger)function_1{ value = value + 1; return value;}
而这个函数就是pure function,因为给定输入,输出一定一致
- (NSInteger)function:(NSInteger)value{ value = value + 1; return value;}
如果你写了一个没有参数,或者没有返回值的方法,那么你要小心了,很可能这个方法很难测试。
5. code coverage 测试覆盖率
report -> by group -> coverage
6. 概念
TDD(Test Driven Development)
- 测试驱动开发 是保证代码质量的不二法则, 是敏捷开发中的一项核心实践和技术,也是一种设计方法论。TDD的原理是在开发功能代码之前,先编写单元测试用例代码,测试代码确定需要编写什么产品代码。TDD虽是敏捷方法的核心实践,但不只适用于XP(Extreme Programming),同样可以适用于其他开发方法和过程。
TDD的基本思路就是通过测试来推动整个开发的进行,但测试驱动开发并不只是单纯的测试工作,而是把需求分析,设计,质量控制量化的过程。
BDD(Behavior-driven development)
- 行为驱动开发。行为驱动开发简单来说就是先定义行为,然后定义测试用例,接着再编写代码。 实践中发现,通常没有那么多时间来先定义行为,不过BDD中的domain-specific language (DSL)能够很好的描述用例的行为。
BDD的框架让测试用例的目的更加明确,测试是否通过更加清晰
BDD的核心是行为。也就是说,需要关注的是一个类提供哪些行为
参考完档:
1. Kiwi 使用 –王巍
2. Kiwi 使用进阶 –王巍
- 单元测试和集成测试
- Spring 单元测试和集成测试
- 软件测试技术---单元测试和集成测试
- 单元测试、集成测试和功能测试
- 使用maven实现单元测试和集成测试
- 集成测试和单元测试覆盖率合并
- 单元测试和集成测试业务应用程序
- 单元测试、集成测试、系统测试和验收测试
- 单元测试,集成测试,系统测试 的区别和联系
- 单元测试.集成测试,系统测试 的联系和区别
- 集成测试单元测试.系统测试,的联系和区别
- 单元测试、集成测试、系统测试
- Spring MVC的单元测试和集成测试(不使用mock)
- 关于单元测试和集成测试的新的理解
- Spring MVC的单元测试和集成测试(不使用mock)
- 单元测试 集成测试 系统测试 验收测试
- 单元测试、集成测试、系统测试、验收测试
- 单元测试,集成测试,系统测试,验收测试
- C# winform的WebBrowser自动登录某网站
- Android Gradle使用总结
- python 2.6 升级 2.7
- 《C++ imooc》笔记
- 剑指offer--(1) 二维数组中的查找
- 单元测试和集成测试
- Maven入门解读
- 关于halcon的OCR字符识别
- 仿斗鱼、美团、网易邮箱等 弹窗效果
- SuperMap iClient 9D for MapboxGL地图风格浅析
- MySQL 四种事务隔离级的说明
- 关于python的基础知识9--文件写入列表
- MyBatis缓存策略之二级缓存
- 《慕课网玩转算法面试》笔记及习题解答8.4~8.5