Tag: 测试

如何在iOS应用中利用验收测试

与后端开发等其他领域相比,移动开发是一门新兴的学科。 由于苹果很长一段时间都不关心测试,因此社区开始进行测试的时间很晚。 最初,我们有单元测试工具,我研究过Swift中的单元测试和Objective-C中的单元测试。 进行单元测试很棒,但是顾名思义,它只是测试单元。 因此,我们继续寻找并找到了黄金大师测试。 另一个提高我们质量的好工具。 最后,我们可以确保我们的用户界面是正确的。 但是拥有正确的UI是否意味着我们的应用正在执行应做的事情? 那么,我们应该如何测试整个应用程序呢? 我们已经进行了UI测试。 太好了,我们可以确保我们的应用正确无误。 为我们的应用程序编写了一系列测试,大概两年了(包括2个iOS和Xcode更新),我们意识到: UI测试缓慢,不稳定且难以维护 这么结束了吗? 我们必须忍受这些缓慢的测试,还是可以以某种方式改进它们? 让我们看一下UI测试为什么会这样。 UI测试 速度 Apple在UI测试中的解决方案是运行两个单独的进程。 每当测试请求XCUIElement时,TestProcess都会从原始应用程序获取整个应用程序状态。 然后它将执行整个状态的搜索查询,并列出所有匹配的元素(通常只有一个,但是在找到第一个元素之后仍会继续)。 知道了所有这些步骤之后,我们就可以知道在此架构内的时间: 将AppState创建为XCTest的树 将AppState传输到TestProcess 查询整个AppState 使用Xcode 9,情况发生了一些变化。 它不是在TestProcess中执行查询,而是传输查询,而应用正在执行它。 此外,您可以使用“ .first”在树中找到第一个元素,然后立即返回。 这使UI测试更快,但是并没有我们希望的那样快。 而不是运行60分钟,他们可能需要52分钟。缓慢测试的另一个原因是动画。 您无法检查它们是否为真,因此可以选择停用它们: UIView.setAnimationsEnabled(_ enabled: Bool) 我不喜欢这种方法,因为您需要在生产代码中实现它,并且可能只有使用动画时才会出现错误。 最后,您将不得不考虑收益并决定是否要冒险。 稳定性 研究了速度问题后,为什么UI测试会出现问题? 由于测试是在自己的流程中运行的,因此我们知道它们必须同步。 但是为此,过程本身需要相互查找。 只要不是这种情况,测试就不会在您的应用程序内无故失败。 这不仅可以在测试的第一次开始时发生,而且可以在中间发生。 每当您的应用重启时,都需要找到该应用进程。 此外,有时由于意外的应用程序行为,导致测试运行不同步。 这可能只是系统对话框弹出而您不处理它,或者网络连接中出现小错误,但最终结果可能是毁灭性的。 知道我们的测试不稳定,就意味着每当运行失败时,就需要进行无休止的调试。 这可能是测试,但通常只是某种时机,(在测试内)意外行为,或者只是Xcode起作用。 但这仍然很耗时。 可维护性 在“屏幕对象”中,我们深入探讨了如何维护测试。 即使我们尝试坚持使用它们,我仍然经常看到与应用程序本身无关的代码。 .tap()之类的函数调用可防止测试松动。 用户界面的微小变化可能会杀死该屏幕上的所有测试。 […]

YNAP上时尚的iOS应用测试的重要技巧

