Tag: 测试

顶级iOS测试框架

您知道吗, 市场是2.5亿+? 发生崩溃后,有11%的iOS用户删除了该应用 发生崩溃后,有45%的iOS用户会删除付费应用 首次崩溃后,有69%的iOS用户将停止玩游戏并删除游戏 每秒售出6–7个iOS设备 随着iOS设备的逐年爆炸,iOS成功的边缘比以往任何时候都高。 越来越多的初创企业和中小型企业发现,购买具有不同操作系统版本和硬件规格的每台iOS设备在财务上都不可持续。 另一方面,由于效率和可伸缩性问题,手动测试应用或游戏不再是质量检查流程的理想选择。 尽管与Android相比,iOS仍然是一个更加封闭的操作系统,但是许多开放源代码测试自动化框架和工具都可以用来创建可靠的自动化测试。 借助基于云的测试解决方案,它使开发人员/测试人员能够以可扩展的方式更有效地验证应用质量,并使iOS测试任务更加轻松。 今天,我们今天将通过5个简单的示例代码来介绍5个广泛使用的iOS测试框架,以使您对开始进行iOS测试具有基本的了解。 如果您还对Android测试自动化框架感兴趣,请不要忘记查看前5个Android测试框架,其中还提供了代码示例。 阿皮 由于其在Android和iOS上的灵活性和可用性而广受欢迎,并且可以在本机,混合和Web应用程序上运行。 对于iOS测试,它使用JSONWireProtocol使用Selenium WebDriver与iOS应用程序进行交互。 为此,Appium确实很好地支持了移动Web测试,并且其用例非常相似,就好像Selenium将用于Web测试一样。 鸦片样本 driver.findElement(By.id(“ com.example.app:id/radio0”))。click(); driver.findElement(By.id(“ com.example.app:id/radio1”))。click(); driver.findElement(By.id(“ com.example.app:id/radio2”))。click(); driver.findElement(By.id(“ com.example.app:id/editText1”))。click(); driver.findElement(By.id(“ com.example.app:id/editText1”))。sendKeys(“简单测试”); driver.findElement(By.name(“ Answer”))。click(); //或使用 driver.findElement(By.id(“ com.example.app:id/button1”))。click(); XCTest与Xcode紧密结合,但仍可用于实际的iOS设备和模拟器。 XCTest允许开发人员为任何级别的组件编写测试,并提供UI测试功能的框架。 XCTest测试被分组为XCTestCase的子类。 使用XCTest编写任何测试对于iOS开发人员来说应该是微不足道的,因为XCTest与Objective-C和Swift完全兼容。 KIF(保持功能)是一个与XCTest测试目标紧密相关并使用XCTest测试目标的iOS集成测试框架。 可以在XCTestCase或任何子类中直接执行KIF测试。 KIF通过利用OS系统为视力障碍者提供的可访问性属性,轻松实现iOS应用程序的自动化。 带有目标C的代码示例 –(void)testClicksOnRadioButtons { [测试人员tapViewWithAccessibilityLabel:@“ Radio1”]]; [测试器tapViewWithAccessibilityLabel:@“ Radio2”]; [测试人员tapViewWithAccessibilityLabel:@“ Radio3”]]; [测试人员enterText:@“简单测试” intoViewWithAccessibilityLabel:@” editText1”]; [测试人员tapViewWithAccessibilityLabel:@“答案”]]; } […]

如何在Swift中编写单元测试而不公开所有内容。

