1. iOS模块化第三部分:模块配置和测试

在本系列的前几篇文章中,我讨论了将iOS代码基拆分为模块的好处以及如何实现这一点。我建议在继续这篇文章之前阅读这些文章。😎

在本文中,我将介绍:

  • 使用多个模块设置CocoaPods
  • 测试功能模块作为主应用程序的一部分
  • 在模块之间共享测试逻辑

我将在iOS模块化系列的最后一篇文章中保存模块间的共享配置

1.1. Setting up CocoaPods with multiple modules

如果您使用CocoaPods,您需要确保为每个需要它们的目标安装依赖项。所有的依赖都必须安装到主应用程序目标上。

为了避免在多个地方更新pod版本号,最好定义可重用的方法。假设一个Podfile就是Ruby,你可以这样做:

# sources
source 'https://github.com/CocoaPods/Specs.git'

# global config
platform :ios, '11.0'
use_frameworks!
workspace 'FunkySocial'

# methods to ensure the same version of each library is used across targets

def networkAndParsingPods
  pod 'JSONUtilities', '5.0.0'
  pod 'TABResourceLoader', '7.2.1'
end

def uiPods
  pod 'AdobeMobileSDK', '~> 4.13'
end

# targets

target 'FunkySocial' do
  project 'FunkySocial/FunkySocial'
  networkAndParsingPods
  uiPods
  target 'FunkySocialTests' do
  end
end

target 'ProfileUI' do
  project 'ProfileUI'
  uiPods
  target 'ProfileUITests' do
  end
end

target 'Profile' do
  project 'Profile'
  networkAndParsingPods
  target 'ProfileTests' do
  end
end

参见上面Podfile中的networkAndParsingPods和uiPods方法。它们在目标部分中被引用。这消除了重复的pod 引用,并避免任何机会的pod版本的差异。

1.2. Testing feature modules as part of the main app

通常,你会希望在主应用程序的单元测试执行时为你的特性模块运行单元测试。这意味着在开发时,您不需要切换方案来测试不同的特性模块。在持续集成方面,只需指定要执行的单个方案的单元测试,所有依赖模块的测试将同时运行。

您可以通过编辑main scheme 来实现这一点。

avatar

选择你的scheme(如上图中的FunkySocial),然后点击编辑Scheme…

从左边的面板中选择Test,并选择出现在右边面板底部的+按钮。

在接下来出现的窗口中,选择希望与主应用程序的测试同时运行的所有测试目标。

avatar

当你选择了所有的测试目标,点击Add。

你最终会得到这样的结果:

avatar

1.3. Sharing test logic between modules

就像我们在模块之间共享公共产品代码一样,通过从公共模块公开它,可能需要共享公共测试逻辑。我们不想把它放在Common中,因为它不是生产代码。

因此,我们将所有共享测试逻辑定义在TestHelpers模块中。

此模块可能包含从文件加载模拟JSON或创建共享模拟对象等函数。

将TestHelpers模块链接到你的测试目标与将特性模块嵌入你的主应用程序略有不同

选择Test target,例如ProfileTests。您将在General选项卡上注意到,没有办法添加嵌入式二进制文件或链接框架。

相反,请转到Build Phases选项卡。展开the Link Binary with Libraries部分,并点击+按钮。你会看到如下对话:

avatar

搜索你的TestHelpers模块,然后点击Add。

对需要在其中共享代码的每个模块执行此操作。

1.4. Coming up next

在本系列的下一篇文章中,我将介绍一种在主应用程序和特性模块之间共享配置的健壮的、经过尝试和测试的方法,以及如何注入该配置以进行单元测试。