写好测试,提升应用质量。涨薪分分钟!!!(二)之单元测试下开发模式、技术框架选择

本文介绍了TDD和BDD在单元测试中的应用,包括它们的开发模式、XCTest的使用,以及Kiwi、Expecta和Specta等测试框架的选择。通过实际案例展示了如何进行TDD开发,强调了测试驱动在提升代码质量和应用可靠性中的作用。
摘要由CSDN通过智能技术生成

目录:

 

四、 单元测试下开发模式、技术框架选择

单元测试是按照测试范围来划分的。TDD、BDD 是按照开发模式来划分的。因此就有各种排列组合,这里我们只关心单元测试下的 TDD、BDD 方案。

在单元测试阶段,TDD 和 BDD 都可以适用。

1. TDD

TDD 强调不断的测试推动代码的开发,这样简化了代码,保证了代码质量。

思想是在拿到一个新的功能时,首先思考该功能如何测试,各种测试用例、各种边界 case;然后完成测试代码的开发;最后编写相应的代码以满足、通过这些测试用例。

TDD 开发过程类似下图:

 

 

  • 先编写该功能的测试用例,实现测试代码。这时候去跑测试,是不通过的,也就是到了红色的状态
  • 然后编写真正的功能实现代码。这时候去跑测试,测试通过,也就是到了绿色的状态
  • 在测试用例的保证下,可以重构、优化代码

抛出一个问题:TDD 看上去很好,应该用它吗?

这个问题不用着急回答,回答了也不会有对错之分。开发中经常是这样一个流程,新的需求出来后,先经过技术评审会议,确定宏观层面的技术方案、确定各个端的技术实现、使用的技术等,整理出开发文档、会议文档。工期评估后开始编码。事情这么简单吗?前期即使想的再充分、再细致,可能还是存在特殊 case 漏掉的情况,导致技术方案或者是技术实现的改变。如果采用 TDD,那么之前新功能给到后,就要考虑测试用例的设计、编写了测试代码,在测试用例的保证下再去实现功能。如果遇到了技术方案的变更,之前的测试用例要改变、测试代码实现要改变。可能新增的某个 case 导致大部分的测试代码和实现代码都要改变。

如何开展 TDD**

  1. 新建一个工程,确保 “Include Unit Tests” 选项是选中的状态

     

    TDD Step 1

     

  2. 创建后的工程目录如下

     

    TDD step2

     

  3. 删除 Xcode 创建的测试模版文件 TDDDemoTests.m

  4. 假如我们需要设计一个人类,它具有吃饭的功能,且当他吃完后会说一句“好饱啊”。

  5. 那么按照 TDD 我们先设计测试用例。假设有个 Person 类,有个对象方法叫做吃饭,吃完饭后会返回一个“好饱啊”的字符串。那测试用例就是

    步骤 期望 结果
    实例化 Person 对象,调用对象的 eat 方法 调用后返回“好饱啊”
  6. 实现测试用例代码。创建继承自 Unit Test Case class 的测试类,命名为 工程前缀+测试类名+Test,也就是 TDDPersonTest.m。【自动化交流群】:1140267353 本群提供免费的学习指导,自动化资料以及免费的解答,不懂得问题都可以在本群提出来,之后还会有职业生涯规划以及面试指导;

     

    TDD step 3

     

  7. 因为要测试 Person 类,所以在主工程中创建 Person 类

  8. 因为要测试人类在吃饭后说一句“好饱啊”。所以设想那个类目前只有一个吃饭的方法。于是在 TDDPersonTest.m 中创建一个测试函数 -(void)testReturnStatusStringWhenPersonAte;函数内容如下

    - (void)testReturnStatusStringWhenPersonAte
    {
        // Given
        Person *somebody = [[Person alloc] init];
        
        // When
        NSString *statusMessage = [somebody performSelector:@selector(eat)];
        
        // Then
        XCTAssert([statusMessage isEqualToString:@"好饱啊"], @"Person 「吃饭后返回“好饱啊”」功能异常");
    }
    复制代码
  9. Xcode 下按快捷键 Command + U,跑测试代码发现是失败的。因为我们的 Person 类根本没实现相应的方法

  10. TDD 开发过程可以看到,我们现在是红色的 “Fail” 状态。所以需要去 Person 类中实现功能代码。Person 类如下

    #import "Person.h"
    
    @implementation Person
    
    - (NSString *)eat
    {
        [NSThread sleepForTimeInterval:1];
        return @"好饱啊";;
    }
    
    @end
    复制代码
  11. 再次运行,跑一下测试用例(Command + U 快捷键)。发现测试通过,也就是TDD 开发过程中的绿色 “Success” 状态。

  12. 例子比较简单,假如情况需要,可以在 -(void)setUp 方法里面做一些测试的前置准备工作,在 -(void)tearDown 方法里做资源释放的操作

  13. 假如 eat 方法实现的不够漂亮。现在在测试用例的保证下,大胆重构,最后确保所有的 Unit Test case 通过即可。

2. BDD

相比 TDD,BDD 关注的是行为方式的设计,拿上述“人吃饭”举例说明。

和 TDD 相比第1~4步骤相同。

  1. BDD 则需要先实现功能代码。创建 Person 类,实现 -(void)eat;方法。代码和上面的相同

  2. BDD 需要引入好用的框架 Kiwi,使用 Pod 的方式引入

  3. 因为要测试人类在吃饭后说一句“好饱啊”。所以设想那个类目前只有一个吃饭的方法。于是在 TDDPersonTest.m 中创建一个测试函数 -(void)testReturnStatusStringWhenPersonAte;函数内容如下

    #import "kiwi.h"
    #import "Person.h"
    
    SPEC_BEGIN(BDDPersonTest)
    
    describe(@"Person", ^{
        context(@"when someone ate", ^{
            it(@"should get a string",^{
              	Person *someone = [[Person alloc] init];
                NSString *statusMessage = [someone eat];
                [[statusMessage shouldNot] beNil];
                [[statusMessage should] equal:@"好饱啊"];
            });
        });
    });
    
    SPEC_END
    复制代码

3. XCTest

开发步骤

Xcode 自带的测试系统是 XCTest,使用简单。开发步骤如下

  • Tests 目录下为被测的类创建一个继承自 XCTestCase 的测试类。

  • 删除新建的测试代码模版里面的无用方法 - (void)testPerformanceExample- (void)testExample

  • 跟普通类一样,可以继承,可以写私有属性、私有方法。所以可以在新建的类里面,根据需求写一些私有属性等

  • - (void)setUp 方法里面写一些初始化、启动设置相关的代码。比如测试数据库功能的时候,写一些数据库连接池相关代码

  • 为被测类里面的每个方法写测试方法。被测类里面可能是 n 个方法,测试类里面可能是 m 个方法(m >= n),根据我们在第三部分:单元测试编码规范里讲过的 一个测试用例只测试一个分支,方法内部有 if、switch 语句时,需要为每个分支写测试用例

  • 为测试类每个方法写的测试方法有一定的规范。命名必须是 test+被测方法名。函数无参数、无返回值。比如 - (void)testSharedInstance

  • 测试方法里面的代码按照 Given->When->Then 的顺序展开。测试环境所需的先决条件准备;调用所要测试的某个方法、函数;使用断言验证输出和行为是否符合预期。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值