每当我参加讨论单元测试主题的会议演讲时,我都会听到两个问题。 1.我如何说服老板给我时间写这些书? (您没有。您只需编写它们。)和2.单元测试破坏了封装。 你是在告诉我我应该公开一切吗? 我在iOS / Swift的世界中工作,那里有解决特定问题的工具,但总体感觉是,我们必须破解向团队其他成员开放的所有功能,才能进入那里并测试一些变量当他们应该被设置时就被设置。 因此,在进一步详细介绍之前,请先进行警告。 本文的目的是激发话题,而不是倡导任何特定观点。 您采用的任何方法都有其优点和缺点,并且在继续进行计划之前,获取尽可能多的信息总是明智的。 自动化测试虽然不错,但是永远不会修复架构不良的应用程序。 我也不声称他们曾经做到过。 从坚实的基础开始建设总是比将绷带应用于需要推倒的东西总是更好。 ew 感觉很好。 好的,有点自以为是! 这到底是什么问题? 当我们在团队中工作时,每个开发人员都定义了一个API,团队中的其他成员在使用他们的代码时都可以访问。 重要的是,我们要给我们的团队成员一些容易理解的东西,否则他们可能会对我们的代码感到困惑。 如果一个类具有太多面向公众的功能,而另一个开发人员需要相当频繁地使用它,则可能会造成混乱。 与创建具有太多菜单选项的应用程序没什么不同。 用户不容易确定哪个选项是正确的选择。 但是实际上,这比那更糟。 其中一些选项可能会对应用程序致命。 有些变量和函数不应该在类之外使用,因为这样做可能会引入意外的行为。 这就是为什么我们每个人都决定为我们的同伴程序员定义一个api。 我们说“这是公共的,您其他开发人员可以在不破坏应用程序的情况下使用它”,“这是私有的。 没有人可以触摸它。” 这是很长时间以来的样子,并且确实运行良好。 这是传达意图的明确方法。 单元测试与私有方法 不幸的是,这种方法不适用于单元测试。 原因很简单。 在iOS中,您不能针对声明为私有的任何内容编写测试。 等等什么 您应该如何进入那里并测试所有内容? 您应该测试所有内容吗? 您应该只测试几件事吗? 你应该测试什么? 你不应该测试什么? 这变得令人困惑。 似乎没有关于它的手册,而且不同小组之间来回往来很多。 有素食主义者说,单元测试就像在吃蔬菜一样,看着自己变得不健康。 然后是另一个团队放弃了,因为似乎需要考虑太多,而他们的老板也不允许他们编写测试。 我被困在这里问,又是什么问题? 它必须是如此二进制吗? 在这里,我主张“仅仅公开一切”并不是一件坏事。因此,在这里,你也让我死死盯着我的建议的荒谬之处。 好的,那部分结束了。 不管你怎么想,我确实有一个问题。 您是否认为公共/私有的重要性取决于其他外部因素,例如团队规模,项目复杂性,代码可重用性等? 当然,BigCo的一个应用程序项目需要数百名团队成员研究相同的代码,而SmallCo的项目可能只有一两个人正在查看相同的代码。 它必须是。 在较大的公司中,不同人群之间的交流要少得多。 由于无法快速召集您讨论如何与您的班级一起工作,因此定义什么是私有的和什么不是私有的更为重要。 但是,在较小的公司中,只要有一点混乱,您就可以与该人配对。 […]

构建iOS单元测试的四个简单规则

