XCTest iOS Swift单元测试

版权声明:转载请标明出处 https://blog.csdn.net/ZY_FlyWay/article/details/80943687

iOS XCTest单元格测试

XCTest iOS7的时候就接触了,可是一直也没用起来。起初的我觉得单元格测试纯属鸡肋,我们只能测试单个类的一个函数,还要自己判断期望的结果,进行验证。如果依赖关系复杂,那么就GG了。

成长是什么呢,成长是在不同阶段看待一个事物不同的看法。现在iOS 11了,从新再看到XCTest和新出的XCUITest,已不是当年的一脸嫌弃和不屑了。

记住一句话存在即合理。下面就是我从新花了1天时间学习路线(点开是链接地址):


认识 XCTest

新建项目的时候,Xcode都会问我们是否新建XCUnitTest和XCUITest。那么XCUnitTest是干什么的呢,怎么用呢,都包括什么呢。

新建项目的Tests Target 文件是这样的:

import XCTest
@testable import XCTestDemo

class XCTestDemoTests: XCTestCase {

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testExample() {
        // This is an example of a functional test case.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
    }

    func testPerformanceExample() {
        // This is an example of a performance test case.
        self.measure {
            // Put the code you want to measure the time of here.
        }
    }

}

从注释我们可以知道这四个函数的意思:

函数 用途
setUp 继承与XCTestCase 函数测试文件开始执行的时候运行
tearDown 继承与XCTestCase 测试函数运行完之后执行
testExample 测试的例子函数
testPerformanceExample 性能测试

下面XCTest 使用简单的例子

看了应该明白怎么用了


//
//  XCTestDemoTests.swift
//  XCTestDemoTests
//
//  Created by Nvr on 2018/7/6.
//  Copyright © 2018年 ZY. All rights reserved.
//

import XCTest
@testable import XCTestDemo

class XCTestDemoTests: XCTestCase {

    var f1:Float?
    var f2:Float?

    override func setUp() {
        super.setUp()
        // Put setup code here. This method is called before the invocation of each test method in the class.
        f1 = 10.0
        f2 = 20.0
    }

    override func tearDown() {
        // Put teardown code here. This method is called after the invocation of each test method in the class.
        super.tearDown()
    }

    func testExample() {
        // This is an example of a functional test case.
        // Use XCTAssert and related functions to verify your tests produce the correct results.
        XCTAssertTrue(f1! + f2! == 30.0)
    }

    //simpale Test
    func testIsPrimenumber()  {
        let oddNumber = 5
        //There are lot XCTAssert function, you can check it
        XCTAssertTrue(isPrimenumber(number: Double(oddNumber)))
    }

    func isPrimenumber(number:Double) -> Bool{
        for No in 1...Int(sqrt(number)) {
            if Int(number)/No != 0 {
                return true
            }
        }
        return false
    }

    func testPerformanceExample() {
        // This is an example of a performance test case.
        self.measure {
            // Put the code you want to measure the time of here.
        }
    }

}

例子说明:

函数 说明
testExample 全局变量f1 + f2 相加是否等于固定的数,断言是否相等
testIsPrimenumber 判断是否是素数 断言是否返回真

总结:通过上面的两个例子,应该明白了XCUintTest是干什么,怎么用的啦。

断言常用API:

