Swift 单元测试介绍

学习ios这么久了,还没好好看过关于测试这方面的东东,一直都是真机调试,趁着学习Swift的机会,转载一篇Swift的测试教程

http://swiftist.org/topics/116#1

这篇教程将简要介绍如何在Swift项目中使用XCTest.framework进行代码单元测试。本教程中用到的示例代码托管在Github。

在介绍之前,建议大家读一这篇文章:为什么要做单元测试?

默认测试类

首先我们新建一个项目SwiftUnitTest,它将在SwiftUnitTestTests目录下自动创建出一个默认测试类(文件)SwiftUnitTestTests.swift

    import XCTest

    class SwiftUnitTestTests: XCTestCase {

        //在此可以定义测试中用到的属性

        override func setUp() {
            super.setUp()
            //在此添加准备代码。此方法在每个测试用例执行前执行
        }

        override func tearDown() {
            super.tearDown()
            //在此添加清理代码。此方法在每个测试用例执行后执行
        }

        func testExample() {
            //这是一个测试用例
            XCTAssert(true, "passed")
        }

        func testPerformanceExample() {
            //这是一个测试用例
            self.measureBlock() {
                //在此填写需要测量运行时间的代码
            }
        }

    }

在这个文件中定义了一个测试类SwiftUnitTestTests,它里面包含了一个setUp()方法和tearDown()方法,分别用来在每个测试方法运行之前做初始化准备,和在测试方法运行之后做清理工作。此外,它还包含了以test开头命名的2个测试方法:testExample()testPerformanceExample()

我们需要注意:

  • 任何以test开头命名的的方法都是一个测试方法,在每次单元测试执行时自动执行,它没有返回值;
  • 在测试方法中,可以使用self.measureBlock() { }来测量代码的运行时间;
  • 测试方法执行的顺序跟测试方法名有关,比如test01()会优先于test02()执行

通过快捷键CMD+U即可运行当前的单元测试。可以看到所有测试方法已通过:

同样,使用CMD+SHIFT+Y打开Console也能看到相应测试方法的运行提示。

定制测试类

为了更好的管理测试用例,我们建议为某个需要测试的类单独创建一个测试类(文件)。

在这之前,我们先创建一个简单的类用来测试:

        import Foundation

        class Frog {            
            var name:String

            init() {
                name = "Tadpole"
            }
            func transform() {
                name = "Frog"
            }

        }

这个类定义了一种青蛙类型,它有一个属性叫name,其初始状态为Tadpole蝌蚪。我们可以对其调用transform方法,之后它就变成了Frog青蛙。

然后我们新建一个针对青蛙类做测试的测试类:新建文件,选择Test Case Class, 为此类取名为FrogTests(建议使用<待测试类名>Tests的形式):

然后我们删除原来的testExample测试方法,并新建方法:

    func testFrogTransformation() {

        let frog = Frog()
        frog.transform()

        XCTAssert(frog.name == "Frog", "Pass")

    }

注意:如果此时Xcode提示无法找到Frog的类定义,请在顶部加上 import SwiftUnitTest。里面的SwiftUnitTest是当前项目的名称。

在此测试方法中,我们创建出了一个新的青蛙实例,然后对其调用transform()方法。这时我们使用断言XCTAssert来判断frog目前的name属性值是否为FrogXCTAssert是一个全局函数,它的第一个参数为布尔表达式,如果为true表示断言通过;它的第二个参数为断言的描述。

注意:如果实例创建比较复杂,并且需要在多个测试方法中使用。你可以在类中定义对应的实例属性,并且在setUp()方法中进行初始化,在tearDown()方法中进行资源清理。

Swift中支持ObjC中原有的所有断言:

  • XCTAssert(expression, format...)当expression求值为TRUE时通过;
  • XCTAssertTrue(expression, format...)当expression求值为TRUE时通过;
  • XCTAssertNil(a1, format...)为空判断,a1为空时通过,反之不通过;
  • XCTFail(format…) 生成一个失败的测试;
  • XCTAssertEqual(a1, a2, format...)判断相等(当a1和a2是 C语言标量、结构体或联合体时使用,实际测试发现NSString也可以);
  • ...

所有断言列表请参考ios UnitTest 学习笔记。由于大部分断言都是衍生自XCTAssert的,只使用XCTAssert能解决大部分问题。

此时执行CMD+U运行单元测试,可以看到单元测试都已通过。

然后我们再修改原有测试方法testPerformanceExample()中的内容:

    func testPerformanceExample() {
        self.measureBlock() {
            var sum:Double = 0
            for i in 1..1000000 {
                sum += Double(i)
            }
        }
    }

再次CMD+U执行单元测试,等待几秒钟,可以看到所有测试用例都已通过,打开console可以看到testPerformanceExample()中代码的运行时间:

后记

在Swift中进行单元测试跟在OC中进行单元测试的流程是一样的。但由于Swift的语法更简单,使用Swift写单元测试也变得比OC中更加有趣。


你可能感兴趣的:(Swift)