单元测试详解

作者: 江水东流 | 来源:发表于2016-10-24 15:46 被阅读100次

只有优秀的程序员才关心产品,只有优秀的程序员才在乎程序的性能,我们要具备性能测试和性能优化的能力,今天开始我开始给大家写一写介绍性能方面的文章,今天写单元测试.

单元测试简介如下:

  1. 单元测试是以代码测试代码
  2. 红灯/绿灯迭代开发
  3. 在日常开发中,数据大部分来自于网络,很难出现所有的边界数据!如果没有测试所有条件就上架
    在运行时造成闪退!
  4. 自己建立测试用例(使用的例子数据,专门检查边界点)
  5. 单元测试不是靠 NSLog 来测试,NSLog 是程序员用眼睛看的笨办法。

提示:

  1. 不是所有的方法都需要测试
    例如:私有方法不需要测试!只有暴露在 .h 中的方法需要测试!面向对象有一个原则:开闭原则!
  2. 所有跟 UI 有关的都不需要测试,也不好测试!
    MVVM,把 小的业务逻辑 代码封装出来!变成可以测试的代码,让程序更加健壮!
  3. 一般而言,代码的覆盖度大概在 50% ~ 70%

demo github地址 https://github.com/1271284056/Unit-test-Demo
希望大家多给点星星~~

  1. 创建项目时候勾选下面的Include Unit Tests


    屏幕快照 2016-10-24 10.08.08.png
  2. 如果创建项目时候没勾选这个选项,通过下图操作为项目添加单元测试.

1448355504907178.png 1448355510545176.png
  1. 在单元测试文件夹新建测试类
屏幕快照 2016-10-24 11.53.40.png
  1. 首先建立测试类Person类,建立它的初始化方法,以及异步方法.

Preson.h

import <Foundation/Foundation.h>

@interface Person : NSObject
@property (nonatomic, copy) NSString *name;
@property (nonatomic) NSInteger age;

  • (instancetype)personWithDict:(NSDictionary *)dict;
    /// 异步加载个人记录
  • (void)loadPersonAsync:(void (^)(Person *person))completion;
    @end

Preson.m

import "Person.h"

@implementation Person

  • (instancetype)personWithDict:(NSDictionary *)dict {
    Person *obj = [[self alloc] init];
    [obj setValuesForKeysWithDictionary:dict];
    if (obj.age <= 0 || obj.age >= 130) {
    obj.age = 0;
    }
    return obj;
    }
  • (void)setValue:(id)value forUndefinedKey:(NSString *)key {}
  • (void)loadPersonAsync:(void (^)(Person *))completion {
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
    [NSThread sleepForTimeInterval:1.0];
    Person *person = [Person personWithDict:@{@"name": @"z", @"age": @5}];
    dispatch_async(dispatch_get_main_queue(), ^{
    if (completion != nil) {
    completion(person);
    }
    });
    });
    }

单元测试方法名都以test开头,写完后左边会有一个菱形,点击菱形,运行变成绿色就是成功,红色表示失败.

  • (void)testNewPerson {
    [self checkPersonWithDict:@{@"name": @"zhang", @"age": @20}];
    [self checkPersonWithDict:@{@"name": @"zhang"}];
    [self checkPersonWithDict:@{}];
    [self checkPersonWithDict:@{@"name": @"zhang", @"age": @20, @"title": @"boss"}];
    [self checkPersonWithDict:@{@"name": @"zhang", @"age": @200, @"title": @"boss"}];
    [self checkPersonWithDict:@{@"name": @"zhang", @"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, @"年龄超限");
    }
    }

异步单元测试

/**
苹果的单元测试是串行的
setUp
testXXX1
testXXX2
testXXX3
tearDown
中间不会等待异步的回调完成
*/

/// 测试异步加载 Person

  • (void)testLoadPersonAsync {
    // Xcode 6.0 开始解决 Expectation 预期
    XCTestExpectation *expectation = [self expectationWithDescription:@"异步加载 Person"];
    [Person loadPersonAsync:^(Person *person) {
    NSLog(@"%@", person.name);
    // 标注预期达成
    [expectation fulfill];
    }];
    // 等待 10s 期望预期达成 10秒后如果执行到[expectation fulfill]这里表面单元测试成功
    [self waitForExpectationsWithTimeout:10.0 handler:nil];
    }

性能测试

以前我们测试一个函数执行时间,在开始时候定义起始时间
NSTimeInterval start = CACurrentMediaTime();
函数执行完毕后计算时间
NSLog(@"%f", CACurrentMediaTime() - start);
单元测试为我们提供一个- (void)testPerformanceExample {}函数,在这个函数的 [self measureBlock:^{}] 中写耗时操作, 相同的代码重复执行 10 次,统计计算时间,平均时间在控制台打印出来!
// Performance 性能!

/*
性能测试代码一旦写好,可以随时测试!
*/

  • (void)testPerformanceExample {
    // This is an example of a performance test case.
    [self measureBlock:^{
    // Put the code you want to measure the time of here.
    // 将需要测量执行时间的代码放在此处!
    for (int i = 0; i < 10000; i++) {
    [Person personWithDict:@{@"name": @"zhang", @"age": @20}];
    }
    }];
    }

相关文章

  • ESLint和Mocha

    javascript单元测试框架mochajs详解

  • 上手unittest读这篇文章就够了

    引言 本文主要介绍了如下内容 单元测试的定义; python中如何写基础的unittest单元测试; 详解unit...

  • Spring Boot 单元测试

    文章分为两部分: 创建单元测试 单元测试类详解 一、创建单元测试 在类名上右键 选择你要使用的测试库、要测试的方法...

  • iOS测试

    [iOS 单元测试之XCTest详解](http://blog.csdn.net/hello_hwc/articl...

  • iOS 单元测试之XCTest详解

    参考自:iOS 单元测试之XCTest详解 原创blog,转载请注明出处 blog.csdn.net/hello_...

  • 单元测试详解

    只有优秀的程序员才关心产品,只有优秀的程序员才在乎程序的性能,我们要具备性能测试和性能优化的能力,今天开始我开始给...

  • Android单元测试详解

    前言:要做单元测试,首先要明白,什么是单元测试。关于单元测试的相关内容,这里就不多做介绍了,若要了解单元测试的相关...

  • iOS单元测试详解

    简介 测试目的:模拟多种可能性,减少错误,增强健壮性,提高稳定性。 测试种类:在iOS中的通常分为单元测试和UI测...

  • Springboot 单元测试详解

    1.Springboot的测试类库 SpringBoot 提供了许多实用工具和注解来帮助测试应用程序,主要包括以下...

  • JUnit单元测试使用详解

    本文中所讨论的JUnit测试框架基于JUnit4.x。并且将通过Android Studio来讲解JUnit的使用...

网友评论

    本文标题:单元测试详解

    本文链接:https://www.haomeiwen.com/subject/moafuttx.html