握住移动设备就像将整个词掌握在手中一样,它是使我们能够访问所需所有内容的枢纽。 不再只是发送短信或打电话,如今,即使通过手机购买商品也正迅速成为一种习惯,高价值的奢侈品也不例外。 我在2012年至2017年期间担任移动测试人员。 在那个时候,移动流量和销售额从微不足道变成了大多数零售商最重要的单一渠道。 这完全与以下事实有关:设备大规模发展,变得越来越强大,从而允许开发更复杂的移动体验。 这使我的工作变得更加困难(也更加有趣),因此,这是我多年来作为移动测试人员的重要秘诀,可确保您构建的任何移动应用程序既流畅又可靠。 1.建立强大的测试基础架构 所有最基本的技巧,但可以说是最重要的,是确保您已建立了强大的测试基础结构。 如果您没有完整的移动指标视图,您将永远无法理解事情是否正常运行。 在我的时间测试中,我们部署了一个名为Fabric的工具-模块化移动平台,该平台与Answers(为平台提供动力的分析引擎)和Crashlytics(崩溃报告解决方案)相结合。 Fabric Answers会向我们显示我们的日常活跃用户,实时使用我们的应用程序的人数,正在使用的设备等等。 我们甚至可以看到用户升级到最新版本所需的时间,从而为我们提供了非常有用的浏览行为概述。 结合Flurry和Omniture等其他分析工具,我们可以对用户的旅程和改进之处进行更深入的了解。 2.模拟和监视,监视和模拟,重复 测试就是在尽可能多的场景中运行并解决过程中出现的所有问题。 我可以在办公室重现一些崩溃,向我的团队演示为什么可能会发生此问题,并进行测试以确保不再发生此问题。 但是,每个设备的使用方式都不相同,因此完全不可能模拟会导致崩溃的每个可能情况。 如果尝试这样做,则永远不会发布应用程序,因此它是找到平衡模拟场景并监视会导致崩溃的新场景的平衡。 使用Crashlytics这样的平台将使您能够检查应用程序的实时性能以及这对用户体验的影响。 将其设置为在发生崩溃或问题时可以接收直接通知,使您作为测试人员可以立即进行监视和响应。 设置有关如何确定工作优先级的规则也是关键。 例如,如果是重大崩溃,请修复它并尽快发布该应用程序的新更新。 如果是次要的,请制定计划以在以后修复。 测试崩溃和故障以外的事物也是关键。 分析应用程序会话时长以查看行为是否发生了变化(例如会话时长的增加),使我们能够相应地调查和优化我们的应用程序。 测试可以是主动的! 3.实际测试 在以技术为中心的办公室里工作,很容易忘记您可能拥有绝对一流的互联网连接。 但是在这种环境中测试应用程序很少会显示出用户在通过更不可靠或间歇性的互联网连接使用应用程序时可能会遇到的实际问题。 例如,某些产品图片或视频可能不会显示或下载时间太长,购买路径可能存在问题,即某个页面无法在用户浏览的最后一件商品上显示,或者该应用可能完全崩溃互联网连接不良时。 那么,如何在现实环境中测试应用程序呢? 很简单,退出您的工作场所并进入现实世界。 我参加过火车旅行,在高耸的建筑物中长途跋涉,甚至要求我丈夫开车两次通过隧道来测试应用程序。 需要注意的关键是,当连接在Wi-Fi,3G和4G之间切换时,这通常会使应用程序陷入困境。 但是当然,由于在地上并不总是很方便-尤其是在伦敦下雨天,将真实的测试与模拟的连接设置进行平衡,可以使您进行广泛的测试。 拥有配备设备和模拟器的储备充足的测试实验室是实现此目标的关键。 4.并非所有屏幕都相等 每年发布如此多的不同设备,屏幕发展迅速,分辨率不断提高,分辨率越来越高,令人赞叹的功能(如多点触摸)和有趣的怪癖(如iPhone X的缺口)。 但是,尽管不断发布具有新屏幕和新功能的新设备,但旧设备(尤其是平板电脑设备)的使用时间却越来越长,构建可在所有设备上提供一致,高质量用户体验的应用变得越来越重要,但也至关重要。保持敬业度和忠诚度。 测试时,请确保通过触摸交互正确处理了应用程序中的所有表单字段,选择列表,按钮和链接。 该应用程序还需要一次处理多种交互,例如多点触摸,捏缩放等,并且最重要的是,分辨率需要与所使用的每个设备完美匹配,以向用户提供最佳的视图。 5.善待电池 给手机充电很不方便,因为它将移动设备锁定在一个位置,这完全破坏了设备的作用。 因此,如果您的应用耗尽了用户的所有电池寿命,他们很可能会停止使用它。 在测试时,请注意您的应用在以下情况下的性能: ·设备正在充电吗? ·电池电量低吗? ·启用了低功耗模式,该模式限制了手机的设置,例如Wi-Fi连接,蓝牙或3G / 4G数据 如果您在努力维持电池寿命,最好的方法是检查是否有任何第三方SDK消耗大量电量。 最后,记住为什么要测试您的应用程序 该博客涵盖了测试应用程序时的一些最重要的考虑因素(还有许多这里未提及的因素,例如推送通知,应用程序更新,设备方向,设备设置,位置等等!)。 […]