您已经知道什么是单元测试,并且您可能已经在自己的iOS应用中编写了其中的一些测试。 那很棒! 现在,我们将进一步了解单元测试的结构。 当以某种方式编写单元测试时,它们是最有效的。 目标是以一种有组织的方式隔离组件和行为,从而使您深入了解应用程序的哪些部分有效,哪些无效。 只需一点技巧,您就可以编写单元测试来帮助您诊断问题,从而节省了比花费更多的时间。 这是创建测试套件时应遵循的最佳实践的简单列表。 隔离组件 好的单元测试不会尝试一次全部测试。 它一次测试一个组件的一种行为。 这是一个简单的经验法则。 每个要测试的组件都应该有一个XCTestCase文件。 该组件的所有测试都在该文件中。 在我的一个项目中,我有一个类来验证用户在文本字段中键入的薪资。 我将其称为PayrateValidator ,并将其命名为PayrateValidator.swift 。 在相应的测试套件中,测试PayrateValidator的XCTestCase子类称为PayrateValidatorTests ,包含该文件的文件称为PayrateValidatorTests.swift 。 这样一来,您也可以轻松地发现应用程序的哪些部分未被单元测试覆盖。 如果没有相应的测试用例文件,则很有可能没有该组件的单元测试 。 您还可以使用Xcode的测试覆盖率工具,我们将在另一篇文章中进行介绍。 关键是要有某种命名约定,以便您知道哪些文件可以测试什么。 等待。 我没有像这样的小组件。 我该怎么办? 对于初学者的iOS开发人员而言,这可能很难。 如果您没有MVC或MVVM等设计模式的经验,则您的应用程序可能没有任何隔离的组件。 您可能拥有一个巨型视图控制器,其中包含所有应用程序功能。 没办法判断。 我们都必须从某个地方开始。 我自己写了很多庞大的视图控制器。 编写好的单元测试的关键是要理解,您需要将应用程序分解成可以测试的较小部分 。 例如,如果视图控制器进行网络连接,请提取该逻辑并创建一个可以测试的单独的网络服务组件。 如果您不知道从哪里开始,请继续阅读一些常见的iOS应用程序设计模式,例如MVC或MVVM。 只需遵循这些步骤,您就会自动获得一个具有单独组件的应用程序,与庞大的视图控制器相比,这些组件更容易进行单元测试。 隔离行为 假设您已经隔离了一个组件。 您有一个与其关联的XCTestCase文件。 凉! 现在您需要测试。 结构良好的单元测试套件将每个组件分解为行为,每个行为都有其自己的功能来测试它们。 假设您正在编写Rick Astley的人工智能版本。 只是奠定基础,您可以像这样模拟他的一些行为。 这必须是Rick Astley的最笨拙的AI版本,但是也许这是您永远需要的所有编程。 在您的测试用例中, 通用约定是在单独的函数中测试不同的行为 。 它应如下所示。 在这里,我们只是断言,Rick […]

用Charles Proxy骇客

今天,让我们谈谈“中间人”方法, 该方法允许任何人跟踪智能手机或计算机上的浏览器发送和接收的所有流量。 有时,您无法将所需的数据放入应用程序中,但是如果您可以在将浏览器或应用程序接收到的内容发送到智能手机之前对其进行修改,则可以使用一种非常方便的方法来测试点播数据。 这就是我将在本文中通过实际示例进行解释的内容。 我将重点介绍在台式机浏览器中进行测试,以及Android和iOS应用程序中的测试。 为此,我将使用Charles Proxy。 稍后,在另一篇博客文章中,我可能会写关于mitmproxy的信息,它是免费的开放源代码,但使用起来不太方便。 因此,在本文中,我将详细介绍如何在MacBook,台式机浏览器和iPhone上使用Charles Proxy。 中间代理人 什么是Charles Proxy? Charles Proxy是HTTP和HTTPS的交互式中间人代理。 它使任何人都可以查看其一台计算机与Internet之间的所有HTTP和SSL / HTTPS通信。 这包括请求,响应和HTTP标头(其中包含cookie和缓存信息)。 也可以在将请求发送到服务器之前对其进行修改,或者,这就是我将在此处描述的,收到的响应会带来很多机会。 如何安装Charles Charles可用于Windows,MacOS和Linux。 只需在“下载”页面上下载所需的那个,然后按照说明进行即可。 您将获得一个试用版,因为Charles不是免费的(而mitmproxy是免费的),但这是值得的。 我必须承认我首先使用了mitmproxy,但是Charles的使用方式更简单,如果您确实需要代理,则可能不后悔这笔费用。 如何捕捉事物……? …将显示在桌面浏览器中 如果要从浏览器捕获数据包,则必须将其配置为使用Charles。 默认情况下,它配置为使用端口8888,但是您可以通过打开“代理设置”来为所需的端口进行修改。 您可以先打开“帮助”,然后打开“本地IP地址”,以了解访问浏览器需要使用哪些IP,但是大多数时候,您可能会使用localhost(127.0.0.1)在本地进行操作。 让我们配置浏览器。 转到代理设置,然后添加127.0.0.1作为代理地址,并添加8888作为端口。 现在,您将捕获所有请求和响应的数据包,但仅适用于http服务器。 例如,如果Charles捕获了https://www.lyontesting.fr,您将看到此响应,但阅读起来不太舒服。 只需右键单击该请求,然后选择“启用SSL代理”。 然后在浏览器中刷新页面,您会发现结果并不理想。 这是因为www.lyontesting.fr页面被重定向到lyontesting.fr。 转到“代理/ SSL代理设置”,并调整位置主机,以匹配您要捕获的所有情况。 有趣的是,您可以修改将发送到浏览器的响应。 为此,只需添加这样的断点。 在“代理/断点设置…”中,选择“启用断点”,使用host = lyontesting.fr添加一个检测POST请求的断点,然后选择“响应”。 现在再次刷新页面,响应将不会发送到浏览器,正在等待您的批准。 在“编辑回复”标签中,您可以修改html。 在这里,我将“里昂测试”替换为“世界测试”。 结果显示在浏览器中。 现在,您可能认为可以使用浏览器的开发工具非常简单地完成此操作,并且您是对的。 但是这些简单的步骤向您展示了Charles和代理的基础知识。 这些东西也可以用于智能手机应用程序,这就是我们现在所看到的。 …将在智能手机应用中使用 Charles Proxy现在也作为iOS应用程序提供。 使用它,您可以指定要在记录中包括或排除的主机名(例如,仅对应用程序服务器的请求),与SSL代理相同。 […]

