6

背景

我正在寻找一种方法来实现类似于Frank 库用于实现“原生 iOS 应用程序的自动化验收测试”的方案,但我希望这个方案依赖于原生 iOS/MacOSX 技术。很抱歉以下内容TLDR,但值得详细解释。

1.以下是 Frank 工作方式的简要概述:

它有客户端和服务器部分。

服务器部分嵌入到我们要对其运行验收测试的应用程序中。Frank 教程向我们展示了如何创建应用程序主目标的重复目标并将 Frank HTTP 服务器嵌入其中。

客户端部分 - 主要是一个运行纯文本场景的Cucumber:每个场景都包含应该针对应用程序运行的指令(填充文本字段、触摸按钮、确保页面上存在特定元素等......)。此外,每个场景都会启动自己的应用程序实例,这意味着每次我们进入一个新场景时都会提供一个新的状态。

客户端(Cucumber 和 Ruby-to-Objective-C 桥)通过 HTTP 协议与服务器(嵌入到应用程序中的 HTTP 服务器)通信。它使用特殊约定,因此客户端可以告诉服务器应用程序应该做什么,以便可以执行特定场景。

2.最近发现Frank Pete Hodgson的作者写的以下文章:

http://blog.thepete.net/blog/2012/11/18/writing-ios-acceptance-tests-using-kiwi/

在其中,他建议为不喜欢依赖 Cucumber 和 Ruby 等外部工具的开发人员编写更简单的验收测试方法。让我引用作者自己的话:

在开始之前,让我明确一点,我个人不会使用这种方法来编写验收测试。我更喜欢使用像 ruby​​ 这样的高级语言来编写这些类型的测试。假设您对 ruby​​ 很熟悉,那么测试代码的工作量就更少了,表现力也更强了。这就是我想尝试这个实验的原因。随着时间的推移,我与不少不习惯用 ruby​​ 编写测试的 iOS 开发人员交谈过。他们在 Objective-C 中比其他任何东西都更舒服,并且希望用他们用于生产代码的相同语言编写测试。很公平。

这篇博文启发了我快速推出自己的原始工具,该工具完全符合 Pete 在他的博文中所描述的内容:NativeAutomation

实际上,就像 Pete 所描述的那样,可以通过仅使用放置在简单 OCTests 目标中的 Kiwi/PublicAutomation 设置来运行验收测试。我真的很喜欢它,因为:

  • 它只是纯 C/Objective-C。构建最初的一堆 C 助手非常容易,看起来像Capybara助手:

tapButtonWithTitle、fillTextFieldWithPlaceholder、hasLabelWithTitle 等等……

  • 它不需要外部工具和语言:在 Cucumber/Ruby 或其他任何东西中都不需要。NativeAutomation 本身只使用Frank 也使用的PublicAutomation 。需要 PublicAutomation 来模拟应用程序屏幕上的用户交互:触摸、填充、手势......

  • 通过运行 Cocoa Unit Tests 包直接从 Xcode 运行这些测试非常方便。(虽然命令行构建也很容易)。

问题

问题Kiwi/PublicAutomation方法是将整个测试套件嵌入到应用程序的包中。这意味着在每个场景运行后,在下一个场景开始执行之前,无法重置应用程序以强制它处于新状态。解决此问题的唯一方法是Kiwi's beforeEach使用执行应用程序软重置的方法编写挂钩,例如:

+ (void)resetApplication {
[Session invalidateSession];
[LocationManager resetInstance];

[((NavigationController *)[UIApplication sharedApplication].delegate.window.rootViewController) popToRootViewControllerAnimated:NO];

[OHHTTPStubs removeAllStubs];

cleanDatabase();

shouldEventuallyBeTrue(^BOOL{
    return FirstScreen.isCurrentScreen;
});

但是在涉及网络、异步作业、核心数据、文件操作的应用程序中,很难对先前场景留下的东西进行真正的拆解

问题

上面描述的问题让我开始思考是否有可能实现类似于 Frank 的方法的更复杂的方法,第二个应用程序与主应用程序的捆绑包分开工作,并且不依赖于 Cucumber(Ruby) 等外部工具。

这是我如何看待它可以完成的方式。

除了一个主应用程序 (MainApp),还有第二个 iOS(或 Mac OS X)应用程序 (AcceptanceTestsRunnerApp),它包含整个验收测试套件,并针对一个主应用程序包运行该套件:

它会在进入每个新场景之前启动新的模拟器实例,并针对当前模拟器的应用程序实例执行当前场景。


问题是:

我不太了解允许我这样做的 Mac OSX 或 iOS 技术:我什至不知道是否可以设置一个可以控制主应用程序的 Mac OS X / iOS 应用程序 (AcceptanceTestsRunnerApp) (MainApp) 并针对它运行验收测试方案。

对于那些对使用原生 Objective-C 工具为 iOS 应用程序编写验收测试感到更自在的人可能有的任何想法/建议,我将不胜感激。


稍后更新

...我确实阅读了一些关于 XPC 服务的文档,但具有讽刺意味的是,我正在寻找的方案应该与 XPC 文档建议的方案完全相反:

理想情况下,我希望我的 AcceptanceTestsRunnerApp 支配 MainApp:通过一些对象代理到 MainApp 的应用程序委托来运行它并控制它(用户交互、关于视图层次结构的断言),而 XPC 服务设置将假定 XPC 服务 (AcceptanceTestsRunnerApp) 从属于应用程序 (MainApp ) 并且将要求 XPC 服务存在于我想通过各种方式避免的应用程序包中。

...我目前的阅读是分布式对象编程主题。在我看来,我会在那里找到我的答案。如果没有人为我提供指南或方向,我将发布有关我自己的研究和想法的答案。

...这是我追求的下一步:iOS 上的分布式对象

4

1 回答 1

0

根据我的经验, KIF和 Jasmine - Cedar到 iOS 的端口运行良好。

但是,我也有很多很好的使用calabash的方法,就像 Frank 一样,由 gherkin 提供支持。

于 2013-11-23T03:51:09.430 回答