使您的UI测试再次变为绿色

加入BUX之前,我从未做过任何UI测试。 在我以前的公司中, 拥有事物总是一件好事,而且从来没有发生过当您可以执行非强制性的事情时我们能够达到目标的情况。 基本上,这通常发生在早期初创企业中的大多数工程师身上。 我真的很高兴在我们的BUX代码中看到UI测试,此外,他们设法在基本的Apple工具上构建了一些不错的抽象。 我很高兴接球并积极参与改善我们应用程序质量的过程。 我不会试图说服您编写测试。 您只需每天执行一次。 这是与“我们应该使用版本控制系统吗?”相同的问题。 答案是“是的,我们应该”。 如果您仍然需要一些启发,可以从我的一位同事撰写的文章开始。 除了要点之外,您还会发现一些很棒的历史见解。 UI测试的主要目的是快速运行最重要的方案。 我们应该能够从用户的角度跟踪是否破坏了某些内容。 当然,我们应该不时看到测试失败! 这就是测试如何帮助我们提高软件质量的方式。 但是,在某些情况下,我们可以进行红色测试,而背后的原因对我们而言似乎毫无意义,因为我们无法采取任何措施对其进行修复。 在第二部分中,我想讨论使您的测试变成红色的主要原因:网络。 烦恼网络的原因 想象一下,您刚刚为应用程序流程的新部分编写了全新的UI测试。 您击中Cmd-U时,看到Xcode的“测试成功”并提交时,微微一笑。 您觉得一切都完成了。 但是,当涉及到CI时,情况可能会发生变化。 您一定会看到红色测试的一天。 发生这种情况的原因可能很多: CI环境与开发环境不同步(例如,需要更新Xcode) 证书已过期 网络/后端失败(最常见的情况) 后端通常有多种原因完全不响应或以意外方式响应: 服务器维护 网络可达性问题(如果您使用真实设备进行测试,并且该框中的WiFi信号较弱) 与数据相关的问题。 我们不能总是知道要从后端接收什么数据 如果您的团队中有人要求您使用真实的服务器进行UI测试,请说“ 否” 。 如果他们想在不付出额外努力的情况下测试API,则应该使用一些适当的集成测试,而不是移动应用程序。 使用移动UI测试作为集成测试并不是最好的方法,因为我们引入了多个故障点,这使得测试对于移动端和后端均不稳定且无用。 即使一个应用程序可以一直访问其后端服务器(假设后端始终在运行),它仍然是一个巨大的依赖项,我们对它没有任何影响! 因此,每次在配置项上看到红色测试时,都应确保我们使用新的提交破坏了测试。 我们不会每次都检查后端/网络问题。 归根结底,每个人都可以习惯于“红色”测试,而这并不是我们想要的方式。 解决方法 我们该如何克服呢? 我们应该从不使用真正的UI测试后端开始。 我们决定从OHHTTPStubs开始,因为我们已经使用它进行了一些存根。 这件事太神奇了,它为我们节省了很多时间。 在BUX,我们决定走得更远,并包装此库以使事情更干净和可维护。 我们的目标是在决定“我是否有时间为该功能编写测试或……吗?”的情况下,轻松创建新的UI测试。 要求 我们对存根工具的主要要求是: 存根文件(很多,目前大约有300个)应该易于维护 系统应该有可能为同一端点返回不同的存根 我们应该能够以可预测和干净的方式对其进行修改以满足新的要求 单个测试流程应能够按特定顺序使用不同的存根 […]

构建轻量级功能标记系统