API 说明
XCTFail(…) 任何尝试都会测试失败,…是输出的提示文字。(后面都是这样)
XCTAssertNil(expression, …) expression为空时通过,否则测试失败。 expression接受id类型的参数。
XCTAssertNotNil(expression, …) expression不为空时通过,否则测试失败。expression接受id类型的参数。
XCTAssert(expression, …) expression为true时通过,否则测试失败。expression接受boolean类型的参数。
XCTAssertTrue(expression, …) expression为true时通过,否则测试失败。expression接受boolean类型的参数。
XCTAssertFalse(expression, …) expression为false时通过,否则测试失败。expression接受boolean类型的参数。
XCTAssertEqualObjects(expression1, expression2, …) expression1和expression1地址相同时通过,否则测试失败。expression接受id类型的参数。
XCTAssertNotEqualObjects(expression1, expression2, …) expression1和expression1地址相同时通过,否则测试失败。expression接受id类型的参数。
XCTAssertEqual(expression1, expression2, …) expression1和expression1相等时通过,否则测试失败。expression接受基本类型的参数(数值、结构体之类的)。
XCTAssertNotEqual(expression1, expression2, …) expression1和expression1不相等时通过,否则测试失败。expression接受基本类型的参数。
XCTAssertEqualWithAccuracy(expression1, expression2, accuracy, …) expression1和expression2之间的任何值都大于accuracy时,测试失败。expression1、expression2、accuracy都为基本类型。
XCTAssertNotEqualWithAccuracy(expression1, expression2, accuracy, …) expression1和expression2之间的任何值都小于等于accuracy时,测试失败。expression1、expression2、accuracy都为基本类型。
XCTAssertGreaterThan(expression1, expression2, …) expression1 <= expression2时,测试失败。expression为基本类型
XCTAssertGreaterThanOrEqual(expression1, expression2, …) expression1 < expression2时,测试失败。expression为基本类型
XCTAssertLessThan(expression1, expression2, …) expression1 >= expression2时,测试失败。 expression为基本类型
XCTAssertLessThanOrEqual(expression1, expression2, …) expression1 > expression2时,测试失败。 expression为基本类型
XCTAssertThrows(expression, …) expression没抛异常,测试失败。expression为一个表达式
XCTAssertThrowsSpecific(expression, exception_class, …) expression没抛指定类的异常,测试失败。expression为一个表达式,exception_class为一个指定类
XCTAssertThrowsSpecificNamed(expression, exception_class, exception_name, …) expression没抛指定类、指定名字的异常,测试失败。expression为一个表达式exception_class为一个指定类,exception_name为一个指定名字
XCTAssertNoThrow(expression, …) expression抛出异常时,测试失败。expression为一个表达式
XCTAssertNoThrowSpecific(expression, exception_class, …) expression抛出指定类的异常,测试失败。expression为一个表达式
XCTAssertNoThrowSpecificNamed(expression, exception_class, exception_name, …) expression抛出指定类、指定名字的异常,测试失败。

异步测试

下面一些情况会用到异步测试:

  • 打开文档
  • 在其他线程工作
  • 和服务或者扩展进行交流
  • 网络活动
  • 动画
  • UI测试的一些条件

网络请求异步Case

关于UI的异步测试在下篇XCUITest中说,一个网络请求的Case可以说明白异步测试的机制。

  1. pod导入alamofire,Target是你要测试的tests Target.
  2. 新建期望,用alamofire 发起请求。
  3. 请求回调里断言是否为空,fullfill期望看是否满足期望
  4. XCWaiter设置期望完成的时间
func testAsynNetworkTest(){

        let networkExpection = expectation(description: "networkDownSuccess")

        Alamofire.request("http://www.httpbin.org/get?key=Xctest", method: .get, parameters: nil, encoding: JSONEncoding.default).responseJSON { (respons) in
            XCTAssertNotNil(respons)
            networkExpection.fulfill()
        }


//        waitForExpectations(timeout: 0.00000001)
//        wait(for: [networkExpection], timeout: 0.00000001)


//XCTWaiter.Result  枚举类型如下
//        public enum Result : Int {
//
//
//            case completed
//
//            case timedOut
//
//            case incorrectOrder
//
//            case invertedFulfillment
//
//            case interrupted
//        }
        let result = XCTWaiter(delegate: self).wait(for: [networkExpection], timeout:  1)
        if result == .timedOut {
            print("超时")
        }
    }

说明:下面三个函数都是设置XCWaiter等待期望时间,只是细节不同。

函数
waitForExpectations(timeout: 0.00000001)
wait(for: [networkExpection], timeout: 0.00000001)
let result = XCTWaiter(delegate: self).wait(for: [networkExpection], timeout: 0.00000001)

Mock

重点来了,我一直

猜你喜欢

转载自blog.csdn.net/ZY_FlyWay/article/details/80943687