Devากที่ได้รับหน้าที่เป็นMobile Dev.。 ฝั่งiOSก็ได้ทำCIบนJenkinsทั้ง单元测试และUi Testingผ่านFastlane…。 ก็สะดวกดี runาคือหลายครั้งที่เมื่อrun ui testบนเครื่องjenkinsมันไม่เสถียร iา ที่มั ผ่านบ้างแล้วแต่ดวง(พูดเล่นนะ) UiTestที่มันมากับ fastlane ui-testingเนี่ยโดย默认默认รันบน模拟器ที่ใช้ทรัพยากรของเครื่อื่ มีอมี工作ื่รๆนพร้อมกันก็ทำให้เครื่องช้า(Mac miniรันUi,单元测试ของทั้งAndroidและiOS) iางทีมก็เริ่มอยากรันUi TestingบนDeviceเพราะเชื่อว่ามันจะดีกว่าที่รันผ่าน仿真器 และมันก็เป็นอย่างนั้นจริงๆราะโดยปกติ UIา ที่รัน UI TestจะบนJenkinsด้วfastlane(simulator)ใช้เวลา〜20分钟 ีกอาจจะพังใช้เวลาหาสาเหตุอีก〜10分钟ลองรันบนเครื่องตัวเองอีก〜7分钟โถ่ววชีวิต Device ล อลองรันบนDeviceกลับใช้เวลา〜8分钟แล้วTesterก็เห็นscreenของdeviceตอนrunด้วยดี้ดีย์ ขี้เกียจเล่าแล้วมาลองกันเถอะ… สร้าง项目ง่ายๆเพื่อลอง เหมือนทำแอพเปิดปิดอะไรสักอย่าง… เมื่อเริ่มต้น应用 ให้状态เป็น关闭 วนไป上的และเมื่อกดปุ่มON / OFFให้状态เปลี่ยนไปเป็น…。 codeนcodeนั้นอยู่ด้านล่างจย้า 设置方案Ui测试设置项目ให้รันได้นDeviceได้นะครับ provisionานการเพิ่มเครื่องเข้าไปใน供应配置文件เซ็ทApps IDให้โปรเจค ส่วนนี้ค่อนข้างยาว ViewController.swift 导入UIKit 类ViewController:UIViewController { @IBOutlet弱var lightStatusLabel:UILabel! @IBOutlet弱var lightSwitcherButton:UIButton! var isLightOn = false 覆盖func viewDidLoad(){ super.viewDidLoad() […]
概括地说,我们编写的测试分为3个不同的类别: 单元测试是人们可以编写的最简单的测试,并且顾名思义,它可以独立测试单个代码单元。 它们既快速又稳定,我们可以编写很多它们,它们是其他测试的基础。 一个普遍的误解是,单元测试仅针对模型(即处理数据的实体)编写。 另一方面, UI测试是对整个事物进行整体测试的工具-它们从用户角度检查系统,并且极易损坏。 UI测试既昂贵又缓慢,并且是需要不断进行维护以跟上不断发展的系统的测试。 我们应该始终努力减少运行测试所需的时间-通过将大量的UI测试转移到单元测试,我们可以获得绝缘和速度方面的好处。 这是一个例子…… 假设我们在UIViewController中有一个UITableView,它应该覆盖整个视图。 我们的测试不应检查tableView是否正确“拉伸”(最终结果),而应检查视图是否具有上述约束(并相信系统在内部做正确的事情): 这个简单的测试比任何UI测试都快得多,并且不依赖于应用程序的其他部分来加载和显示View Controller(根据UI测试的要求)。 希望这可以帮助。 测试愉快! 为了完整起见,这是整个TasksViewControllerTests类:
为什么还要编写测试呢? 让我们从基础开始,为什么我们甚至需要编写测试? 即使我是编写测试的坚定支持者,但我确实理解有时候由于各种原因,没有足够的时间或资源可以专门用于测试,最常见的情况是缺乏对重要功能的理解,或者换句话说,缺乏公司文化。 通常是我们开发人员必须说服我们的经理我们需要编写测试。 另一方面,有很多开发人员根本不相信编写测试,或者只是出于某种原因不喜欢编写测试。 如果您是这些开发人员或管理人员之一,我将请您仔细考虑以下事实。 在医院洗手是相当近期的做法。 直到1847年,匈牙利医生Ignaz Semmelweis才提出医护人员洗手以降低医院死亡率的想法。 他的想法与当时的科学观点和医学观点相矛盾,并被当时的医学界完全拒绝。 由于遭到拒绝和嘲笑,他感到神经衰弱,并在庇护中死亡。 医学界花了很长时间才开始将洗手作为强制性做法。 毋庸置疑,从那时起,洗手挽救了无数生命,而提到的医生是现代英雄。 杀手bug 我希望我能说,没有人为了让我们(软件开发人员)能够学习到有关编写测试的重要性的类似课程而死,但这已经与臭名昭著的计算机控制放射治疗机Therac的 “杀手臭虫”发生了-25 ,这会导致它发生故障,并给至少6名患者带来大量(有时甚至是致命的)辐射剂量。 如果以适当的方式对Therac-25的软件进行了测试,也许可以避免发生这一系列可怕的悲剧。 测试iOS应用 软件开发社区中有关自动测试的情况看起来像19世纪后期的医学界,在iOS应用程序开发社区中尤其如此。 编写任何类型的测试通常都是iOS应用开发的事后思考,特别是在较小的团队中。 实际上具有大量单元测试的某些项目通常会完全省略UI测试。 作为iOS开发人员,我们的工作与其他软件开发人员没有任何不同,我们应该像其他开发人员一样坚持经过时间验证的做法,并通过测试彻底覆盖我们的代码。 我们可以使用的某些工具可能还不如XCUITest (我在看着你! ),但这并不意味着我们不能在它们之上构建并解决眼前的问题,毕竟,这就是我们要做的正在付款。 在BUX上进行测试 当我开始在BUX工作时,我被分配给一个经验丰富的iOS开发人员团队,他们准备开始构建具有挑战性的新iOS应用程序。 团队已经使用当前的BUX应用程序设置了很高的质量标准,该应用程序已经在App Store上运行了几年,并且非常稳定,有成千上万的用户,几乎没有崩溃。 毋庸置疑,这种稳定性是严格的测试程序的产物,我们也在新应用程序的开发过程中加以应用和改进。 新应用,新挑战 我们正在构建的新应用是下一代股票交易应用。 它是从头开始设计的,其任务是抽象出股票交易的复杂性,将其带给以前从未交易过的人们,同时使用户界面尽可能直观,并为其添加独特的社交组件。 有很多重叠的实时事件,例如股票报价更新,账户余额更新,交易执行,社交事件等,它们可以在一瞬间发生并动态影响用户界面,有时一次会发生多个事件。 另外,可以从应用程序中的多个点触发很多自定义流。 我们的解决方案 为了降低复杂性,我们将应用程序分为几个模块/框架,一个包含核心业务逻辑,一个用于发出和发送http请求,另一个用于Web套接字事件观察,等等。 通过使用单元测试,测试这些框架非常简单,单元测试覆盖了它们的100%。 当要测试应用程序本身时,出现了一个大问题。 测试应用程序的某些部分非常简单,我们的逻辑控件已从其支持的视图中分离出来,因此我们能够通过使用单元测试轻松地涵盖其中的大部分内容。 另一方面,端到端测试所有UI流程并不是那么简单。 手动测试它们会花费时间,消耗人力并且容易出错。 另一方面,使用XCUITest进行自动UI测试并不是有史以来最好的开发人员体验。 有一些出色的iOS UI测试框架可用,但是我们觉得其中大多数都不适合我们,或者仅仅是一个过大的选择,因此我们决定构建自己的简单且最小的iOS UI测试框架。 我们正在尝试做的是通过控制应用程序接收的所有数据,以一种用户使用应用程序的方式来模拟应用程序的使用,但是在受控环境中。 在单元测试的情况下,通过模拟和存根实现非常简单,但是在UI测试的情况下,则变得更加复杂,因为您没有相同级别的访问应用程序代码的权限。 iOS App及其UI测试本质上是两个独立的过程,它们进行通信的唯一方法是在测试开始时通过XCUIApplication变量传递一些参数。 有一些第三方解决方案即使在应用程序和UI测试目标已经运行后也能在它们之间传递数据,但是我们认为这太过hacky和容易出错,因此我们围绕此约束构建了框架。 页面对象模型 我们的解决方案基于Page Object […]
移动应用程序的UI测试至关重要,以便在最终用户手中准确测量给定应用程序的可用性。 当应用程序的功能集增长时,手动测试应用程序的UI可能会效率低下,如果需要测试多个设备配置,则几乎不可能。 因此,自动化的UI测试已成为开发人员监视其移动应用程序行为的宝贵工具。 使用Xamarin.UITest框架,我们能够快速而轻松地完成此任务。 Xamarin.UITest,Calabash和NUnit概述 Xamarin.UITest是基于Calabash的自动化测试框架,允许开发人员编写以NUnit编写的验收测试。 Calabash是用Ruby编写的核心框架,它使开发人员能够编写自动UI接受测试。 最后,NUnit是用于基于.NET的语言的单元测试框架。 开发人员可以使用NUnit和Xamarin.UITests对iOS和Android应用程序运行测试。 从那里,开发人员还可以通过Visual Studio App Center(以前称为Xamarin测试云)提交这些测试,以使其在数百个物理设备上运行。 为什么要编写自动化的UI测试? 自动化的UI测试允许快速开发健壮的代码库,同时能够系统地测试多个设备目标上的常见用户方案。 如果团队决定重构其核心体系结构,它还允许用户快速测试应用程序。 这使团队可以清晰地了解可能需要检修的工作项目以及按预期工作的项目。 通常,行为驱动开发还具有隐藏的好处,例如难以发现代码库中的错误以及允许专家和开发人员更好地协作来构建用户故事。 使用Xamarin.UITest Xamarin.UITest框架需要依靠一些概念才能正常工作。 框架中的每个自动UI测试都以[Test]属性进行修饰。 在每个测试中,存在测试逻辑的类称为测试夹具 。 给定的测试套件中可以有一个或多个测试夹具。 这些测试应该按照最终用户根据Xamarin自己的“安排-行为-声明”模式与应用程序进行交互的方式进行逻辑安排。 此模式要求设置和初始化测试条件(安排),测试将像用户一样操作并与应用程序交互(执行),最后,测试将检查这些交互的结果(声明)。 下面是一个示例。 我们将对包括本文在内的所有示例使用Xamarin.iOS。 初始化 要在iOS上初始化Xamarin.UITest,请使用静态ConfigureApp类: var config = ConfigureApp .iOS .InstalledApp(“package.identifier”) .EnableLocalScreenshots(); 这允许UITest库将应用程序部署到物理设备上以运行测试。 使用InstalledApp允许在物理设备上以编程方式启动,而调用AppBundle将强制在模拟器上运行。 在物理设备上进行测试时,务必将应用程序的捆绑软件ID放置在package.identifier参数的位置。 您可以使用应用程序的相对或绝对路径在模拟器上进行测试。 在我们的情况下,如果没有用户首先通过身份验证应用程序登录,该应用程序将无法成功运行。 登录后,用户将被重定向到原始应用程序。 这可以通过框架以与上述相同的方式实例化应用程序来完成。 重要的是要注意,为了使它在iOS上成功运行,还必须已经构建了该应用程序。 调试测试 在编写UI测试时,可能有时需要手动浏览UI或快速测试一些应用程序命令。 幸运的是,Xamarin.UI测试框架配备了repl(read-eval-print-loop)来处理此问题。 该工具使开发人员可以与应用程序的UI进行交互,从而使他们可以测试单个命令,遍历界面,并清晰地了解哪些视图处于活动状态以及与每个元素相关联的元数据标签。 为了使用repl,我们只需要从测试内部调用IApp.repl()方法。 当执行repl()方法时,它将暂停当前测试,并在新的终端窗口中打开repl。 在这里,我们可以直接与该应用进行交互,测试命令和查询,并进一步了解我们的UI。 在编写测试时,我们经常需要检查屏幕上实际存在的视图。 为此,repl有一个名为tree的漂亮命令,该命令提供了屏幕上当前可见的所有视图的层次结构列表。 由于Xamarin.UI测试框架的许多方法都依赖AppQuery对象在屏幕上找到正确的视图,因此我们需要知道实际上是在获取正确的元素。 […]
免责声明:阅读前请检查对本文的评论。 Ilya Puchka 找到了更好的解决方案作为解决方法。 您可以注意到,当您使用其录制工具录制UI Test并点击SFSafariViewController内容时,Xcode 9.3崩溃。 捕获到“ NSInternalInconsistencyException”,“无效的参数不令人满意:[后裔_isDescendantOfElement:self]” 发生这种情况是由于Xcode中的错误,非常令人讨厌。 例如,如果我们要测试Facebook或其他社交登录信息,则需要与Web视图进行交互。 有趣的是,在调试期间,您可以进行debugPrint Web视图的所有按钮和字段,而不会出现任何问题。 但是由于NSInternalInconsistencyException的原因,您无法在文本字段中tap按钮或typeText。 为了成功进行测试,我需要Web视图元素中的一些内容: 检查元素是否存在 等待元素出现 点击按钮 清除文本字段中的文本 在文字栏位中输入文字 请记住,我们可以debugPrint元素,我们可以尝试这个疯狂的解决方案:解析元素的debugDescription ,从中获取其框架,然后按坐标点击XCUIApplication 。 让我们编码为: 等待元素出现 点击元素并检查元素是否存在 下一个问题是我们不能在文本字段中typeText Text。 但这不能阻止我们,对不对? 我们可以点击位置,因此可以通过复制/粘贴菜单粘贴文本。 同样,我们可以使用“全选”和“剪切”清除文本字段中的当前文本。 咱们试试吧。 在文字栏位中输入文字 就这样。 现在,我们可以测试Web视图中的许多内容。 这应该适用于SFSafariViewController并且希望与WKWebView或UIWebView (我没有对此进行测试)。 所有代码都在一个文件中:https://gist.github.com/pilot34/09d692f74d4052670f3bae77dd745889
为了对应用程序进行UI测试,我正在研究在测试执行期间模拟所有网络调用的最佳方法。 模拟网络调用的动机是消除执行测试时的不确定性。 我们不能依靠服务器来运行,我们的测试用例所基于的数据总是一样,等等。此外,模拟所有调用将使测试运行更快。 UI测试的问题是Apple对其进行设置的方式,使您的应用在一个过程中运行,而在另一个过程中进行测试。 UI测试使用UIKit内置的可访问性功能与在单独进程中运行的应用程序进行交互。 随之而来的问题是,我们不能像通常在单元测试中那样注入模拟或存根网络调用。 根据我的阅读,有两种方法可以解决此限制。 一方面,我们可以将我们需要的所有固定装置(我们将用作响应模拟调用的文件,它们可以是json,xml等)放置在应用程序的主要目标中,并提供模拟框架以及在运行UI测试时通过环境变量,以告知我们的应用设置模拟程序。 这种方法让我有些困扰。 首先,我们仅将特殊代码用于运行测试,应尽可能避免这种做法。 这看起来从不漂亮,可能导致错误,使代码的可读性和可维护性降低。 另一个选择是在本地运行服务器,该服务器嵌入执行测试的过程中,在该过程中,我们对网络调用进行存根(stub),测试正在命中并返回固定装置。 Michal Ciurus的一则帖子详细介绍了他的操作方式。 在他的情况下,在应用程序进程中进行存根对他来说不是一个选择,因为他需要动态更改服务器的响应。 他使用swifter作为服务器,这是用Swift written编写的简约HTTP服务器。 还有其他使用其他服务器的帖子,例如Fang-Pen Lin的帖子。 Michal分享了我们需要设置服务器和对电话进行存根的类: 帮助程序类,以建立快速和存根我们的电话 然后我们简单地像这样使用它: 我们可以在helper类中设置常量存根,或者根据需要在测试中动态设置新的存根,如上面所示。 现在唯一需要做的就是告诉我们的应用使用http://localhost:8080作为调用的端点。 我有两个xconfig文件,即Debug和Release,用于设置测试和生产端点。 我使用http://localhost:8080作为端点创建了另一个UITesting。 将UITesting的特定xconfig 设置为UI Testing方案的Test Action的Build Configuration 。 现在,我们的道路上仅有一个最后的障碍,即应用程序传输安全性(ATS)。 在iOS 9中引入了Apple激励开发人员使用基于HTTPS的安全网络连接来提高用户安全性和隐私性。 但是swifter仅通过HTTP起作用。 有一种方法可以在我们的Info.plist添加异常,但是Apple建议它是临时的,从而提示开发人员确保他们在其应用程序中使用的资源的安全。 自2017年以来,除了开发人员可以证明其合理性的情况之外,Apple拒绝使用此异常的应用程序。 有一种方法可以使用密钥NSAllowsLocalNetworking为localhost添加一个不需要理由的异常,但只能在iOS 10上使用NSAllowsArbitraryLoads可以在iOS 9中使用 NSAllowsLocalNetworking should be added to the plist with iOS 10. Source. 就我而言,因为我使用iOS 10运行测试,所以只需要NSAllowsLocalNetworking 。 […]
在视图控制器中更改某些代码已经发生了多少次,并且在生产环境中测试应用程序时,视图已经发生了神奇的变化? 如果我们不想,我们是否应该有某种方法来确保视图不变? 因此,进行UI测试很重要。 通过添加UI测试,我们可以确保不会对UI进行意外更改。 在本文中,我们将在一个简单的示例项目中专注于FBSnapshotTestCase的用法。 FBSnapshotTestCase的历史 最初,FBSnapshotTestCase由Facebook创建和维护。 这是一个非常有用的工具,具有非常简单的实现。 所需要做的就是将库集成到项目中,并实例化我们要测试的UIView或UIViewController子类。 不幸的是,自去年以来,Facebook已停止维护该工具。 Facebook已经创建了另一个与其内部基础设施紧密相关的工具,因此他们不赞成该工具。 对我们来说幸运的是, Uber决定为他们当前维护的项目创建一个分支。 FBSnapshotTestCase测试实际上是单元测试,它使我们能够将UIViewController的参考图像(也可以是UIView,但通常是在全屏模式下)与视图的当前呈现进行比较。 如果存在任何不一致(第一张图像与第二张图像之间存在差异),FBSnapshotTestCase将生成第三张图像,并以灰度标出差异。 如果参考图像和项目中的电流之间存在差异,则该工具将生成此第三张图像,并且在该单元测试中会生成错误,从而导致测试套件产生故障。 Fastlane为我们提供了类似的工具Fastlane Snapshot(存储库),它使我们能够在Xcode UI测试中截取屏幕截图。 所有UI测试完成后,如果它们都获得批准,它将生成带有所有屏幕截图的HTML文件。 Fastlane Snapshot默认情况下还允许我们设置我们要查看的所有设备和语言。 这对于测试所有可能的组合非常有用(如果您有3种语言,应用程序中有10个屏幕,并且支持5种设备,则它会生成3 x 10 x 5 = 150个屏幕截图!)。 问题在于,这只是一个屏幕截图,它没有为我们带来有关图像是否具有正确UI的信息。 总而言之,FBSnapshotTestCase允许我们比较并告诉我们是否有任何错误,Fastlane Snapshot只是为我们带来了Xcode UI测试的屏幕截图。 我们将讨论以下主题,力图充分利用该工具的潜力: 如何集成FBSnapshotTestCase 使用SnapKit重构代码并使用FBSnapshotTestCase 编写脚本以生成具有不同分辨率的屏幕 要开始本教程,请下载以下示例项目https://github.com/fedejordan/FBSnapshotTestCaseExample 在模拟器中编译项目(我使用过iPhone 8),您将看到以下屏幕: 一个简单的View Controller,可以是任何应用程序的第一个屏幕,带有登录和注册按钮。 我已经使用CocoaPods集成了SDK。 您可以使用Carthage或您选择的包裹管理员。 集成该工具的步骤在存储库指南中。 为了方便起见,以下是使用CocoaPods的安装说明: 在终端应用程序中,我们输入pod init以创建podfile 在podfile中,我们添加pod ‘FBSnapshotTestCase’ 我们在终端中进行pod install以下载SDK 我在这里使用的版本是2.1.6 将SDK集成到项目中后,我们将打开CocoaPods生成的工作区并编译项目,以确保一切正常。 就像它在FBSnapshotTestCase官方指南中所说的那样,我们转到Edit […]
一,为什么要使用UI测试? 1.自动化手动测试🤖 测试应用程序时,我们总是重复相同的过程以测试我们没有破坏任何东西。 我们可以通过一系列与手动测试相同的测试来实现这一目标。 2.表示层中的逻辑丰富🌅 我们拥有的UI逻辑越多,我们测试的内容就越多 3.节省时间⌚️ 有了一系列的ui测试,我们可以在更少的时间内每次都重复相同的手动测试。 二。 我们可以测试什么? 纽扣 刷新表格 输入文字 滑杆 检查导航栏标题 推拉视图控制器 重新排列细胞 等等.. 您可以查看此UI测试备忘单以获取更多信息。 三, 我们如何正确测试? 1.有助于将逻辑与表示法separate分开的架构。 当我们谈论MVC时,我们都知道它不是非常可测试的,因为视图和控制器之间的交互非常紧密。 我们可以使用MVVM或VIPER架构,通过更好的分布来实现更好的可测试性。 您可以查看这篇很棒的文章,以获得更多信息iOS体系结构模式。 2.依赖注入💉 这种软件设计模式允许在运行时而不是在编译时选择组件,目的是用Test Doubles代替生产代码。 依赖注入的示例将类似于以下ServiceLocator: CharactersViewController :是主视图控制器,并显示GOT字符列表。 CharacterDetailVC :显示CharacterDetailVC的详细信息。 字符VC测试 辅助方法 我们将在测试中使用一些辅助方法。 我们将不再需要手动重复此过程this。 五,从这里去哪里 在github上检查整个项目,查看所有使用的配置和框架。 尝试自己编写一些UI测试。 创建您自己的项目,并按照此结构做一些事情! VI。 归因 GOT Challenge Swift应用程序基于Idealista GOT Challenge Android。
简介✍️ 在本文中,我们将首先解释如何使用Xcode编写UI测试,然后如何添加可视化差异,最后解释如何在Bitrise中进行配置。 为什么要测试用户界面(UI)? 对于产品发布,要测试每个用例并确保没有回归是很痛苦的。 您可能忘记测试一个流程,或者认为您的更改不会影响代码的其他部分……但是有时会这样做。 这是在Appaloosa上为我们的iOS应用程序所发生的情况,其中一些错误逐渐消失。 例如,当发布iOS 11时,我们在导航栏中添加了约束,但是此功能在以前的版本中不可用,并且该应用在iOS 10中崩溃。 它很快被发现并修复,但是警报提醒我们采取更强有力的措施来防止此类问题。 UI测试和单元测试 使用单元测试,您可以独立测试每个小代码,并专注于代码的逻辑方面。 使用UI测试,您可以模拟用户交互和用户流。 让我们以用户尝试登录您的应用程序为例。 它将在整个过程中测试用户与我们的应用程序的不同交互。 设置📚 在Xcode上转到您的项目,单击“ +”按钮(请参见下图)并添加iOS UI测试包。 还将创建一个新目标。 您还可以在Xcode上创建项目时添加它。 样例项目 这是一个示例项目。 我们要测试多个用户流,并确保它们都能按预期工作。 您可以在github上找到完整的代码。 目的是确保我们的登录页面在不同步骤中显示正确的视图。 因此,我们将需要访问页面的不同视图以评估其在测试期间的行为。 您可以通过多种方式检索应用程序的元素: 您可以使用Xcode中的“录制”按钮,它将自动生成您的代码。 您可以在视图上添加可访问性标识符,以更轻松地访问它。 您可以手动编写代码,在这种情况下,您需要知道如何访问元素。 您可以使用LLDB中的以下命令来打印可见屏幕的详细视图层次结构: (lldb)po打印(app.debugDescription) 我更喜欢这最后一种方法,代码更具可读性。 编写您的第一个UI测试 使用无效的凭据登录: 如果用户输入无效的凭据,我们希望该应用程序显示错误消息: 让我们看看它如何转换为代码。 用户想要显示他的应用程序列表: 在这里,我们被迫等待假服务器的响应。 我们需要告诉Xcode等待,直到应用程序完成了视图的渲染。 如果不这样做,则由于目标对象尚未出现,我们的测试将失败。 为了强制Xcode等待,我对XCTestCase使用了扩展名: 用户希望查看应用程序的详细信息: 从Xcode 9开始,我们不再能够比较长度超过128个字符的字符串,因此我们不得不使用谓词:
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 […]