借助基于枚举的功能标记系统,可以放心地将代码交付生产 在构建应用程序时,通常有必要将代码运送到App Store,但是您不希望用户使用它,因为它尚未准备好投入生产或打算在特定日期投入使用。 您问为什么还没有准备好代码时将其运送到App Store? 如果您的团队遵循持续的交付流程,通常就是这种情况。 所有新代码都没有功能分支,而是合并到开发分支中并开始构建。 在团队中有多个成员时,您仅需要在功能完整,经过全面质量检查并准备就绪后才能发布功能🐯 让我们谈谈代码👨🏼‍🚀 枚举FeatureFlag:字符串,CaseIterable { 案例功能1 } 扩展FeatureFlag {var isEnabled:Bool { 切换自我{ case .featureOne: 如果isRunningInAppStore(){ 返回假 } 返回featureFlagValue() } } 私用var键:字串{ 返回“ com.companyname.featureflag”。 + rawValue } 私有功能featureFlagValue()-> Bool { 返回UserDefaults.standard.bool(forKey:key) } func enable(){ UserDefaults.standard.set(true,forKey:键) } func disable(){ UserDefaults.standard.set(false,forKey:key) } } 在 这里 查看完整的要点 : 通过使用快速枚举,我们有了一个非常好的API。 在我们的代码库中的任何地方使用它都很容易。 FeatureFlag. featureOne .isEnabled […]

从头开始创建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 .. 一个更大的例子,还有很多事情要做。 我将设计要点,并讨论一些重要的部分。 […]

测试,测试,1、2、3,测试

我是卫斯理大学(’18)的计算机科学和戏剧双专业,整个暑假都在Flatiron学校(FS)学习。 由于我一生都是学生,所以我习惯于进行测验,学习测验,在测验前拖延,以及受到测验的情绪影响(无论好坏)。 我认为大多数人都可以同意的事实是测试很糟糕。 但是,就编码而言,从长远来看,测试可以节省时间和金钱,并且可以产生更完善,更完美的应用程序。 要进行大量测试,对于一篇博客文章而言,测试太多了,但让我们对其进行分解。 我们都很熟悉XCode向我们提供的红色或绿色小菱形,其中包含支票或’x’。 我们都看着颜色从红色变成绿色,有时又回到红色。 最后,我们全都翻了个白眼,甚至在看到红色的眼睛时甚至撞到了墙上,而在看到绿色的眼睛时就为喜悦而跳了起来。 作为程序员,成功是保持我们编码的动力。 小小的成功是使头脑振奋值得的。 想象一下,如果等到所有编程完成后才知道代码是否按预期进行编译和运行,您会头疼。 这就是为什么测试是一种绝妙的做法。 测试使我们能够构建声音产品并对其功能进行检查。 对于新编码员,养成优雅的习惯很重要。 测试是一种习惯,可能会改变您对编程的看法。 编写测试可能有些繁琐,因此尽早开始很重要。 您越早开始编写和练习进行测试,就会越好。 测试方式 这是几个不同测试选项的简要说明。 Specta和Expecta是不错的选择,因为它们不需要您输入返回类型,并且可读性强。 “总体Specta和Expecta使得语法更加简单,易于编写和阅读。 这直接转化为开发人员的生产力” ( Harry Hornreich )。 XCode提供了一个测试构建框架,使编写测试更加容易。 XCode框架很好,但是IMO最多不过是万不得已,因为它总比没有好。 XCode框架的问题在于,无法知道您正在包括最有意义的测试。 有很多UITesting工具(例如XCode)作为唯一的测试源都不可靠。 有意义的测试 测试有各种形状和大小。 编写测试可能并不像提出测试那样困难。 例如,假设我们在Pig-Latin中编写代码字。 “ in”和“ as”之类的词保持不变。 如果程序员不熟悉该语言,则他们可能会忽略此细节,并让其代码返回“ niay”和“ saay”。 或者,他们可能会记住该规则,却忘记了以元音或以“ sh”或“ ch”开头的单词在其中辅音必须保持在一起的单词的规则。 这种代码中有太多的出错机会,这就是为什么使用测试有益的原因。 如果没有遵循的准则,没有规则,那么如何使程序员避免使程序充满错误? 测试的目的是消除运行时错误(与语法等编译器问题相对)。 测试不是为了弄清楚如何使用内存空间,也不是为了提高速度和效率。 测试以二进制形式进行:您通过或失败,直到通过。 有被迫失败的事情。 强制失败用于指示代码是否朝着不应执行的方向行进。 如果存在某种情况,您担心会发生并且不希望发生,那将是包括强制性失败的充分理由。 右BICEP Right-BICEP是我经过多年编程学习的一种助记符设备。 Right-BICEP是考虑编写代码的绝佳方法。 正确是指检查结果是否正确。 […]

