一个用于在 Swift 中管理测试固件的简单框架。
SwiftFixture 提供了一组工具,旨在帮助您轻松实例化和组织您自己的 Swift 类型的值,以便在单元测试期间用作固件。
@ProvideFixture
struct User {
let id: UUID
let name: String
let createdAt: Date
let isActive: Bool
}
func getSummary(for user: User) -> String {
if user.isActive {
return "\(user.name) is currently active!"
} else {
return "\(user.name) is not active."
}
}
class UserTests: XCTestCase {
let fixture = Fixture()
func testSummaryForActiveUser() throws {
let user: User = try fixture(isActive: true)
XCTAssertEqual(getSummary(for: user), "\(user.name) is active!")
}
}
几乎每个单元测试都需要一个固件。 简单来说,固件就是控制测试环境的一段信息。 在测试 Swift 代码时,您的类型实例就是您的固件,例如上面示例中的 user
。
随着编写的单元测试越来越多,您会发现需要初始化的值也越来越多。 这会开始变得重复,并且随着项目复杂性的增加,初始化程序参数列表也可能会增长。 最终,您可能会发现自己编写了类似这样的代码,这并不少见
func testStateForSubscribedUser() {
let user = User(
id: UUID(),
name: "ksdf",
itemCount: 0,
createdAt: Date(),
subscription: Subscription(
id: UUID(),
startedAt: Date(),
expires: Date(),
paymentMethod: .iap,
referralCode: nil
),
profileState: .complete,
avatar: nil
)
XCTAssertEqual(user.state, .subscribed)
}
func testStateForUserWithoutSubscription() {
let user = User(
id: UUID(),
name: "ksdf",
itemCount: 0,
createdAt: Date(),
subscription: nil,
profileState: .complete,
avatar: nil
)
XCTAssertEqual(user.state, .unsubscribed)
}
func testStateForUserWithExpiredSubscription() {
let user = User(
id: UUID(),
name: "ksdf",
itemCount: 0,
createdAt: Date(),
subscription: Subscription(
id: UUID(),
startedAt: Date(timeIntervalSinceReferenceDate: 0),
expires: Date(timeIntervalSinceNow: -10),
paymentMethod: .iap,
referralCode: nil
),
profileState: .complete,
avatar: nil
)
XCTAssertEqual(user.state, .expired)
}
上面三个简单的测试最终使用了比实际需要的更多的代码,并且总体而言,事情变得非常混乱。 此外,对 User
进行不相关的更改(例如添加新属性)需要我们返回并为我们初始化的每个实例添加新的默认值,而该属性甚至不应该与此测试相关联。
使用一些辅助方法,您当然可以稍微改进一下,但是当您最终必须编写自己的辅助方法时,很难做到一致。 此外,也很容易做出影响生产代码的事情,例如在主初始化程序上提供默认值。
SwiftFixture 旨在解决所有这些问题,因此您不必担心。
请查看文档以获取有关使用 SwiftFixture 的指导。
该库的灵感来自 KFixture,它是 JFixture 的 Kotlin 包装器(灵感来自 AutoFixture)。