在设备上安装iOS测试版本

本简短说明描述了如何在Xcode版本10.1(10B61)中开发的iOS应用程序安装到要用于测试的iOS设备上。 请注意,您可以改为使用Xcode将应用程序安装到目标设备上,但这并不总是一种选择。 例如,如果您想在同事的设备上安装您的应用,而您没有物理访问权限,则将无法执行此操作。 转到Apple Developer网站。 在“设备”部分中添加您iOS设备的UDID。 从几个月前开始,您现在需要使用Apple Configurator 2应用程序来获取设备的UDID。 在Xcode中找到您一直在使用的开发人员证书来对您的应用程序进行签名。 记下其名称-创建配置文件时将需要它的名称。 添加与您的应用程序包标识符匹配的应用程序标识符。 例如,如果您的捆绑包标识符是“ com.mystartup.myapp”,则将其用作应用程序标识符的ID值。 创建一个配置文件。 这会将开发人员证书链接到供应配置文件。 选择“ iOS应用程序开发”类型。 选择您刚刚创建的应用程序标识符。 选择您的开发人员证书。 选择您希望针对应用程序安装的设备UDID。 给配置文件命名。 下载配置文件,然后双击它以使其在Xcode中可用。 在Xcode中,将配置文件与您的应用程序项目相关联。 禁用自动代码签名管理。 为所有签名配置选择已安装的配置文件-关闭自动代码签名后,这些文件就会出现。 生成应用。 选择产品/归档。 创建存档后,选择新的存档,然后单击“分发应用程序”。 选择开发作为开发方法。 如果要定位到特定的iOS设备,请使用App Thinning。 如果选择此选项,将减小输出文件的整体文件大小。 选择用于签署应用程序的开发人员证书(在上面已注明其名称)以及最近安装的配置文件。 创建完成后,选择一个位置来保存您的构建。 在iOS设备上安装应用程序所需的生成文件的扩展名为.ipa。 在目标设备上安装该应用程序。 安装Apple Configurator 2。 将iOS设备连接到计算机。 将.ipa文件拖放到用户界面中的设备上以进行安装。 如果一切都按计划进行,则应在轻按时启动该应用。 否则,您将遇到问题。

XCUITest的一些好的做法