在iOS中测试钥匙串

今天,我将Keychain升级到Swift 4,并借此机会修复了测试。 测试通过了macOS,但在iOS上,我收到-25300错误 var status = SecItemCopyMatching(以CFDictionary形式查询,无) 这是因为没有测试目标的钥匙串权利。 但这是一个框架,我该如何添加权利solution解决方案是使用测试主机托管XCTest测试。 看到我的请求 创建测试主机目标 首先创建一个iOS应用作为测试主机 启用钥匙串功能 然后启用“钥匙串”功能,让Xcode为您自动创建权利文件。 请注意,您只能进入“ Keychain group 。 您无需转到Apple Developer dashboard即可进行任何配置 指定测试主机 然后在测试目标中,使用$(BUILT_PRODUCTS_DIR)/TestHost_iOS.app/TestHost_iOS指定Test Host 现在再次运行测试,它应该通过 原始故事https://github.com/onmyway133/blog/issues/92

在iOS中使用地图视图运行UI测试

您应该模拟一个位置以确保可靠的测试 创建gpx文件 转到Xcode -> File -> New -> GPX File 看起来像 奥斯陆S 2017-05-31T14:55:37Z 奥斯陆S 2017-05-31T14:55:40Z gpx文件非常强大,因为它允许您指定具有不同移动速度的路线。 提供一个或多个包含纬度/经度对的航点。 如果您提供一个 航点,Xcode将模拟该特定位置。 如果您提供多个路标, Xcode将模拟访问每个航点的路线。 (可选)为每个航路点提供时间元素。 Xcode将插补运动 以每个航点之间经过的时间为基础的速度。 如果您不提供 时间元素,则Xcode将使用固定的速度。 航点必须按时间升序排列。 使用gpx文件 在应用程序目标而非UITests目标中声明gpx文件。 转到您的app scheme -> Run -> Options 转到Simulator -> Debug -> Location -> Custom Location然后选择相同的位置,以确保确定。 它不必相同,但是我看到没有Custom Location ,它在UITests中UITests 让地图= app.maps.element(boundBy:0) let谓词= NSPredicate(格式:“ label CONTAINS’City Hall’”) 让cityHall = […]

使用FBSnapshotTestCase测试用户界面

有时,您需要为应用程序的UI添加自动测试。 有几种不同的方法可以实现此目的。 在测试中,您可以获取屏幕的元素并断言所有帧是否都符合您的期望。 根据要测试的UI,这可能需要很多工作。 或者,您可以使用Xcode提供的UI测试。 但是这些操作非常慢,以我的经验,有时它们只是停止工作。 有更好的选择。 Facebook有一个名为FBSnapshotTestCase的开源组件。 此类允许您创建快照测试。 快照测试将视图的UI与快照的外观进行比较。 让我们看看它是如何工作的。 我要测试的UI如下所示: 有两个带有标签,按钮和两个文本字段的堆栈视图。 使用迦太基安装FBSnapshotTestCase 我是迦太基人。 因此,我将向您展示如何使用迦太基在测试目标中安装FBSnapshotTestCase并使用它为简单的登录屏幕添加快照测试。 创建一个如下所示的Cartfile: github“ facebook / ios-snapshot-test-case” 然后要求Carthage使用以下命令创建动态框架 迦太基更新-平台iOS 迦太基将从github上获取源代码并构建框架。 迦太基完成后,将框架从迦太基/ Bild / iOS文件夹中拖动到测试目标的链接二进制文件与库构建阶段: 接下来,向测试目标添加一个新的运行脚本构建阶段。 输入命令 / usr / local / bin / carthage复制框架 并添加输入文件$(SRCROOT)/Carthage/Build/iOS/FBSnapshotTestCase.framework 。 在Xcode中,它应如下所示: 配置FBSnapshotTestCase 接下来,您需要配置放置快照的目录。 每当快照测试失败时,您还可以告诉FBSnapshotTestCase创建差异映像。 这意味着,当测试失败时,将创建一个图像,该图像显示预期的UI和使测试失败的UI之间的差异。 这样,您可以找出UI中发生了什么变化。 打开您使用测试的方案,并添加以下环境变量: FB_REFERENCE_IMAGE_DIR:$(SOURCE_ROOT)/ $(PROJECT_NAME)测试/失败差异 FB_REFERENCE_IMAGE_DIR:$(SOURCE_ROOT)/ $(PROJECT_NAME)测试 在Xcode中,它看起来像这样: 创建快照 要创建快照测试,请将FBSnapshotTestCase的子类添加到测试目标并添加以下导入语句: 导入FBSnapshotTestCase […]

