• 软件测试技术之iOS 单元测试—逻辑测试


    单元测试分为3种:

    逻辑测试:测试逻辑方法

    异步测试:测试耗时方法(用来测试包含多线程的方法)

    性能测试:测试某一方法运行所消耗的时间

    本节介绍逻辑测试,直接创建一个项目,并选中Include Unit Tests选项。

    创建工程时选中Unit Tests.png

    1.新建一个Person类,提供字典转模型的方法,这个方法就是需要进行单元测试的:

    + (instancetype)personWithDict:(NSDictionary *)dict;//字典转模型方法

    字典转模型方法的单元测试.png

    原始的Person.m文件:

    #import ““Person.h””

    @implementation Person

    • (instancetype)personWithDict:(NSDictionary *)dict {

    Person *obj = [[self alloc] init];

    [obj setValuesForKeysWithDictionary:dict];

    return obj;

    }

    @end

    2.下面,我们打开单元测试Tests黄色虚拟文件夹,然后Command+N 创建一个单元测试文件。文件命名格式:类名+Tests,继承自:XCTestCase

    新建一个Unit Test文件.png

    单元测试文件的命名格式.png

    创建完毕,可以看到Tests文件里有如下4个方法:

    单元测试开始前,先了解几个知识点:

    单元测试是以代码测试代码

    红灯/绿灯迭代测试开发

    自己建立测试用例(使用例子数据,专门检查边界点)

    单元测试不是靠 NSLog 来测试,NSLog 是程序员用眼睛看的笨办法。

    使用 断言 来测试的,提前预判条件必须满足!

    XCTAssert(expression, …)

    XCTAssert(条件, 不满足条件的描述)

    3.准备工作已完成,下面正式开始单元测试:

    导入Person.h头文件,仿照文件自带的 - (void)testExample {} 格式,写这样一个逻辑测试方法:- (void)testNewPerson {} ,然后Command+S保存,左边会出现菱形白色方框,它就是执行单元调试的按钮??,在调试过程中,我们需要反复点击这个按钮去调试。方法里书写测试代码。

    PersonTests.m文件:

    // 逻辑测试方法

    • (void)testNewPerson {

    // 1.测试 name和age 是否一致

    [self checkPersonWithDict:@{@““name””😡““zhou””, @““age””:@30}];

    /** 2.测试出 age 不符合实际,那么需要在字典转模型方法中对age加以判断:

    if (obj.age <= 0 || obj.age >= 130) {

    obj.age = 0;

    }

    */

    [self checkPersonWithDict:@{@““name””😡““zhang””,@““age””:@200}];

    // 3.测试出 name 为nil的情况,因此在XCTAssert里添加条件:“person.name == nil“

    [self checkPersonWithDict:@{}];

    // 4.测试出 Person类中没有 title 这个key,在字典转模型方法中实现:- (void)setValue:(id)value forUndefinedKey:(NSString *)key {}

    [self checkPersonWithDict:@{@““name””😡““zhou””, @““age””:@30, @““title””😡““boss””}];

    // 5.总体再验证一遍,结果Build Succeeded,测试全部通过

    [self checkPersonWithDict:@{@““name””😡““zhou””, @““age””😡-1, @““title””😡““boss””}];

    // 到目前为止 Person 的 工厂方法测试完成!?

    }

    // 根据字典检查新建的 person 信息

    • (void)checkPersonWithDict:(NSDictionary *)dict {

    Person *person = [Person personWithDict:dict];

    NSLog(@“”%@“”,person);

    // 获取字典中的信息

    NSString *name = dict[@““name””];

    NSInteger age = [dict[@““age””] integerValue];

    // 1.检查名字

    XCTAssert([name isEqualToString:person.name] || person.name == nil, @““姓名不一致””);

    // 2.检查年龄

    if (person.age > 0 && person.age < 130) {

    XCTAssert(age == person.age, @““年龄不一致””);

    } else {

    XCTAssert(person.age == 0, @““年龄超限””);

    }

    }

    最好调试修改后的Person.m文件:

    #import ““Person.h””

    @implementation Person

    • (instancetype)personWithDict:(NSDictionary *)dict {

    Person *obj = [[self alloc] init];

    [obj setValuesForKeysWithDictionary:dict];

    // 预防处理age超限

    if (obj.age <= 0 || obj.age >= 130) {

    obj.age = 0;

    }

    return obj;

    }

    // 预防处理没有找到的key

    • (void)setValue:(id)value forUndefinedKey:(NSString *)key {}

    @end

    注意事项:

    不是所有的方法都需要测试。

    例如:私有方法不需要测试!只有暴露在 .h 中的方法需要测试!面向对象有一个原则:开闭原则!

    所有跟 UI 有关的都不需要测试,也不好测试。

    把 业务逻辑 代码封装出来!变成可以测试的代码,让程序更加健壮!

    一般而言,代码的覆盖度大概在 50% ~ 70%

    从github上得知:YYModel测试覆盖度为83%,AFNetworking测试覆盖度为77%,两者都是比较高的。

    文章来源:网络 版权归原作者所有

    上文内容不用于商业目的,如涉及知识产权问题,请权利人联系小编,我们将立即处理

  • 相关阅读:
    聊聊API安全的重要性及治理思路
    axios封装get,post请求, 原生xhr ajax封装同步请求
    Vue3 项目中 vue文件出现大面积爆红问题
    甘露糖-顺铂mannose-cisplatin|甘露糖-聚乙二醇-顺铂cisplatin-PEG-mannose
    【Verilog基础】【计算机体系结构】cache读写操作
    自动控制原理3.3---二阶系统的时域分析
    R语言使用is.vector函数判断数据对象是否是向量数据类型vector
    利用芯片74hc165为单片机增加输入扩展端口proteus仿真arduino
    自动化之python面试
    【Kafka专栏 12】实时数据流与任务队列的较量 :Kafka与RabbitMQ有什么不同
  • 原文地址:https://blog.csdn.net/xuezhangmen/article/details/126580073