学习资料
- 苹果官方介绍
- 苹果官方文档
- Quick文档
Xcode单元测试基本用法
- 整体测试
command + u,或者Xcode -> Product -> Test
- 测试标签栏
- 添加新的测试Target或官方测试类的快捷方式
- 局部测试快捷方式
注意
:
在用Xcode写测试类,引用app target中的变量、方法或类时,有时没有提示.原因是,你刚刚为app target 中的文件添加的变量、方法或类还没有被编译器识别,Command + B 编译一下就好.
Quick进一步介绍
控件测试
控件测试的基本思路是:通过触发控制器生命周期的相关事件来测试.
我们通过三种方法来触发:
- 访问控制器的view,这会触发诸如控制器的.viewDidLoad()
- 通过控制器.beginAppearanceTransition()来触发大部分生命周期事件
- 直接调用.viewDidLoad()或者.viewWillAppear()来触发
ViewController.swift
import UIKit
public class ViewController: UIViewController {
public var bananaCountLabel : UILabel!
public var button : UIButton!
override public func viewDidLoad() {
super.viewDidLoad()
bananaCountLabel = UILabel(frame: CGRect(x: 100, y: 100, width: 100, height: 40))
view.addSubview(bananaCountLabel!)
bananaCountLabel.text = "0"
bananaCountLabel.backgroundColor = UIColor.orangeColor()
button = UIButton(type: .Custom)
view.addSubview(button)
button.frame = CGRect(x: 100, y: 200, width: 100, height: 40)
button.backgroundColor = UIColor.blackColor()
button.setTitle("Button", forState: .Normal)
button.addTarget(self, action: "buttonAction", forControlEvents: .TouchUpInside)
}
func buttonAction() {
let bananaCount = Int(bananaCountLabel.text!)
bananaCountLabel.text = String(bananaCount! + 1)
}
override public func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
ViewControllerSpec.swift
import Quick
import Nimble
import UseQuick
class BananaViewControllerSpec: QuickSpec {
override func spec() {
var viewController : ViewController!
beforeEach { () -> Void in
viewController = ViewController()
// // storyboard初始化
// let storyboard = UIStoryboard(name: "main", bundle: nil)
// viewController = storyboard.instantiateViewControllerWithIdentifier("ViewController") as! ViewController
}
// #1
describe(".viewDidLoad()", { () -> Void in
beforeEach({ () -> () in
// 方法1: 访问控制器的view,来触发控制器的 .viewDidLoad()
let _ = viewController.view
})
it("sets banana count label to zero", closure: { () -> () in
print(viewController.bananaCountLabel.text)
expect(viewController.bananaCountLabel.text).to(equal("0"))
})
})
// #2
describe("the view", { () -> Void in
beforeEach({ () -> Void in
// 方法2: 触发.viewDidLoad(), .viewWillAppear(), 和 .viewDidAppear() 事件
viewController.beginAppearanceTransition(true, animated: false)
viewController.endAppearanceTransition()
})
it("sets banana count label to zero", closure: { () -> () in
expect(viewController.bananaCountLabel.text).to(equal("10"))
})
})
// #3
describe(".viewDidLoad()", { () -> Void in
beforeEach({ () -> () in
// 方法3: 直接调用生命周期事件
viewController.viewDidLoad()
})
it("sets banana count label to zero", closure: { () -> () in
expect(viewController.bananaCountLabel.text).to(equal("10"))
})
})
// 测试UIControl事件
describe("the more banana button") { () -> () in
beforeEach({ () -> Void in
viewController.viewDidLoad()
})
it("increments the banana count label when tapped", closure: { () -> () in
viewController.button.sendActionsForControlEvents(.TouchUpInside)
expect(viewController.bananaCountLabel.text).to(equal("1"))
})
}
}
}
减少冗余测试文件
如果我们在不同的测试文件中,用到了相同的测试行为,应该考虑用sharedExamples
.
比如,不同的类遵循了相同的协议,我们要测试这个协议下不同类的表现.
Dolphin.swift
public struct Click {
public var isLoud = true
public var hasHighFrequency = true
public func count() -> Int {
return 1
}
}
public class Dolphin {
public var isFriendly = true
public var isSmart = true
public var isHappy = false
public init() {
}
public init(happy: Bool) {
isHappy = happy
}
public func click() -> Click {
return Click()
}
public func eat(food: AnyObject) {
isHappy = true
}
}
Mackerel.swift
public class Mackerel {
public init() {
}
}
Cod.swift
public class Cod {
public init() {
}
}
EdibleSharedExamplesConfiguration.swift
import Quick
import Nimble
import UseQuick
class EdibleSharedExamplesConfiguration: QuickConfiguration {
override class func configure(configuration: Configuration) {
sharedExamples("something edible") { (sharedExampleContext : SharedExampleContext) -> Void in
it("makes dolphins happy", closure: { () -> () in
let dolphin = Dolphin(happy: false)
let edible = sharedExampleContext()["edible"]
dolphin.eat(edible!)
expect(dolphin.isHappy).to(beFalsy())
})
}
}
}
MackerelSpec.swift
import Quick
import Nimble
import UseQuick
class MackerelSpec: QuickSpec {
override func spec() {
var mackerel : Mackerel!
beforeEach { () -> () in
mackerel = Mackerel()
}
itBehavesLike("something edible") { () -> (NSDictionary) in
["edible" : mackerel]
}
}
}
CodSpec.swift
import Quick
import Nimble
import UseQuick
class CodSpec: QuickSpec {
override func spec() {
var cod : Cod!
beforeEach { () -> () in
cod = Cod()
}
itBehavesLike("something edible") { () -> (NSDictionary) in
["edible" : cod]
}
}
}
Quick介绍到此告一段落,谢谢阅读!
下载源码
下载地址