//在您的ViewController上 btnSend.accessibilityIdentifier =“ btn_send” //测试查询元素: app.buttons [“ btn_send”]。tap() 查看过渡 在实际显示视图之前,可能需要一些时间。 过渡动画,加载视图从Web或其他任何过程获取信息所消耗的时间。 因此,请确保在声明任何内容之前始终等待视图的存在。 让resultView = app.otherElements [“ view_result”] 让viewExists = resultView.waitForExistence(超时:10) XCTAssert(viewExists) XCTAssert(app.staticTexts [“ Xcode字词的结果”] .exists) 一个好的做法是识别每个UIViewController的视图 ,以便断言该视图是否存在,您不依赖于可以很容易更改的标签文本,而是依赖于可访问性标识符。 页面对象模式+方法链接 将有关每个ViewController的信息包装在不同的对象( Page )中。 这样,测试可以使用该对象而不是查询元素本身。 类SearchPage { 函数类型(查询:字符串) func tapSend() } //使用Pages进行测试: searchPage.type(查询:“ Xcode”) searchPage.tapSend() 为了使测试更具可读性,您可以使用方法链接,如下所示: 类SearchPage { 函数类型(查询:字符串)->自我 func tapSend()-> ResultPage } //使用Pages +方法链接进行测试 searchPage .type(查询:“ Xcode”) […]

Xcode快速提示–测试布局以进行本地化

Zendesk支持应用程序支持多种语言,这意味着我们在应用程序中显示的字符串会根据设备语言集而改变。 最近,当设备语言从默认语言(英语)更改时,我们遇到了UI组件定位错误的问题。 这在荷兰文中显示如下。 由于一些不确定的自动布局约束,包含字符串的UILabel随着字符串长度的增加而增大,从而导致下一个UI元素UISwitch被推到包含视图的边界之外。 在调查并解决此错误时,我们需要重复再现该问题。 我们没有改变繁琐的设备语言,而是偶然发现了一种称为伪本地化的测试方法。 伪本地化是一种用于测试国际化的测试方法,其中涉及用更改后的版本替换默认语言字符串。 例如,我们可以将“登录”替换为“登录登录,登录登录”。 然后,我们在Xcode方案编辑器中发现了一个非常有用的选项,该选项使我们能够使用伪本地化来测试布局,如下所示。 使用此设置,应用中的所有字符串都将被伪翻译所取代,该伪翻译由重复两次的原始字符串组成。 下面显示的是在启用此设置的情况下运行的应用程序,这导致默认字符串被伪翻译替换。 使用伪本地化Xcode方案设置,我们能够快速重现报告的问题并实施修复! 🎉我们的更新后的用户界面如下所示。 综上所述 伪本地化是一种用于测试国际化的测试方法,其中涉及用更改后的版本替换默认语言字符串。 Xcode包含一个方案设置,该设置使我们可以使用伪本地化来测试UI布局。 伪本地化应该是正常功能开发的一部分。 而已! 📱🚀👍🏽 也可以在petethedeveloper.com上获得

自2017年以来有关使用Swift进行单元测试的文章的完整列表

您是否为应用编写单元测试? 无论您在Swift中编写测试有什么答案,它都会成为开发社区中的热门话题。 许多开发人员发表了出色的文章,就用Swift编写测试进行了出色的演讲和播客。 通过这些材料,学习变得比以往更加容易。 在2017年底,我决定分享我最喜欢的材料,这对您将单元测试技能从零提高到一非常有用。 快乐学习🙂 在弄脏手之前 可测性工程 可测试性工程– WWDC 2017 –视频– Apple Developer 单元测试是必不可少的工具,可以一致地验证您的代码是否正常工作。 探索设计技术…… developer.apple.com 如果您是编写单元测试的新手,我强烈建议您从WWDC 2017的视频开始。在此视频中,Brain Croom和Greg Tracy声明了编写可测试代码的动机以及可测试性的重要性。 然后,他们展示了如何逐步分离模块。 他们还介绍了在建模应用程序和编写单元测试中应了解的许多技术和技巧。 这绝对是开始您的旅程的好地方。 iOS单元测试和UI测试教程 iOS单元测试和UI测试教程 编写测试并不是魅力十足,但是由于测试可以使您闪亮的应用程序避免变成臭虫缠身的垃圾…… www.raywenderlich.com 我仍然记得,当我第一次选中“包括单元测试”复选框时,我并不知道该项目有任何更改,也不知道如何进行。 这是由Audrey Tam提出的有关在Swift中编写测试的完整指南。 她介绍了一些基本主题,例如如何在Xcode中设置单元测试以及如何创建模拟对象或存根对象。 她还介绍了更高级的主题,例如性能测试和测试范围。 在此过程中,您将掌握测试忍者所使用的一些词汇,并且到本教程结束时,您将非常有信心地将依赖项注入待测系统 (SUT)中! Swift开发人员时尚的单元测试指南 Swift开发人员时尚的单元测试指南 Jaim Zuber介绍了成熟的技术来测试您的应用程序,包括使测试变得困难的模式以及… academy.realm.io 我应该在当前阶段对代码编写测试吗? Jaim Zuber展示了为什么需要测试以及将测试引入项目的好处。 他还提供了详细的分步教程,以在实践中编写测试: 我们将回答以下问题:如何测试ViewController? 如何测试故事板代码? 在没有模拟库或部分模拟的情况下如何生存? 如果您仍然不确定编写测试有什么好处,请观看此视频讲座! Xcode Playgrounds中的TDD Xcode Playgrounds中的TDD 技能专区| 2017年3月30日 iOSCon […]

