Tag: Lydia Gehrlein

单元测试中的存根网络调用

确保您知道您的回应 几年前,我被要求支持公司的其他分支机构。 他们的iOS开发人员很快就离开了,他正在开发的应用程序即将完成。 我去那儿修复了大约10个错误……它以50多个问题结束,但是我们都知道,这在开发过程中很正常。 尤其是当您有一位对利润非常挑剔的出色设计师时。 无论如何..我到了那里,想测试一些网络代码。 我以为我既年轻又年轻(大约一年前才开始使用Kiwi),所以我可以使用这些方法,然后继续前进。 我的一个同事不太喜欢这个主意。 她建议使用当前存在的依赖项,而不要引入新的依赖项(在此期间,我们使用的是XCTest,而不是Kiwi)。 那么她的解决方案是什么? 她已经在使用KIF,并且针对后端运行UI测试并不好玩。 而是使用OHHTTPStubs。 使用此库,您可以拦截网络请求并返回所需的任何内容。 我的猜测是,它在NSURL上使用方法刷新进行拦截,但是如果有库,为什么要自己做。 如何使用 编写拦截器非常容易。 只需指定要拦截的主机和路径并返回响应即可。 我倾向于在包含我的拦截器的OHHTTPStubs上使用类方法创建扩展。 响应是您的JSON对象。 根据要返回的内容,您可以使用库提供的初始化程序。 我还创建了一个匹配器,以便于检查是否调用了正确的网址。 OHHTTPStubs提供了一些,但是有时您必须编写自己的。 这是通过创建OHHTTPStubsTestBlock来完成的。 这是一个闭包,将在其中传递一个RequestObject并返回一个Bool。 与往常一样,要设置我们的套件,我们可以使用beforeEach或beforeSuite。 只是不要忘记事后清理! 所以请不要忘记: OHHTTPStubs.removeAllStubs() 结论 我喜欢这个图书馆。 这是您进行单元测试所需的全部。 几个月前,我向团队介绍了它,从那时起,我们的网络测试就针对OHHTTPStubs进行了。 使用OHHTTPStubs使我们能够测试整个应用程序,而不必在生产系统中引入任何测试代码。 这样,我们可以确定,只要后端api不变,我们的应用程序就会按照我们期望的方式运行。 下一步:TDD向后 上一篇:测试苹果MVC

如何在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()之类的函数调用可防止测试松动。 用户界面的微小变化可能会杀死该屏幕上的所有测试。 […]

如何在iOS测试中使用Chaos

您听说过无穷大的猴子定理吗? 内容如下: “如果您让猴子在打字机上敲击随机键,在无限的时间内,它会扑灭任何预期的书面文字” 还有其他版本使用无限数量的猴子而不是时间。 作为应用程序开发人员,我们有类似的情况。 我们的应用程序被大量以无法想象的方式使用我们的应用程序的用户使用(好吧,他们被编号了,而不是猴子,但是仍然相似。) 结果,他们将发现我们从未预料到的错误。 那么我们该怎么做呢? Netflix创造了一个新名词:混沌工程。 这样做的目的是在生产代码中引入混乱,以发现系统在出现故障时的行为。 他们发表了他们的混乱猴子,杀死了他们生命系统的实例。 我们也许可以在后端系统上使用它,但是总的来说,我们的应用程序有其自身的问题,我们不能仅仅在用户使用它们时就杀死它们;)。 所以,我们能做些什么? 单元测试 在为算法编写单元测试时,通常必须减少输入值,因为它们可能很大。 相反,我们考虑一些极端情况并进行测试。 可悲的是,这可能导致我们遗漏了一些错误。 考虑到上述在测试中添加受控混乱的想法,我们可以开始使用特定范围内的随机值。 这些值需要生成,并且我们的算法必须包含一个条件(意味着条件始终为真)。 幸运的是,我们不必自己写所有这些随机性。 SwiftCheck已创建为我们做到这一点。 让我们开始吧! 阅读以下说明时,请考虑将电子邮件作为我们的域结构: 结构电子邮件{ var local:字串 var host:字符串 var tld:字符串 } 发电机 在SwiftCheck中,您可以使用生成器来创建任意数据。 尝试生成电子邮件地址时,我们必须生成三个部分:本地,主机和TLD。 本地部分可以包括大写和小写字母,数字和某些种类的字符。 完成此操作后,我们可以构建库并以通常的方式包括它们: 迦太基建造 完成所有这些之后,我们可以添加相应的测试: 结论 即使是最优秀的开发人员,也无法预测其应用程序可能具有的所有状态。 这导致没有测试所有内容。 由于没有人是完美的,并且我们无法测试所有内容,因此我们的应用程序容易出现错误。 找到这些错误很困难,但是混沌测试可以提供帮助。 在单元测试中,我们可以在测试算法时测试各种属性。 在UI测试中,我们可以使用猴子来完成应用程序的操作,这是我们从未想到的。 听起来需要做很多工作,但是由于这可以防止生产中的重大错误,因此我认为这是值得的。 如上文所述,它甚至可以用于查找生产中的错误。 如果您感兴趣,它是UIWebView。 从iOS 9开始,似乎每个导航都会创建很多手势识别器。 过渡到其他页面时,这些页面不会被释放,因此会保留下来。 当您触摸屏幕时,所有这些动作都会使主队列超载,从而使您的应用无响应。 最后,看门狗杀死了它。 上一篇:黄金大师测试

