如何将XCTestCases暴露给外部测试包?

时间:2016-07-09 02:34:11

标签: xcode swift xctest dependency-inversion

我有一个框架Whiteboard,它封装了我的业务逻辑。我试图保持我的依赖项被反转和解耦,所以由于Whiteboard依赖于存储库,它声明了一个协议WhiteboardRepository,并且它期望与Whiteboard链接的客户端供应WhiteboardRepository的实现。

您可以在下面的屏幕截图中看到这一点。另请注意WhiteboardTests组,其中包含WhiteboardRepositoryTests类以及WhiteboardRepositoryFake及其自己的测试子类。

enter image description here

为了确保WhiteboardRepository的实现符合预期,WhiteboardTests测试包定义了WhiteboardRepositoryTests XCTestCase的子类:

class WhiteboardRepositoryTests: XCTestCase {
  var repo: WhiteboardRepository?

  override func setUp() {
    if let repo = repo {
      // test setup here
    }
  }

  // test cases here

}

为了使Whiteboard的客户端测试其WhiteboardRepository的实现,实现的测试类将WhiteboardRepositoryTests子类化,并将实现的实例提供给测试子类,然后在运行测试时使用该实例。

例如,这里是WhiteboardRepositoryFakeTests的样子:

class WhiteboardRepositoryFakeTests: WhiteboardRepositoryTests {
    override func setUp() {
        repo = WhiteboardRepositoryFake()
        super.setUp()
    }

    // the test classes run, using the instance of WhiteboardRepositoryFake()
}

这当然可行,因为WhiteboardRepositoryFakeTests位于WhiteboardTests包中,因此WhiteboardRepositoryTests会向WhiteboardRepositoryFakeTests公开。

问题是:与Whiteboard相关联的应用需要创建自己的WhiteboardRepositoryTests子类来测试自己的实现,但因为他们无法访问{{1}测试包,他们不知道WhiteboardTests类,所以不能将它子类化。

我有多个客户使用WhiteboardRepositoryTests,所以我不能简单地将Whiteboard类复制到每个客户端 - 我也不想这样做,因为它' WhiteboardRepositoryTests负责定义Whiteboard的行为,因此WhiteboardRepository应该存在于WhiteboardRepositoryTests的测试包中。在理想的世界中,我能够将Whiteboard的测试包链接或注入到客户端的测试包中,以便Whiteboard向客户端公开#&# 39;测试,但我不知道如何做到这一点。

绕过这个障碍有什么办法吗?如何将WhiteboardRepositoryTests公开给客户端测试包中的测试,以便客户端可以确保其WhiteboardRepositoryTests的实现符合预期?

1 个答案:

答案 0 :(得分:2)

这里的主要问题是WhiteboardTests目标可能是一个测试目标,并没有真正构建一个可链接的框架。这可以防止我们构建从中导入和子类化的另一个目标(您的客户端测试)。例如,您会注意到测试目标缺少用于从框架中导出符号的普通{TARGET_NAME} .h头文件。我们需要的是一个构建框架但与XCTest链接的目标。客户端项目的测试目标将与此框架链接,以导入和子类化它提供的XCTestCase类。那该怎么做:

  1. 通过单击项目文件然后编辑>在您的Whiteboard项目中创建框架构建目标。添加目标。我们暂时将此称为WhiteboardAbstractTests。该目标将与XCTest链接并构建一个框架,以提供您希望客户端项目的测试成为子类的超类。

  2. 现在,与XCTest链接有点奇怪,因为它们不再在Xcode中提供。但是,您仍然可以在Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/Library/Frameworks/XCTest.framework找到XCTest框架并将其拖到Xcode中的WhiteboardAbstractTests目标文件夹中。

  3. 从这里开始,您应该能够在WhiteboardAbstractTests中定义XCTestCase子类,这些子类将构建在WhiteboardAbstractTests.framework中。

  4. 在您的客户端项目中,我假设Whiteboard xcodeproj以某种方式嵌套,可以是Cocoapods,Carthage或git子模块。找到Whiteboard xcodeproj文件并将其拖到Xcode中的客户端项目测试目标中。

  5. 在Xcode中选择客户端项目文件,然后转到Build Phases。在Tar​​get dependencies下,单击加号按钮,您应该会看到来自Whiteboard的各种构建目标。选择WhiteboardAbstractTests。这将确保Xcode在构建客户端测试之前构建抽象测试。

  6. 同样在Build Phases中,在Link Binary With Libraries下,选择WhiteboardAbstractTests以确保我们的测试目标链接并可以从Whiteboard提供的抽象测试中导入类。

  7. 从这里开始,您应该能够在客户端项目中运行测试,这些测试将构建WhiteboardAbstractTests,将客户端测试与其链接,并运行客户端测试,这些测试将抽象测试子类化。我很快就测试了它,但如果你遇到麻烦,请告诉我。

    P.S。我喜欢你的建筑风格。在某个地方,马丁福勒流下了喜悦的泪水。