如何将 XCTestCases 公开给外部测试包?
How to expose XCTestCases to external test bundles?
我有一个框架 Whiteboard
封装了我的业务逻辑。我试图保持我的依赖倒置和解耦,所以由于 Whiteboard
依赖于存储库,它声明了一个协议 WhiteboardRepository
,并且它期望客户端 link 反对 Whiteboard
提供 WhiteboardRepository
.
的实现
您可以在下面的屏幕截图中看到这一点。还要注意 WhiteboardTests
组,其中包括一个 WhiteboardRepositoryTests
class 以及一个 WhiteboardRepositoryFake
和它自己的测试子 class.
为了确保 WhiteboardRepository
的实现按预期运行,WhiteboardTests
测试包定义了 XCTestCase
的 WhiteboardRepositoryTests
subclass:
class WhiteboardRepositoryTests: XCTestCase {
var repo: WhiteboardRepository?
override func setUp() {
if let repo = repo {
// test setup here
}
}
// test cases here
}
为了让 Whiteboard
的客户端测试其 WhiteboardRepository
的实现,实现子 class 的测试 class 是 WhiteboardRepositoryTests
并向测试子 class 提供一个实现实例,然后在 运行 测试时使用该实例。
例如,WhiteboardRepositoryFakeTests
看起来像这样:
class WhiteboardRepositoryFakeTests: WhiteboardRepositoryTests {
override func setUp() {
repo = WhiteboardRepositoryFake()
super.setUp()
}
// the test classes run, using the instance of WhiteboardRepositoryFake()
}
当然,这很好用,因为 WhiteboardRepositoryFakeTests
在 WhiteboardTests
包中,所以 WhiteboardRepositoryTests
暴露给 WhiteboardRepositoryFakeTests
。
问题是:link 反对 Whiteboard
的应用需要创建自己的 WhiteboardRepositoryTests
的子 class 来测试自己的实现,但是因为他们不无法访问 WhiteboardTests
测试包,他们不知道 WhiteboardRepositoryTests
class,因此无法子 class 它。
我有多个客户端使用 Whiteboard
,所以我不能简单地将 WhiteboardRepositoryTests
class 复制到每个客户端中 — 我也不想这样做,因为它是Whiteboard
有责任定义 WhiteboardRepository
的行为,因此 WhiteboardRepositoryTests
应该存在于 Whiteboard
的测试包中。在理想情况下,我可以 link 或将 Whiteboard
的测试包注入客户端的测试包,以便 WhiteboardRepositoryTests
暴露给客户端的测试,但我不这样做不知道我该怎么做。
有什么办法绕过这个障碍吗?我如何将 WhiteboardRepositoryTests
公开给客户端测试包中的测试,以便客户端可以确保其 WhiteboardRepository
的实现按预期运行?
这里的主要问题是 WhiteboardTests 目标可能是一个测试目标,实际上并没有构建一个 linkable 框架。这可以防止我们构建另一个从中导入和子类化的目标(您的客户端测试)。例如,您会注意到测试目标缺少用于从框架导出符号的正常 {TARGET_NAME}.h 头文件。我们需要的是构建框架但 link 带有 XCTest 的目标。客户项目的测试目标将 link 使用此框架来导入和子类化它提供的 XCTestCase 类。那么怎么办:
单击项目文件,然后单击编辑器 > 添加目标,在白板项目中创建框架构建目标。我们暂时将此称为 WhiteboardAbstractTests。该目标将 link 与 XCTest 一起构建一个框架来提供您希望客户项目的测试子类化的超级类。
现在,使用 XCTest link 有点奇怪,因为它们不再使它在 Xcode 中可用。但是,您仍然可以在 Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework
找到 XCTest 框架并将其拖到 Xcode.
的 WhiteboardAbstractTests 目标文件夹中
从这里开始,您应该能够在 WhiteboardAbstractTests 中定义 XCTestCase sub类,它将构建到 WhiteboardAbstractTests.framework.
在您的客户端项目中,我假设 Whiteboard xcodeproj 以某种方式嵌套,由 Cocoapods、Carthage 或 git 子模块嵌套。找到Whiteboard xcodeproj文件,拖入Xcode中的客户端项目测试目标。
Select Xcode 中的客户端项目文件,然后转到构建阶段。在 Target dependencies 下,单击加号按钮,您应该会看到来自 Whiteboard 的各种构建目标。 Select 白板抽象测试。这将确保 Xcode 在构建客户端测试之前构建抽象测试。
同样在构建阶段,在 Link Binary With Libraries 下,select WhiteboardAbstractTests 以确保我们的测试目标 link 具有并且可以导入 类 来自 Whiteboard 提供的抽象测试。
从这里您应该能够 运行 您的客户端项目中的测试将构建 WhiteboardAbstractTests,link 您的客户端使用它进行测试,并且 运行 您的客户端测试哪个子类抽象测试。我已经快速测试过了,但如果您遇到问题,请告诉我。
P.S。我喜欢你的建筑风格。 Martin Fowler 在某处流下了喜悦的泪水。
我有一个框架 Whiteboard
封装了我的业务逻辑。我试图保持我的依赖倒置和解耦,所以由于 Whiteboard
依赖于存储库,它声明了一个协议 WhiteboardRepository
,并且它期望客户端 link 反对 Whiteboard
提供 WhiteboardRepository
.
您可以在下面的屏幕截图中看到这一点。还要注意 WhiteboardTests
组,其中包括一个 WhiteboardRepositoryTests
class 以及一个 WhiteboardRepositoryFake
和它自己的测试子 class.
为了确保 WhiteboardRepository
的实现按预期运行,WhiteboardTests
测试包定义了 XCTestCase
的 WhiteboardRepositoryTests
subclass:
class WhiteboardRepositoryTests: XCTestCase {
var repo: WhiteboardRepository?
override func setUp() {
if let repo = repo {
// test setup here
}
}
// test cases here
}
为了让 Whiteboard
的客户端测试其 WhiteboardRepository
的实现,实现子 class 的测试 class 是 WhiteboardRepositoryTests
并向测试子 class 提供一个实现实例,然后在 运行 测试时使用该实例。
例如,WhiteboardRepositoryFakeTests
看起来像这样:
class WhiteboardRepositoryFakeTests: WhiteboardRepositoryTests {
override func setUp() {
repo = WhiteboardRepositoryFake()
super.setUp()
}
// the test classes run, using the instance of WhiteboardRepositoryFake()
}
当然,这很好用,因为 WhiteboardRepositoryFakeTests
在 WhiteboardTests
包中,所以 WhiteboardRepositoryTests
暴露给 WhiteboardRepositoryFakeTests
。
问题是:link 反对 Whiteboard
的应用需要创建自己的 WhiteboardRepositoryTests
的子 class 来测试自己的实现,但是因为他们不无法访问 WhiteboardTests
测试包,他们不知道 WhiteboardRepositoryTests
class,因此无法子 class 它。
我有多个客户端使用 Whiteboard
,所以我不能简单地将 WhiteboardRepositoryTests
class 复制到每个客户端中 — 我也不想这样做,因为它是Whiteboard
有责任定义 WhiteboardRepository
的行为,因此 WhiteboardRepositoryTests
应该存在于 Whiteboard
的测试包中。在理想情况下,我可以 link 或将 Whiteboard
的测试包注入客户端的测试包,以便 WhiteboardRepositoryTests
暴露给客户端的测试,但我不这样做不知道我该怎么做。
有什么办法绕过这个障碍吗?我如何将 WhiteboardRepositoryTests
公开给客户端测试包中的测试,以便客户端可以确保其 WhiteboardRepository
的实现按预期运行?
这里的主要问题是 WhiteboardTests 目标可能是一个测试目标,实际上并没有构建一个 linkable 框架。这可以防止我们构建另一个从中导入和子类化的目标(您的客户端测试)。例如,您会注意到测试目标缺少用于从框架导出符号的正常 {TARGET_NAME}.h 头文件。我们需要的是构建框架但 link 带有 XCTest 的目标。客户项目的测试目标将 link 使用此框架来导入和子类化它提供的 XCTestCase 类。那么怎么办:
单击项目文件,然后单击编辑器 > 添加目标,在白板项目中创建框架构建目标。我们暂时将此称为 WhiteboardAbstractTests。该目标将 link 与 XCTest 一起构建一个框架来提供您希望客户项目的测试子类化的超级类。
现在,使用 XCTest link 有点奇怪,因为它们不再使它在 Xcode 中可用。但是,您仍然可以在
Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework
找到 XCTest 框架并将其拖到 Xcode. 的 WhiteboardAbstractTests 目标文件夹中
从这里开始,您应该能够在 WhiteboardAbstractTests 中定义 XCTestCase sub类,它将构建到 WhiteboardAbstractTests.framework.
在您的客户端项目中,我假设 Whiteboard xcodeproj 以某种方式嵌套,由 Cocoapods、Carthage 或 git 子模块嵌套。找到Whiteboard xcodeproj文件,拖入Xcode中的客户端项目测试目标。
Select Xcode 中的客户端项目文件,然后转到构建阶段。在 Target dependencies 下,单击加号按钮,您应该会看到来自 Whiteboard 的各种构建目标。 Select 白板抽象测试。这将确保 Xcode 在构建客户端测试之前构建抽象测试。
同样在构建阶段,在 Link Binary With Libraries 下,select WhiteboardAbstractTests 以确保我们的测试目标 link 具有并且可以导入 类 来自 Whiteboard 提供的抽象测试。
从这里您应该能够 运行 您的客户端项目中的测试将构建 WhiteboardAbstractTests,link 您的客户端使用它进行测试,并且 运行 您的客户端测试哪个子类抽象测试。我已经快速测试过了,但如果您遇到问题,请告诉我。
P.S。我喜欢你的建筑风格。 Martin Fowler 在某处流下了喜悦的泪水。