概括地说,我们编写的测试分为3个不同的类别: 单元测试是人们可以编写的最简单的测试,并且顾名思义,它可以独立测试单个代码单元。 它们既快速又稳定,我们可以编写很多它们,它们是其他测试的基础。 一个普遍的误解是,单元测试仅针对模型(即处理数据的实体)编写。 另一方面, UI测试是对整个事物进行整体测试的工具-它们从用户角度检查系统,并且极易损坏。 UI测试既昂贵又缓慢,并且是需要不断进行维护以跟上不断发展的系统的测试。 我们应该始终努力减少运行测试所需的时间-通过将大量的UI测试转移到单元测试,我们可以获得绝缘和速度方面的好处。 这是一个例子…… 假设我们在UIViewController中有一个UITableView,它应该覆盖整个视图。 我们的测试不应检查tableView是否正确“拉伸”(最终结果),而应检查视图是否具有上述约束(并相信系统在内部做正确的事情): 这个简单的测试比任何UI测试都快得多,并且不依赖于应用程序的其他部分来加载和显示View Controller(根据UI测试的要求)。 希望这可以帮助。 测试愉快! 为了完整起见,这是整个TasksViewControllerTests类:
测试驱动开发(TDD)可以帮助您完成测试驱动开发(TDD) 。 Genellikleyanlışbirkanıolarak单元测试yazmanınuygulamageliştirmesüresiniuzatacağıdüşünülüyor。 Halbukiuygulamamızdaöncedenunit testleriyazılmasıdaha kolay birşekildeyapılacakişlevintasarlanabilmesinisağlar。 布达下摆tasarım下摆işlevintestinde bize zamankazandırdığıgibi kodu daha iyiyapılandırabilmemizede olanaksağlar。 Bu nedenle unit testler ile uygulamageliştirmemizdaha sonraoluşacakmuhtemelbuglarıdaöncesindetespitedebileceğimiziçinuygulamageliştirmesüresiniazaltacaktır。 Uygulamamızınkod kalitesiniartırarakdaha az bir bug ilegeliştirebiliriz。 单元测试器下摆pozitif下摆negatif caseler ile beraberyazdığımızdaolabilecekbirçokfarkli案例测试etmeolanağınakavuşmuzoluruz。 Buda iyi testedilmişve daha az bugiçerenkodyazmamızısağlayacaktır。 Yazdığımız单元测试仪daha sonra uygulamadakioluşabilecekdiğerbuglarıtespit etmemizde bizeoldukçakolaylıksağlayacaktır。 Budauygulamamızdakigelecek olanbuglarıçözmesüremiziönemliölçüdeazaltacaktır。 Teamcity gibi CI( Continus Integration)单元测试人员, Jenkins单元, 测试系统(SUT)(测试中) prensibine uygunsürekliolarak测试,edilen biruygulamamızolur。 Projedeyapılan她的承诺sonrasındaunit […]
我们如何在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。 在每次测试执行之前,我们将启动一个参数,指示我们正在运行测试。 […]
免责声明:阅读前请检查对本文的评论。 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
注意:这是原始访客博客的重新发布,我在 此处的 Bitbar博客上写道 在宣布推出三款新iPhone之后,苹果及时发布了iOS 12。 新的iOS版本在性能和用户体验方面具有丰富的功能,并在性能,安全性和隐私性方面进行了重大改进。 在为用户考虑这些新功能的同时,我们还需要考虑此版本对每个iOS开发人员和质量检查工程师的意义。 在这篇文章中,我们将探讨Apple新操作系统的一些主要开发和测试注意事项。 每个iOS开发人员都应了解以下新功能。 Xcode 10 新建系统 平行测试 xccov的代码覆盖率 创建ML Siri快捷方式 ARKit 2.0 CarPlay + Google Map 这些是iOS 12的一些特定于开发人员的关键功能。您准备好升级技术堆栈以支持这些iOS 12功能了吗? 正如我之前所说,这是我在Bitbar上的原始博客的转贴。 为了进一步了解面向开发人员和质量检查工程师的iOS 12功能,请在此处阅读Bitbar博客上的原始文章 让我知道是否错过了iOS 12的开发人员专用功能。 ======================================== 像XCBlog的XCTEQ发布的帖子一样? 您可能还会喜欢我们在 Github 上的一些开源项目, 或者在 Twitter 和 LinkedIn 上关注我们 XCTEQ 对于为Apple平台构建应用程序的公司 而言, 是生产力的提高。 让XCTEQ自动执行平台应用程序(iOS,macOS,tvOS)的构建,测试,发布,CI / CD管道,然后您专注于构建业务功能。 不要在错误的CI / CD和测试自动化工具上浪费时间和金钱,请接受专家的建议。 在 http://www.xcteq.co.uk上 查看XCTEQ产品和服务, 或通过info@xcteq.co.uk。给我们写信。
自动生成测试? 是的,请。 这篇文章展示了如何使用Markdown表为您的软件/应用程序编写业务逻辑 ,以及如何使用名为AcceptanceMark的命令行工具为Xcode 自动生成测试 。 但是首先,一些背景 。 您的代码可能具有以下测试形式: 单元测试 整合测试 验收测试 UI测试 阅读此处 可以很好地了解它们之间的区别。 此外,您可能有一个专门的质量检查小组,并定期手动运行您的应用程序以验证其正确性。 虽然编写好的测试对于构建高质量的软件是必不可少的,但这也需要花费很多时间。 我将向您展示如何更快地测试代码 ,以便您可以将时间花在更重要的事情上! 测试,Xcode方式 在Xcode中,可以通过子类XCTestCase编写单元测试或UI测试 。 假设您的被测系统(SUT)是一种日期格式化程序,需要使用各种可能的语言/输入日期才能正常工作。 测试类可能如下所示: 并将其自动转换为Xcode测试类吗? 好吧, 我已经编写了一个名为AcceptanceMark的工具来 完成该任务 。 只需在终端上运行此命令: amtool -i DateFormattingSimple.md 该工具将生成如下所示的Swift测试文件: 一些观察: 年 , 月 , 日 , 小时 , 分钟 , 第二列被注释为Int 。 AcceptanceMark还不支持将日期作为内置类型使用,但是可以在此处使用单独的组件,以便日期输入与格式无关。 语言列是语言环境标识符字符串。 dateStyle列是一个字符串。 dateStyle和localizedDate之间有一个空列。 这称为分隔符列 。 AcceptanceMark将其前面的所有列均视为输入,并将其之后的所有列均视为输出。 AcceptanceMark始终需要分隔符列 […]
原始 博客文章 : http : //shashikantjagtap.net/podcast-interview-automating-ios-apps-in-the-apple-bubble/ 最近,我接受了Joe Colantonio的播客采访,主题为“在Apple Bubble中自动化iOS应用程序”,讨论了iOS测试自动化和iOS DevOps空间的当前趋势。 Joe运行了TestTalks播客,所有有关测试自动化最佳实践的内容,到目前为止,他有199集。 他已经采访了许多行业专家,我很高兴也有机会与他进行了采访,分享了我在iOS自动化和DevOps方面的经验。 我的采访是TestTalks播客系列的第199集。 在iTunes上可以找到它,也可以在TestTalks网站上找到播客片段的详细信息。 在此播客采访中,我们涉及了iOS测试自动化和DevOps的各个主题,包括 这些天公司如何测试iOS应用程序? 如何为iOS测试自动化XCUITest Vs Appium选择工具? iOS中有哪些“行为驱动开发”选项? 如何使iOS Tests CI或DevOps友好? 如何在iOS应用程序中测试REST API? AI / ML可以测试iOS应用程序吗? 如果您要使用iOS Automation或iOS DevOps,则一定要查看此剧集。 在手机上喜欢的播客客户端中搜索“ TestTalks”第199集。 希望您会发现此情节有用。 让我知道你的想法? 我在Twitter @ Shashikant86 像XCBlog的 XCTEQ 发布的帖子一样 ? 您可能还喜欢我们的一些服务,例如访客博客或Mobile DevOps(CI / CD)或测试自动化。 在 Github 上 搜索我们的 服务 ,开源项目, 或者在 Twitter , […]
最初在 这里 发布在XCBlog上 在将iOS应用发布到Apple App Store之前,通常有一个针对内部受众的构建,即质量检查工程师,仅在特定配置的设备上运行的产品所有者。 在此过程中,您可能会听到诸如DEBUG或RELEASE配置之类的信息。 当我们使用Xcode创建新的iOS项目时,Apple为我们提供了两个项目级别的构建配置,即调试和发布。 调试配置通常用于开发和内部项目设置,例如将应用程序指向测试环境,然后使用发行版将应用程序提交到App Store。 但是,在许多情况下,可能会触发对更多内部设置或其他构建配置的需求。 作为一名优秀的iOS开发人员,您必须使用XCTest框架编写单元和UI测试。 通常,开发人员使用调试构建配置或运行单元和UI测试,但是为XCTest创建单独的构建配置会使测试更加独立,可靠和确定性。 在本文中,我们将看到如何为XCTest创建单独的构建配置。 构建配置 在进入创建新的构建配置之前,让我们看看什么是iOS中的构建配置以及为什么使用正确的配置构建应用很重要。 想象一下,我们已经在Xcode中创建了全新的iOS应用。 它将有两个构建配置,分别在iOS项目的“构建设置”中进行调试和发布。 在编译和构建iOS应用程序时,幕后发生了很多事情,例如编译,链接,复制包资源,运行构建脚本等。我们始终可以在xcodebuild日志中看到这些事情。 构建配置定义了我们希望如何在特定设置下构建应用程序,例如,当我们使用模拟器开发应用程序时,“调试信息格式”构建设置不需要生成dSYM文件,因此我们可以使用DWARF进行调试构建。 但是,我们需要发布版本的信息,以便我们可以将DWARF与dSYM文件设置一起使用。 如上图所示,您可以在Xcode的所有构建设置中看到这一点。 简而言之,构建配置定义了一种机制,该机制应如何使用不同的条件或设置构建应用。 在运行使用XCTest框架编写的单元或UI测试时,仍然可以使用调试配置,但是,添加其他配置可以使我们对测试过程进行大量控制。 XCTest的构建配置 现在,我们将添加另一个仅可用于XCTest单元或UITests的构建配置。 通常,单元测试需要较少的配置,因为我们可以直接在应用程序内部访问数据和API。 但是,UITests或XCUITests完全是黑盒子,因此我们需要在那里进行更多配置,以便通过UI测试的特定设置。 让我们从Xcode为示例iOS应用添加另一个构建配置开始。 在Xcode项目级别设置中,选择“信息”选项卡,我们将看到可用配置的列表以及添加更多配置的选项 注意,我们必须进行项目级别的配置才能获得此选项,而不是目标级别的配置。 单击配置中的+按钮。 我们可以通过复制调试或发布配置来添加其他配置。 通常,为了测试目的,我们需要重复调试配置,因此我们将其称为xctest在“ 配置”部分下,按+按钮。 选择“ 重复调试配置” 。 命名您的新配置xctest 现在,我们有了全新的构建配置,可用于单元测试或UI测试。 我们可以将用户定义的设置分配给新配置,以便我们可以设置测试特定的配置。 在项目构建设置中,向下滚动到构建设置的最底部,有一个名为User-Defined的部分。 这是将添加和设置配置变量的位置。 预处理器宏 现在,我们添加了新的构建配置,是时候更改预处理器宏了,以便我们可以设置源代码有条件地执行一些代码 现在,我们可以使用调用测试代码的主应用程序中的代码来唤醒此配置。 #if XCTEST //仅测试代码版本代码 #其他 //仅应用程式程式码 #万一 同样,我们可以使用相同的方法来更改不同的环境,例如阶段,测试,但是某些文章已经介绍了该方法。 一些受欢迎的文章是 Xcode项目中的多个构建配置 […]
最初在 这里 发布在XCBlog上 苹果已经发布了带有Xcode 9.3的新命令行工具xccov,用于检查Xcode代码覆盖率报告的内容。 不幸的是,还没有任何Web文档,因此我们必须在终端中键入man xccov以获得有关此命令行工具的更多信息。 此实用程序需要Xcode 9.3和Xcode 9.3附带的命令行工具。 使用xccov,我们可以使用人类可读格式以及机器可表示格式(例如JSON)生成Xcode代码覆盖率报告,而无需使用第三方工具。 在本文中,我们将探讨如何使用带有演示iOS应用的新命令行实用工具生成和查看Xcode代码覆盖率报告。 注意名字 命令行工具xccov是Xcode 9.3附带的本地Apple开发人员工具。 但是,很少有名称相似的开源工具可能会使您感到困惑。 不是xcov 有一个名为xcov的Ruby库可生成美观的代码覆盖率报告,可与Fastlane和Danger等工具一起使用。 不是hiroakit / xccov 还有另一个纯粹的Swift库可以生成Xcode代码覆盖率报告,也称为xccov,但由Hiroaki ENDOH编写 这些库的名称与Apple发行的新实用程序相似或几乎相似,巧合的是,它们正在执行相同的工作,即为Xcode生成不错的代码覆盖率报告。 随着苹果公司xccov的发布,可能不需要这些库。 生成代码覆盖率报告 为了探索xccov,让我们使用带有单元和UI测试目标的“ Tabbed App”模板创建一个新的iOS应用,并将其命名为“ XCCov-Demo”。 这将创建Xcode项目方案“ XCCov-Demo”。 我们可以通过编辑方案并在“测试”操作中选中“代码覆盖率”框来明确启用该方案的代码覆盖率。 如果我们不想包括UITest的覆盖范围,我们也可以过滤目标,如下所示 现在,我们为方案启用了代码覆盖率。 一旦我们使用Xcode中的CMD + U按钮构建并测试了该方案,这将生成代码覆盖率报告到默认的派生数据目录中,该目录位于〜/ Library / Developer / Xcode / DerivedData中,您将看到在Logs / Test中生成的代码覆盖率报告目录。 但是,对于此演示,我们将在项目内部生成派生数据,以便我们可以轻松查看报告。 让我们使用xcodebuild从项目根目录使用以下命令来构建和测试我们的应用程序 $ xcodebuild -project XCCov-Demo.xcodeproj / -scheme […]
测试驱动开发(TDD)是软件开发人员可以在软件开发中使用的方法之一。 在TDD中,开发人员计划要创建的软件功能,然后在编写功能实现之前,为软件的每个功能编写测试用例。 在开始时,测试用例显然会失败,因为代码尚未实现。 此阶段通常称为红色阶段。 然后,开发人员编写代码以确保测试用例成功通过,并且不会破坏任何组件或当前的测试用例,因此不必完全优化和高效地完成此阶段中的代码。 此阶段称为绿色阶段。 此后,开发人员应通过清理,维护代码库和优化代码效率来重构代码的实现。 然后,应在添加新的测试用例时重复此循环。 每个测试单元应做得尽可能小且隔离,以使其易于阅读和维护。 在本文中,我们将使用带有Xcode XCTest Framework的TDD构建一个简单的网络API单元测试。 Network API将对服务器的网络调用封装为以JSON格式获取电影列表,然后将其编码为Movie Swift类的数组。 网络测试需要在不发出实际网络请求的情况下快速执行,为此,我们将创建模拟对象和存根来模拟服务器调用和响应。 APIRepository类:此类封装了我们对服务器的网络请求调用,以获取电影列表 APIRepositoryTests类:XCTest子类,我们将使用该子类为APIRepository类编写测试用例 MockURLSession类:URLSession子类,充当模拟对象以测试传递的URL以及使用存根数据,URLResponse和Error对象创建的MockURLSessionDataTask MockURLSessionDataTask类:URLSessionDataTask子类,充当模拟对象,用于存储网络调用中的存根数据,URLResponse,Error,completionHandler对象,它覆盖恢复调用并调用传递存根对象的completionHandler存根。 测试用例1 —从API获取电影按预期设置URL主机和路径 我们将创建的第一个测试用例是测试get films方法是否在正确的期望范围内设置了URL Host和Path。 首先在“测试”模块内创建APIRepositoryTests单元测试类。 不要忘记添加“ @testable import project-name”以将项目模块包含在测试模块中。 要在Xcode中运行测试,可以使用快捷键Command + U。 在函数中,我们设置实例化APIRepository类对象,此方法中创建了一个名为testGetMoviesWithExpectedURLHostAndPath()的方法,因为我们尚未输入APIRepository类,所以我们键入了有关未解析标识符APIRepository的编译器投诉。 导入 XCTest @testable 导入 APITest 类 APIRepositoryTests:XCTestCase { func testGetMoviesWithExpectedURLHostAndPath(){ 让 apiRespository = APIRepository() } } 要编译测试,请创建一个包含APIRepository类的名为APIRepository.swift的新文件。 导入基础类 APIRepository {} 接下来,在testGetMoviesWithExpectedURLHostAndPath内部,我们将调用APIRepository方法,以从通过完成处理程序的网络中获取电影。 […]