从头开始创建Marvel iOS应用。第2部分测试,覆盖率以及更多..

这是一系列文章的第二部分,介绍了如何使用许多不同的Pod和工具从头开始创建iOS应用,从而使您的生活更轻松。 如果您错过了第一部分,则可以在此处进行检查。 在这篇文章中,我将讨论测试,覆盖率报告,如何使用Fastlane自动化流程以及更多内容。

该项目的源代码可在此存储库中找到。 我为此帖子创建了一个名为v0.2的标签,您 只需克隆存储库并切换到标签v0.2。

初始步骤..

首先,我们必须确保项目具有单元测试目标,如果不是这种情况,我们可以通过单击文件>新建>目标来创建目标

测试盒..

为了正确创建测试,我将使用几个不同的测试库。 在编写测试的过程中,它们可以为我们提供很多帮助,因此,请将它们添加到我们的Podfile中。 在下面,您可以看到类似Pod的容器:Quick,Nimble,Fakery。 这些吊舱将大大增强我们进行测试的方式。

该测试并没有做太多事情,只是产生了一个期望,即true是true,并且总是会成功。 它看起来很简单,却有更大的用途。 这个断言可以告诉您一切都已正确配置和设置。

到目前为止,仅使用XCTest编写测试的人可能会感到奇怪,这种编写测试的方法是使用Expect而不是XCAssert来描述和创建断言。 但是,它更接近自然语言,因此到目前为止,它可以大大提高测试的可读性。 这就是为什么人们选择这种方法后,经过学习之后,它使编写测试变得更加容易和直观,从而增加了测试在项目中的采用率。

可以肯定的是,如果很难编写测试,则没人会编写! Quick和Nimble等测试框架的最终目标是充分降低学习曲线,以确保人们编写测试。

接下来..自动化,然后再添加复杂度..

在添加任何其他测试之前,请确保我们可以运行测试并从cmd行生成代码覆盖率报告。 这样做将确保我们正确设置所有内容,而复杂度仍然较低。 这是一种安全的措施,如果有什么不对劲,我们可以减少要找出正在发生的事情的要点。

这一步非常重要,通过使我们的开发流程自动化,我们可以放心,以后再插入连续集成过程将更加容易。

Fastlane是一个了不起的工具,可以为我们提供帮助,我们可以使用它的“扫描”操作来运行测试,然后使用Slather生成测试覆盖率报告。

抱着你的马..首先更多的设置..

在进行自动化过程之前,让我们确保每个人都在正确的页面中,这意味着,确保我们使用的是预期的快车道,cocoapods等版本。我们可以通过在项目中采用Bundler来做到这一点。 让我们创建一个像这样的Gemfile:

用Fastlane自动化..

Fastlane非常直观,我们需要做的就是运行其cmd并完成设置步骤。 完成此操作后,您会注意到一个名为fastlane的新文件夹,其中包含一些文件。 现在,让我们仅关注fastfile。

图为标签v0.2上的项目覆盖率报告, 97.16% 的确不错! 到达那里.. =)

现在,测试..

让我们从模型层开始,确保在我们的情况下可以使用它们来映射api响应,因此我们必须有一种在测试中加载json并从中创建模型的方法。

为了做到这一点,我们将在测试目标中创建一个名为MockLoader的帮助程序结构。

下一步是创建第一个真实规范,让我们创建一个CharacterSpec,以测试我们的第一个模型。

这里没有太多事情要做,但是即使是这个小小的测试也可以证明我们的模型可以用来解析我们的api响应。 即使任何一次api调用都经过一次,我们也可以放心地声明。 这就是强大而有用的测试。

手动测试这种事情,没有自动化测试,这是不好的并且容易出错。 一路上有很多地方,事情可能会横着走,并表现出异常情况,例如互联网问题,网络层问题,api调用错误等。测试可以帮助我们避免所有这些,专注于我们真正想要的东西的情况下,有一种方法可以从json创建模型。

我不会涵盖该项目中的所有测试,否则这篇文章会很大。 但是,我强烈建议您克隆项目并检查所有项目。 现在,让我们继续进行下一种测试,即视图控制器。

测试ViewController ..

一个更大的例子,还有很多事情要做。 我将设计要点,并讨论一些重要的部分。

beforeEach块是我们可以设置将要创建的所有断言和期望所需的东西的地方。

首先,我们需要恢复我们要测试的控制器,我们可以使用Storyboard枚举轻松地做到这一点。 接下来,我们需要模拟api,这将确保我们在不依赖网络的情况下运行,例如,我们可以使用setter注入来实现。 从这一刻起,api调用将由我们的模拟类处理,该模拟类将返回从文件加载的Json。

这是单元测试的关键 ,它们必须在受控的环境中运行,这意味着没有网络调用,没有数据库等。

我们需要再做一件事,这是食谱的一部分,以确保我们所有的视图组件都已准备就绪。 波纹管指令具有此目的。

  //加载视图组件 
让_ = controller.view

其他测试很直观,它们在项目之间会发生很大的变化,我不会详细介绍它们。 但是,这里有一个重要的教训,您是否想知道接下来要测试 什么? 答案实际上很简单,在覆盖率报告中寻找提示。 该报告将显示未涵盖的项目区域,功能等。 对我来说,就是最佳利用覆盖率报告。 它本身不仅仅是一个指标,它应被用来指导您的测试,以及您的测试应被用来重构和改进我们的代码。

免责声明:**如果您像我一样来自Objective-C,您可能想知道为什么我不使用模拟框架,请相信我,我也对此进行了质询。 Altought swift有一些模拟吊舱,如果您在代码中采用协议,则实际上并不需要它们。 您需要做的就是像我上面所做的那样,在测试目标中创建符合协议的自定义类和结构,并用实际的实现代替。 这种方法将使一切变得更加简单。 确实,某些事情很难快速完成,OCMock的旧的部分模拟非常方便。 就是说,Swift的社区坚持只测试公共内容的理念,如果您的测试过期不佳,也许您真正需要的是专注于重构实现。

测试数据源..

该项目利用了一种称为“外部数据源”的技术,这种方法缺乏更好的命名,实际上只是从视图控制器中删除数据源并委托逻辑的一种方法,从而避免了在此过程中使用太多的责任。 这种设计还有其他好处,如本教程的第1部分所述。

我将在没有更多说明的情况下安排数据源和委托的测试布局,没有什么真正的新内容。

最后的话 ..

在这篇文章中,我已经设计了几种技术和工具,可以将这些技术和工具整合到您的项目中,以便对其进行测试并提高其质量。 测试会在您的代码周围创建一个安全网,您真正可以信任的安全网会在以后推出。 从现在开始的六个月,当没有人真正记得实现细节时,您将有信心进行更改,只要没有测试失败,一切都会按预期运行, 这本身就是无价的

下一篇文章将介绍持续集成以及为什么要在项目中使用它。 同时还将介绍一个名为“危险”的工具,以及如何使用它来改善您的存储库下的团队协作。

免责声明:**对于执行以下步骤的人员来说,克隆项目并进行操作绝对重要,我无法在单个帖子中传达所有信息,否则将非常庞大且难以理解。

与往常一样,任何想法,疑问或反馈都值得欢迎。 =)

附:如果您喜欢这篇文章,请在Twitter上分享,或在中级推荐,或两者都=)。 这确实有助于我吸引更多人。 非常感谢 ..

更新:**您可以在此处查看本教程的第三部分。