Swift中Xcode UI测试入门

UI测试是确保您最关键的UI交互在添加新功能或重构应用程序的代码库时仍能正常工作的好方法。 这也是一种在处理UI代码时自动执行重复任务的好方法(例如,当您必须深入浏览应用程序以测试正在处理的内容时)。 编写和运行UI测试与进行单元测试有所不同,因为您实际上是在与应用进行交互 ,而不是针对某个API执行编程测试。 两者都有很大的价值,最好的方法是将两者都用于不同的任务。 Xcode附带了XCTest框架中内置的UI测试,您可能已经将其用于单元测试。 这些UI测试功能已经存在了好几年,但是由于不稳定,易碎且难以使用而被许多开发人员所摒弃。 过去是这样 ,在Xcode UI测试的前几次迭代中,确实确实非常不稳定-但现在情况有所好转-如果您还没有这样做的话,我真的值得给它第二次机会🙂 设置东西 如果您的应用程序还没有UI测试目标,则只需添加Xcode中的File > New > Target..并选择一个“ UI测试包”即可。 然后在Xcode中转到Product > Scheme > Edit Scheme.. ,然后在“测试”下添加UI测试包,以编辑应用的方案以在测试时运行UI测试。 让我们写一个测试 UI测试是一个很好的解决方案的例子是,当您想测试用户流程时,例如,在应用程序的入门流程中进行测试。 假设您的入职流程由4个屏幕组成,用户必须先滑动才能完成此过程。 最后,右上角出现一个“完成”按钮,需要关闭该按钮才能关闭入职流程,如下所示: 因此,让我们编写一个精确地执行此操作的测试: class OnboardingUITests: XCTestCase { var app: XCUIApplication! // MARK: – XCTestCase override func setUp() { super.setUp() // Since UI tests are more expensive to run, it’s […]

宝石-测试用例iOS

编写测试用例的步骤? 1.失败-> 2.通过-> 3.重构 这些步骤是什么意思🤔 失败:首先编写测试用例以进行失败。 通过:然后仅通过测试用例。 REFACTOR:最后但最不重要的一点是,尝试重构意味着重组测试用例。 1.给定-> 2.当-> 3.然后 给予:您已经拥有的内容,例如API网址。 时间:您将如何处理此问题,例如获得成功/失败的响应 然后:在获得预期的输出之后,例如响应成功/失败,该怎么办 查看以下代码段以进行API调用: 导入 XCTest class UnitTestingTests:XCTestCase { var sessionUnderTest:URLSession! 覆盖 func setUp(){ 超级 .setUp() sessionUnderTest = URLSession(配置:URLSessionConfiguration.default) } func test_APIComplition(){ //给定 让 url = URL(字符串:“ https://itunes.apple.com/search?media=music&entity=song&term=abba”) 让 promise =期望(描述:“已调用复合处理程序”) var statusCode:整数? var responseError:错误? //什么时候 让 dataTask = sessionUnderTest.dataTask(with:url!){(data,response,error) in statusCode =(响应为 ?HTTPURLResponse)?. […]