斯图尔特的苹果派食谱

我们如何在Stuart为我们的本机iOS应用程序运行自动化的UI测试。 每个厨师都有自己的食谱。 苹果派可以用多种样式制作,每种都可以用自己的方式美味……但是,有一个我们最喜欢的特殊食谱。 让我向您展示质​​量保证团队为在我们的iOS应用上执行UI测试而构建的Stuart测试框架配方。 我将通过苹果 , 烤锡和我们选择的面粉与您交谈。 苹果 我要谈的第一个要素是测试框架,即我们的“苹果”。 有几个选项,例如Appium,EarlGrey,Calabash,但我们选择了XCTest。 但为什么? 这是苹果公司支持的框架(我们知道他们正在努力使它年复一年地变得更好); 它将完全集成在应用程序代码中。 这为我们的iOS开发人员添加/修复测试打开了一扇门,并且是一种鼓励他们(当然,是质量检查小组!)为同一功能请求中的每个功能或错误修正添加测试的方式。 最后但并非最不重要的一点是,我们可以在UI测试和单元测试之间共享模拟,这使得编写新测试非常顺利。 烤锡 选择合适的苹果后,我们要使馅饼变大。 当我切成薄片时,我个人讨厌它,它会破裂,因此Stuart Apple蛋糕将不得不抵制所做的更改并使外观保持惊人。 在开始做任何事情之前,我们必须先喘口气,然后想想在我们的项目中遵循哪种架构。 我们希望在使代码可重用且易于维护的同时保持简单性。 为了满足这些需求,页面对象模式将用于对应用程序的屏幕进行建模。 我们还将使用机器人模式,以将与应用程序的所有交互封装在一个地方。 测试将使用屏幕与应用程序进行交互,屏幕将使用机器人执行操作(即查找元素,获取文本,点击,滑动…)。 此外,我们创建了一个不同的应用程序目标,以使应用程序与测试脱钩。 这使我们可以在应用程序目标(和其他一些文件)中创建模拟,以定义这些模拟的默认值。 例如,我们有一个模拟客户端(在具有应用程序目标的文件中定义),将具有firstName John和lastName Doe。 这些变量在两个目标都共享的文件中定义,并且仅包含静态数据,因此即使我们要在测试目标中执行断言(甚至使用它构建模拟),我们也可以引用该数据。 面粉 馅饼几乎已经准备好放入烤箱了,但是我们错过了最后一个(也许是最重要的)配料:面粉。 普通面粉可以胜任,但优质面粉可以发挥作用。 我说“面粉”是什么意思? 我们不想通过我们的测试打入网络! 这些测试的目的是检查我们的应用程序的UI在特定的交互后是否以特定的方式运行。 如果由于API返回有效值但我们期望有所不同而导致测试失败,该怎么办? 如果网络请求花费太长时间怎么办? 测试可能会失败。 我们不希望每次由于网络请求而导致测试失败或(或者更糟)习惯于失败的测试时都收到烦人的通知。 我们对可以使我们实现该目标的内容进行了一些研究。 我们发现有趣的选项是OHHTTPStubs,Embassy / Ambassador,MockServer。 每个人都有优点和缺点,但是……我们的最终决定不是所有这些! 主要原因是我们不想在项目中添加外部依赖关系和/或维护大量API响应。 因此,我们使用了不同的方法。 让我们一步一步走。 我们要确保我们的APIClient不会影响网络。 让我们在APIClient中添加几行代码来完成工作并初始化我们的URLSession: 但是……我们如何知道测试是否为UITest以及MockUrlSession是什么 ? 请耐心等待我的朋友,细节来了! 为了让该应用知道我们是否正在运行测试,让我们使用Apple提供给我们的一个很棒的功能:launchArgument和launchEnvironment。 在每次测试执行之前,我们将启动一个参数,指示我们正在运行测试。 […]