11. 在XCUIApplication的扩展中构建UI测试
func testLoggingInAndOut() {
XCTAssertFalse(app.userIsLoggedIn)
app.launch()
app.login()
XCTAssertTrue(app.userIsLoggedIn)
app.logout()
XCTAssertFalse(app.userIsLoggedIn)
}
func testDisplayingCategories() {
XCTAssertFalse(app.isDisplayingCategories)
app.launch()
app.login()
app.goToCategories()
XCTAssertTrue(app.isDisplayingCategories)
}
📱 大多数UI测试的逻辑都放在XCUIApplication的扩展中,这样让测试用例很容易阅读和理解。
不幸的是,大多数的项目都是靠着人工来测试,而没有使用XCode的自动测试。对于大型项目,随着业务越来越复杂,编写测试用例就势在必行了。
12. 使用.语法调用初始化方法,并且传递必包参数
class Logger {
private let storage: LogStorage
private let dateProvider: () -> Date
init(storage: LogStorage = .init(), dateProvider: @escaping () -> Date = Date.init) {
self.storage = storage
self.dateProvider = dateProvider
}
func log(event: Event) {
storage.store(event: event, date: dateProvider())
}
}
这里展示了初始化的一种方式,笔者曾今无意中写过这种语法,当时还感觉奇怪。
13. 使用===操作符进行对象比较
protocol InstanceEquatable: class, Equatable {}
extension InstanceEquatable {
static func ==(lhs: Self, rhs: Self) -> Bool {
return lhs === rhs
}
}
extension Enemy: InstanceEquatable {}
func testDestroyingEnemy() {
player.attack(enemy)
XCTAssertTrue(player.destroyedEnemies.contains(enemy))
}
===操作符可以用来判断两个对象是否是同一个对象,比较常用的场景就是判断一个数组中是否包含一个对象。
14. Referring to enum cases with associated values as closures
enum UnboxPath {
case key(String)
case keyPath(String)
}
struct UserSchema {
static let name = key("name")
static let age = key("age")
static let posts = key("posts")
private static let key = UnboxPath.key
}
15. 方法定义使用...可变的参数
extension Canvas {
func add(_ shapes: Shape...) {
shapes.forEach(add)
}
}
let circle = Circle(center: CGPoint(x: 5, y: 5), radius: 5)
let lineA = Line(start: .zero, end: CGPoint(x: 10, y: 10))
let lineB = Line(start: CGPoint(x: 0, y: 10), end: CGPoint(x: 10, y: 0))
let canvas = Canvas()
canvas.add(circle, lineA, lineB)
canvas.render()
variadic parameters,可变参数,翻译对吗?理解对吗?
👍,使用可变参数定义方法,可以创建很nice的方法,它接受一组对象作为参数,而不必使用数组。
网友评论