【发布时间】:2016-01-21 16:07:54
【问题描述】:
我有两个或多个接口(协议)的实现:
protocol Interface {
func methodOne()
func methodTwo()
}
我想测试每个实现,我不想重复代码。我有几个选择,但没有一个让我满意。
第一个是为ImplementationA 创建测试用例并将其子类化以获取ImplementationB 的测试用例:
class ImplementationATests: XCTestCase {
var implToTest: Interface!
override func setUp() {
super.setUp()
implToTest = ImplementationA()
}
func testMethodOne() {
...
}
func testMethodTwo() {
...
}
}
class ImplementationBTests: ImplementationATests {
override func setUp() {
super.setUp()
implToTest = ImplementationB()
}
}
这种方法的一个缺点是我不能进行仅适用于ImplementationA 的测试。 (例如,测试特定于该实现的一些辅助方法)
我想出的第二个选项是为测试用例创建共享子类:
class InterfaceTests: XCTestCase {
var implToTest: Interface!
func testMethodOne() {
...
}
func testMethodTwo() {
...
}
}
但是在这里,这些测试也会被执行,并且它们会失败,因为没有将实现分配给implToTest。当然,我可以为其分配一些实现,但是我将以两个测试用例结束相同的实现。最好的选择是以某种方式禁用InterfaceTests 测试用例并只运行它的子类。有可能吗?
我得到的第三个想法可能看起来很棘手,但它会满足我的所有需求。不幸的是,它不起作用。
我决定创建InterfaceTestable 协议:
protocol InterfaceTestable {
var implToTest: Interface! { get set }
}
并通过所有共享测试对其进行扩展:
extension InterfaceTestable {
func testMethodOne() {
...
}
func testMethodTwo() {
...
}
}
然后为每个实现创建测试用例:
class ImplementationATests: XCTestCase, InterfaceTestable {
var implToTest: Interface!
override func setUp() {
super.setUp()
implToTest = ImplementationA()
}
// some tests which only apply to ImplementationA
}
class ImplementationBTests: XCTestCase, InterfaceTestable {
var implToTest: Interface!
override func setUp() {
super.setUp()
implToTest = ImplementationB()
}
// some tests which only apply to ImplementationB
}
那些测试用例可以编译,但 Xcode 看不到在 InterfaceTestable 扩展中声明的测试。
还有其他方法可以为不同的实现共享测试吗?
【问题讨论】:
-
非常有用的问题。建议:将问题编辑为问题中的最小问题陈述。为您的 3 种方法中的每一种添加“答案”。然后人们可以投票和讨论每个人。
标签: swift unit-testing xctest