Tag: 测试

测试unitario Swift

西班牙语测试,测试,测试,测试,测试和测试。 重新测试无法实现的错误和不正确的解决方法。 1.目标测试 XCode的中型企业和中型企业的标志性形式。 (图像中的蓝色天空) En el mismo navegador,en la barra de abajo pulsamos sobre elbotón+ y seleccionamos 新单元测试目标 2.分类测试 埃尔·纽埃目标瓦斯·哈瓦拉·克雷多·厄瓜多尔·厄瓜多尔·普罗维克托·科普诺· 阿卡巴多 是的,您可以通过测试,测试和修复项目, 构建设置或公交车来启用可测试性和功能。 测试的目的是通过测试进行测试。 Volvemos al archivo Tests.swift。 Viene predefinido con unas funciones de las cuales solo vamos a dejar por el momento dos。 Dentro de la clase de test al lado de la […]

不起眼的TableView

我最近一直在考虑表视图。 表视图和集合视图已成为为许多类型的应用程序(尤其是内容驱动的应用程序)构建UI的默认方法。 但是,随着我们的表格视图变得越来越复杂,很难测试它们是否显示了正确的内容。 我认为创建可测试表的许多困难源于一种模式,在这种模式下,我们具有描述应用程序域的模型对象,然后尝试将其显示在表中。 尽管这些模型完美地描述了应用程序域的特定问题,但它们可能无法完全描述我们要在特定表单元格中显示的内容。 让我们看一个例子,然后看看如何改进。 我将使用表视图,因为它稍微简单一些,但是您也可以将这些技术应用于集合视图。 您的应用程序中可能有一些模型对象,它们描述了您的应用程序所关注的领域。 例如,如果您制作一个社交应用程序,则可能具有User , Friend和Message对象。 您可能是通过从api获得的Json表示形式创建对象来获得这些对象的,并在整个应用程序中使用它们来对应用程序的域进行建模。 在我们的示例中,我们可以想象一个音乐流应用程序,其中有一个特定艺术家的屏幕,其中显示了可以为该艺术家播放的所有曲目。 我们可能已经有一个域对象Track ,因此我们可以获取艺术家的所有Track ,并在表中显示它们: struct Track { let id:字符串 让标题:字符串 持续时间:双倍 让streamURL:URL } TrackCell类:UITableViewCell { func configure(track:Track){ //用轨道配置单元格 } } 好吧,还不错! 当用户打开艺术家页面时,我们将从MusicAPI获取Track ,并将其显示在表格中。 然后,该单元格可以显示曲目标题和持续时间,并且当用户按下播放时,我们可以开始流式传输。 通过此设置,我们直接从域模型( Track )转到UITableViewCell 。 但是,当我们必须在单元格中显示Track对象未描述的信息时,该策略就会Track 。 假设我们有一个新的要求–我们的应用程序现在可以下载轨道,并且需要在列表中显示每个轨道的下载状态。 我们的用户界面将如下所示。 在此示例中,已下载了第三首曲目,而其他未下载。 不幸的是,我们的Track模型现在无法完全描述TrackTableViewCell需要了解的所有内容。 我们是从MusicAPI获取Track的,但是我们需要参考DownloadsManager来确定是否在本地下载了轨道。 也许我们可以在创建单元格并将其分别传递给下载状态时调出给DownloadsManager ,甚至可以从单元格内部调用它,如下所示: TrackCell类:UITableViewCell { func configure(track:Track){ //用轨道配置单元格 downloadIcon.showDownloaded […]

如何不急于MVVM实现

假设您有一个小项目,过去仅在两天内就交付了新功能。 然后,您的项目将变得更大。 交货日期变得不受控制,从2天到1周,然后是2周。 它使您发疯! 您一直在抱怨:一个好的产品应该没有那么复杂! 那正是我所面对的,对我而言确实是一个糟糕的时刻。 现在,在该领域工作了几年之后,与许多优秀的工程师合作,我意识到产品设计并没有真正使代码变得如此复杂。 是我让事情变得如此复杂。 我们可能有编写意粉代码的经验,这严重损害了我们项目的性能,问题是如何解决它? 好的架构模式可能会有所帮助。 在本文中,我们将讨论一种好的架构:Model-View-ViewModel(MVVM)。 MVVM是一种流行的iOS体系结构,其重点是将用户界面的开发与业务逻辑的开发分开。 术语“好的架构”听起来可能太抽象了。 也不知道从哪里开始。 这里有个提示:我们可以将重点放在如何提高代码的可测试性上,而不必关注体系结构的定义。 有太多的软件架构,例如MVC,MVP,MVVM,VIPER。很明显,我们可能无法掌握所有这些架构。 但是,我们仍然可以牢记一条简单的规则:无论我们决定使用哪种架构,最终目标都是使测试变得更简单。 使用这种方法,我们在编写代码之前就开始思考。 我们强调如何直观地区分责任。 而且,按照这种思维方式,体系结构的设计似乎清晰合理,我们不再局限于琐碎的细节 TL; DR 在本文中,您将学习: 我们选择MVVM而非Apple MVC的原因 如何调整MVVM以设计更清晰的架构 如何基于MVVM编写一个简单的实际应用程序 您不会看到: MVVM,VIPER,Clean等之间的比较 解决所有问题的灵丹妙药 所有这些体系结构都有优点和缺点,但是它们都旨在使代码更简单明了。 因此,我们决定专注于为什么我们选择MVVM而不是MVC, 以及我们如何从MVC转向MVVM。 如果您对MVVM的缺点感兴趣,请参考本文末尾的讨论。 因此,让我们开始吧! 苹果MVC MVC(模型-视图-控制器)是Apple推荐的体系结构模式。 定义可以在这里找到。 MVC中对象之间的交互如下图所示: ViewController包含视图并拥有模型。 问题是我们曾经在ViewController中编写控制器代码以及视图代码。 它使ViewController过于复杂。 这就是为什么我们称其为Massive View Controller。 在为ViewController编写测试时,您需要模拟视图及其生命周期。 但是很难嘲笑观点。 而且,实际上,我们只想测试控制器逻辑就不想模拟视图。 所有这些使编写测试变得如此复杂。 因此,MVVM随时可以挽救。 MVVM —模型—视图— ViewModel MVVM由John Gossman在2005年提出。MVVM的主要目的是将数据状态从View移到ViewModel。 […]

UITests中的模拟网络请求

联网是iOS开发人员必须面对的长期问题。 几乎没有应用程序,不需要它。 在测试中,我们需要可重现且稳定的结果,而网络对此不做任何保证。 理想情况下,我们希望将Mac抛入地下100m的暗洞中并运行自动化测试。 没有网络连接不应该成为测试失败的原因。 由于应用程序依赖于从后端获取数据,因此这需要我们方面的一些工作。 在单元测试的存根网络调用中,我们确保控制了单元测试。 作为一个不错的副作用,它还提供了暗洞选项。 因此,无事可做。 概括地说,OHHTTPStubs用于返回NSURLRequest级别的数据。 遗憾的是,此技巧不适用于任何不与应用程序共享流程的UITest框架(EarlGrey可以工作;)。 继续使用OHHTTPStubs进行UI测试 您的第一个想法可能是:“为什么不在应用程序中使用OHHTTPStubs?” 这是可能的,但是有一些我不喜欢的原因: 很难控制需要退还什么。 它改变了应用程序内的许多逻辑。 它添加(测试)代码,该代码不属于生产代码。 控制后端 在编写UI测试时,您需要考虑要测试的内容。 您是要仅测试您的应用程序,还是要测试系统? 我工作过的公司倾向于测试整个产品。 这只是一个拐杖,因为他们对后端的正常工作没有信心。 测试您的系统听起来不错,但是错误并不能真正告诉您什么地方坏了。 您将不得不四处看看。 所以我建议 您 为您的应用程序使用UI测试。 为此,您必须为测试创建自己的后端。 它必须在同一台计算机上运行,​​因此不存在网络依赖性。 在一台机器上设置整个后端听起来有些矫kill过正,所以让我们跳过这一点。 相反,我建议创建一个模拟后端服务器,您可以在该服务器上控制测试所需的响应。 模拟后端的基本结构 我们对测试后端有什么要求? 我们可以控制,它返回什么 它在我们的应用程序之外运行 最小化我们的生产代码 这些只能通过编写我们自己的后端来实现。 最基本的想法是为每个请求类型提供一个带有字典的程序。 该词典将路径映射到响应。 因此,每当我们调用“ GET / hello”时,它将返回“ 200 OK – world”。 如果您希望将此后端编写为独立应用程序,则可以这样做。 也许有某种网络API,例如: “ / getRoute?path = hello&result = […]

单元测试— KIF和FBSnapshot

自从我谈论单元测试以来已经有一段时间了,在我们的应用程序和测试框架(如Quick和Nimble)中编写它们的重要性。 测试可以帮助我们保持功能正常运行,并避免新功能破坏旧功能。 我今天在这里谈论一个新框架:KIF。 这篇文章对KIF,优点,缺点,何时使用它以及一个示例进行了思考。 是一个单元测试框架,可帮助开发人员创建UI测试(是的,UI测试)并测试您的应用程序流,例如整个登录过程,例如,如果用户触摸键盘时键盘消失,则输入有效凭据,轻扫tableView单元格,当无效用户名的警报弹出。 它是用objc编写的,使用XCTestCase,但是如果您想将它与Quick一起使用,则可以使用KIF-Quick。 它带来了有助于执行事件的功能,如tap() , swipeLeft()和swipeLeft() 。 使用accessibility来标识要与之交互的对象,例如,您可以使用其accessibilityIdentifier或accessibilityLabel检索对象,然后使用tap()执行操作 viewTester().usingIdentifier(“btn_login”).tap() 您应该问自己-如果Apple提供了一个不错的UI测试框架,为什么我应该使用KIF-答案很简单:模拟! 通过KIF,您可以注入模拟对象来创建应用程序的强大本地测试流,换句话说,您可以自由模拟服务响应并测试整个应用程序流,而无需Internet连接,API响应甚至数据量。 哇! 那很棒。 那么,为什么我应该编写单元测试(如果KIF可以处理更多)? 这是个好问题! 的确,KIF可以处理单元测试以及更多内容,但是它需要在模拟器上运行并且需要时间。 因此,如果您决定仅使用KIF编写测试,则运行这些代码所花费的时间将比单项单元测试多得多。 如何使用它 通过cocoapods,KIF的安装过程很容易,只需将pod KIF添加到您的podfile运行pod install并完成。 KIF是用Obj-C编写的,因此您需要创建一个桥接头并向其中添加KIF。 #import 在此示例中,我们将测试带有成功和失败案例的简单登录流程。 将KIF和Snapshot的功能结合在一起(如果您不知道什么是Snapshot,则应该阅读此内容),我们将验证所有UI。 如果用户输入正确的值(在这种情况下,用户名是“ user”,密码是“ 123123”),则将显示主屏幕,否则将显示警告错误。 不要忘记测试目标并在将要交互的每个UI对象中设置可访问性标签。 DefaultFlowSpec测试 在此文件中,我们创建一个窗口,从情节viewController检索初始viewController并将其添加为窗口的rootViewController 。 之后,我们需要测试我们的成功和失败流程。 成功流程 我们的成功流程基于正确的投入。 首先,用户将在用户123123中设置user , 123123在密码字段中设置123123 ,我们现在要检查UI,然后单击login按钮并检查是否显示了homeScreen 。 成功流程 失败流程 在失败流程中,我们将按login按钮,检查是否显示错误警报,对警报按ok ,然后检查警报是否消失。 失败流程 结论 最好的方法是将单元测试和KIF结合起来以获得快速而完整的测试。 继续使用单元测试来测试您的方法和功能,这会更快。 使用KIF测试UI和MVC架构中模型,视图和控制器等层之间的连接。 我写了一些文章,展示了如何实现一些单元测试。 第1部分-具有Nimble + […]

了解不稳定的iOS单元测试:XCTestCases基础知识

曾经试图弄清楚为什么单元测试随机失败了吗? 试图解决这些问题时花了很多血汗和眼泪? 对于我从事的许多较大的长期项目来说,不稳定的单元测试是一个真正的问题。 他们占用了时间和精力,而这可以在其他地方得到最好的利用。 我已经看到一些公司禁用了许多测试,从而在测试服中留下空白,在某些极端情况下,由于事情太重了,删除了整个测试服。 我是一个测试狂,我喜欢这些东西,多年来,我学到了一些我想分享的技巧。 我希望其中一些可以使您摆脱我遇到的同样的陷阱。 但是,在深入了解细节之前,让我们退后一步,首先看看XCTestsCases是如何工作的。 不了解这些测试的流程会导致我遇到的大部分问题。 XCTestCase流程 了解XCTestCase流程的最好方法是运行以下测试代码,并在测试运行后查看调试(“ >>>”在那里,您可以进行过滤并轻松查看流程)。 在示例代码中,测试类ExampleTestCase包含一个Object和两个测试函数testExampleA和testExampleB (在此示例中,我们对Object的作用并不真正感兴趣,只是其生命周期与XCTestCase有关) 这是输出… >>>对象初始化0x0000600000b94290 >>>对象初始化0x0000600000b942d0 >>> testExampleA 0x0000600000b94290 >>> testExampleB 0x0000600000b942d0 这告诉我们什么? 在编写测试时,我们需要牢记此输出中的一些关键信息: 为每个测试功能创建一个ExampleTestCase对象,并且在运行任何测试之前首先创建所有对象。 测试按字典顺序运行,而不是按文件中表示的顺序运行。 ExampleTestCase不会被释放,因此从不释放对象 。 这种流动如何影响稳定性? 作为开发人员,我们有各种各样的机会编写不稳定的测试。 后续帖子将更详细地介绍在过早创建对象并将其与诸如Observer和特定类型的Singletons等模式以及其他可能导致不稳定的事物(如UIWindow和UINavigationControllers。 对于简单的简短测试文件,您可以在测试函数中创建所有属性。 但是,随着事情变得越来越复杂,这可能变得很麻烦,因此最好在setUp中创建所有属性, 然后在tearDown中手动释放它们 。 我只在Objective-C测试中看到过此技巧,但是如果您已经进行了不稳定的测试,那么您可以做的第一件事就是释放tearDown中的所有内容,这有时会导致测试崩溃,方法是可能导致问题。 即使您没有任何不稳定的测试,也最好立即开始在tearDown中释放对象,以在出现任何潜在问题之前捕获它们。 您可以开始使用XCode10新功能对测试进行随机化,要记住您拥有的测试越多,随机组合就越多。 如果发生问题,您需要能够看到他们重新创建问题的顺序,因此请确保您的CI系统可以为您提供所需的信息。 在编写测试时,我们需要注意以下几点 XCTestCase为每个方法创建一个新的测试类。 每个XCTestCase类及其所有属性都是在运行任何测试之前预先创建的。 XCTestCase不会自动释放。 测试未按定义的顺序运行。 在setUp中创建XCTestCase属性,并在tearDown中手动释放 相关链接 NSNotifications测试不稳定

iOS UI测试,汗水…绕……更多汗水(第1部分:Stubbing网络)

当我试图为我的iOS项目争取到一个名为CI / CD的黄金之山时,UI Testing是我必须征服的山谷。 在那个地方,那是一次浩大,朴实而又烦人的经历。 Xcode为我提供了一种在旅途中帮助我的武器,该武器称为XCUITests。 该武器在访问,交互以及在我必须击败的测试中主张时具有很大的壮举。 但是对于存根网络来说,这就像枪战中的一把刀-它使我丧命。 反应过度? 我不这么认为,在这个山谷中,您需要隔离自己,以便一切顺利。 从真实服务器获得真实响应只会延迟测试,如果没有失败的话。 盯着空白处,我一直想知道应该怎么做……直到它撞到我身上。 OHHTTPSTUBS 我很高兴找到另一种名为OHHTTPSTUBS的武器。 OHHTTPStubs是一个旨在非常轻松地对您的网络请求进行存根的库。 —取自GitHub 当我穿越那片广阔的平原时,我高兴地哭了。 乐观地说,我跳得更快,跑得更快。 就像我找到了击败龙的武器。 我的心跳加快,然后突然停下来(我还没死,很冷)。 我面前出现了一个障碍物,它的魔力使我飞回了山谷的入口。 怎么了? 我在寻找线索,武器的背面写着一个线索。 杜德(Dude),托管测试非常棘手 我认为这是为了另一个叫做“单元测试”的山谷(这是我必须走的另一条路,但是让我们稍后再谈)。 那颗充满希望的闪烁星光突然使我失望。 但是,我仍然在绝望中寻找一种更相关的武器。 也许这不是我需要的武器,可能不是车辆还是房屋? 方便地,一个老隐士路过并丢下了一封信。 我在心里大声朗读。 亲爱的儿子, 您所需要的不是武器,车辆或房屋。 这是一个模拟服务器。 尝试一些事,例如迅速或使馆 -您方便的陌生人 哦,好吧……隐士似乎不喜欢类比。 为了寻找线索,我竭尽全力击败了这个令人烦恼的山谷。 看起来很奇怪,我将尝试其中之一。 迅捷 事实证明,这个“微小的HTTP服务器”是我的解决方案,我的光明了我的黑暗,我的罗密欧是我的朱丽叶,我的托尼·斯塔克是我的奇异博士,我明白了。 遵循此页面上的任务指南,我立即迈出了第一步。 但是首先,我必须下定决心,下定决心,并确定自己的build configuration和scheme 。 使用新scheme我可以为我的应用程序提供一个环境,该环境连接到localhost:8080(Swifter将在其中托管HTTP服务器)作为该服务器的base url ,我可以得到预期的响应,我必须为每个端点提供该响应我的应用最初与之联系。 预期的响应可以与JSON文件一起提供。 锁好并装好,我准备出发了。 我可以说,第一步是“冗长但必要的”。 当我浏览端点回答日记*咳嗽* apiary *咳嗽*时,我自信地走着。 我将所有这些注释放在由JSON扩展标记的单独注释中,并将这些注释放入我的资源中。 之后,剩下的就是在公园里漫步。 […]

编写可扩展XCUITests的技巧— WWDC 2017

在WWDC 2017上,有一个关于可测试性工程的精彩演讲,重点关注测试代码以及​​应用程序代码质量的重要性。 演讲介绍了通过编写出色的测试代码来提高应用程序可测试性的各种方法。 最重要的一点是第二部分,其中分享了改善UI测试的可伸缩性的技巧。 在这篇文章中,我们将看到Apple工程师分享的那些技巧。 请记住,这不仅仅是在WWDC上发表的演讲的复制粘贴,本文还提供了一些在Github 可扩展XCUITest上的演示项目的真实示例,以证明这些观点。 WTF是可扩展的测试代码吗? 即使未在生产中执行,测试代码也与应用程序代码一样重要。 我们绝对应该使我们的应用程序可测试,但还要付出一些努力使测试代码更具可伸缩性。 因此,可扩展测试代码的好处是 更快地运行我们的测试 使我们的测试即使对于非技术人员也更具可读性 以更好的方式组织测试代码,避免重复 轻松添加新的测试用例 示例应用 让我们探讨一下Apple工程师共享的一些技巧,这些技巧可通过示例应用程序Expandable-XCUITest使测试代码可扩展 ,该应用程序具有6种不同颜色的按钮,分别是红色,绿色,蓝色,黑色,灰色和黄色。 这是一个非常简单的应用程序,但请想象我们必须测试一些东西,例如 轻按所有颜色 只需点击RBG颜色 点击非RBG颜色。 不可缩放的UI测试如下所示: func testTapAllColorNonScalable(){ XCUIApplication()。buttons [“ RED”]。tap() XCUIApplication()。buttons [“ BLUE”]。tap() XCUIApplication()。buttons [“ GREEN”]。tap() XCUIApplication()。buttons [“ BLACK”]。tap() XCUIApplication()。buttons [“ YELLOW”]。tap() XCUIApplication()。buttons [“ GRAY”]。tap() } 再次测试RGB和非RGB值,我们几乎必须重复同样的事情。 您可以在此处查看测试类Non_Scalable_XCUITestUITests.swift ,并猜测它有多混乱。 通过使用讲座中描述的技术,我们绝对可以做得更好。 编写可伸缩XCUITest的技巧 通过使用一些常见的面向对象的原理(例如抽象和封装),可以共享一些技巧以使测试可伸缩,可维护且更快。 让我们来看一些技巧 抽象的XCUIElement查询 如果存在多次使用XCUIElement查询的情况,请将其存储为变量。 在上面的示例中,我们点击了6次按钮,但唯一改变的是按钮的颜色。 我们可以轻松地将其包装到方法中。 […]

信息推送通知证词

敲门声,“我”的意思是“克纳布”,“我”是“克纳布”。 Sayesinde推送通知testimizi servis kullanmadan测试edebiliyoruz。 İkteböylebir nimet bu Knuff。 İndirmekiçin→n Xcodeüzerinde推送通知içingerekligeliştirmeleriyaptığınızıvebaşarılıbirşekildebildirimlerialdığınızıvarsayıyorum。 哈迪çalıştıralımşulanetolasışeyi! 1-自定义:Uygulamamızınsertifikasıile bildirimgöndereceğimizyer。 Knuff iOS:Knuff’ınçalıştığındanemin olmakiçin iOS的indirek bildirimgönderebilirsiniz。 密码为“ nizialmasınaizin verin”的设备。 Sonra MacOSuygulamasındaKnuff iOS”dandevices’ıseçinve kendi telefonunuzuseçin。 2-选择butonu ileuygulamamızın推送通知sertifikasınıseçiyoruz。 Xcode’dakullandığınızprovizyonunortamıile pushnotification’ınortamınınaynıolduğundanemin olun。 İkiside ya development ya da distributionolmalı。 选择Xcode’da开发provizyonunukullandığımiçin,选择“ Apple Development IOS推送服务:com.xxx.xxx”即可。 3-设备ID’mizi burayayapıştırıyoruz。 4-Gönderilenbildirimler json格式ındadır。 Bu json’a ekleme yaparak bildirimegöreaksiyon alabiliriz。 测试 儿子olarak Knuff’daki bildirimjson’ımşuşekilde; […]

蒸气3系列III-测试

在上一篇文章中,我们实现了两种验证用户身份的方法:HTTP基本身份验证和承载令牌授权。 因此,我们的应用程序仅接受来自经过身份验证的用户的请求。 但是,即使我们的应用程序很简单,我们也应该为端点编写一些单元测试。 测试是软件开发的重要组成部分,编写单元测试使我们能够快速开发和发展应用程序。 为了快速开发新功能,我们希望确保现有功能不会中断,并且拥有完善的测试套件可让我们验证更改代码库时一切仍然正常。 在本文中,我将演示如何为CRUD端点编写单元测试,以及如何在具有Docker的Linux机器上运行测试。 请注意,本文将基于先前的实现。 在Swift中编写应用程序的好处之一是,我们能够使用可爱的Xcode运行测试。 但是,为了使用Xcode运行测试,我们必须事先生成测试目标。 请打开Package.swift并将以下行替换为.target(name: “Run”, dependencies: [“App”]) 。 让我们开始编写Application的辅助方法。 请打开Application+Testable.swift并添加以下代码。 现在,我们可以运行测试用例了,它应该通过了! 然后,我们可以为用于检索User模型的端点编写测试用例。 在UserTests.swift内部,将以下函数追加到testUserCanBeSaved函数下方。 这是整个项目。 让我们回顾一下这个测试过程。 首先,我们生成新的测试目标和相应的文件。 此外,我们编写了Application和User模型的辅助方法,以使我们的测试用例简明易懂。 其次,我们使用辅助方法编写每个端点的测试用例,并使用Xcode运行测试。 最后,我们使用Docker在Linux环境上运行测试用例。 测试是软件开发的重要组成部分,并且编写单元测试并使其尽可能自动化是有益的。