适用于iOS开发人员的WWDC 2018:Siri快捷方式

Apple在2016年发布了SiriKit,作为您的应用程序与Siri一起使用的一种方式。 我真的很兴奋,因为它为用户创造了一种与手机互动的全新方式。 他们不再局限于触摸(手势,力度,键盘)了。 相反,他们最终可以在支持它的任何应用程序中使用自己的声音。 那时,当我沉迷于这个想法时,我意识到,事实并非如此。 SiriKit的使用仅限于6类,即: 讯息传递 VoIP通话 付款 乘车预订 图片搜寻 锻炼 这真烂。 我很沮丧,也没有深入研究它,因为我的名单上没有项目可以从中受益。 快进到2018年。周一,苹果公司在其主题演讲中终于宣布了一种与Siri进行交互的新方式。 它称为Siri快捷方式。 让我们深入研究iOS开发人员如何使用它们。 捷径 那么什么是Siri快捷方式? 它们是Siri可以预测并在Spotlight搜索,锁定屏幕等位置提供给用户的操作。您的应用可以在用户与Siri交互时将这些操作提供给Siri。 例如,当用户在您的商店订购咖啡时,您的应用可以向Siri提供带有订购信息的操作。 随着时间的流逝,Siri将了解用户是否多次执行此操作,并将开始建议您的应用提供的操作。 这样,可以从锁定屏幕订购咖啡。 那不是很好吗? 那不是全部! 用户甚至可以使用这些快捷方式添加个性化语音短语。 因此,下次您告诉Siri“胡言乱语”时,Siri将点您的咖啡。 但是我们该怎么做呢? 快速方法 如果您已经在使用NSUserActivity,则可以使用一行代码使它们符合Siri的预测: userActivity.isEligibleForPrediction = true 但是快捷方式可能更强大。 因此,让我们看看自定义快捷方式是如何工作的。 应用程式结构 和以前使用SiriKit一样,我们需要对应用程序进行Intent应用程序扩展。 该扩展将处理将在后台运行的快捷方式。 此外,Apple建议将扩展程序和应用程序之间共享的代码拆分为框架。 该框架应包含所有管理和捐赠快捷方式的代码。 创建快捷方式 查看您的应用并查看最常发生的操作。 让我们看一下可以播放音乐的健身应用程序。 每当您开始锻炼时,您都想听音乐。 因此,该应用可以向Siri捐赠相应的快捷方式。 现在,只要Siri检测到用户开始锻炼程序,它就可以建议通过您的应用播放音乐。 当然,Siri必须先学习它,因此在Siri提出这些建议之前,必须进行一些锻炼。 我做舞厅舞。 由于我总是从开始就开始练习慢速华尔兹15分钟以进行热身,因此我的应用程序可以创建一个快捷方式,建议您精确地进行此操作并将其捐赠。 在研究如何捐赠快捷方式之前,让我们看看如何创建快捷方式。 首先,我们需要一种新型的意图。 意图是用于与Siri通信的对象。 在我们的案例中,系统未提供此类意图,因此应用必须提供自定义意图。 这可以通过将Intent Definition文件添加到项目中来完成。 […]