使用解析器组合器在Swift中进行高级UI测试
我一直喜欢Cucumber风格在iOS上进行UI测试。 但是我真的不喜欢在计算机上管理15000个红宝石版本,更不用说确保团队运行相同的版本,gem(我在看着你calabash-ios )等等。
我也希望它简单:只需读取代码,然后按“运行测试”即可。
因此,我决定在Swift中编写一个简单的Gherkin解析器。 我希望测试的结构如下:
方案:导入按钮起作用
鉴于我在主屏幕上
当我点击“导入”时
然后打开导入屏幕
func I_am_on_the_home_screen(){
...
}
func the_import_screen_opens(){
...
}
该方案位于最上方,执行功能位于其下方。 请注意,没有“ I_tap_Import”功能,我希望tap和type具有足够的通用性,以使我的框架能够理解它。
解析中
POC版本基本上是在进行字符串比较和模式匹配,但是您可以想象,这不是非常有效和灵活。
对于“真实”版本,我使用了解析器组合器。 观看Swift讨论解析数学表达式的视频时,解析器组合器引起了我极大的兴趣。
联机有一些解析器组合器的介绍,因此在这里我不会做太多详细介绍,但是它的大致工作原理是这样的:基本解析器(例如,字符)使用…悬念…组合器组合在一起! 创建更复杂的解析器( 字符串解析器= n × 字符解析器),并且可以应用一些逻辑来创建语法(字符串是直到行尾的每个字符)
我花了几天的时间来“获取”它,但是一旦我将所有内容放到白板上,一切都变得有意义。
简而言之,它解析场景时忽略了前导和尾随空格。
当有一个“ tap ”关键字时,它将使用加引号的字符串作为参数来调用预建的tap函数(例如, Given I tap on "continue"
调用app.buttons["continue"].tap()
当有’ type ‘关键字时,它将使用加引号的字符串作为参数来调用预构建类型函数(例如, Given I type "hello" in field "id"
调用app.textFields["id"].typeText("hello")
))
如果没有关键字,它将调用带下划线的分隔线命名函数(例如, Then I land on a page
调用I_land_on_a_page()
函数)
那可以让我做这样的事情:
运行它
由于它是纯快速的,并且全部嵌入测试中,因此我只需要运行它,然后让测试框架和解析器完成工作即可。
除了明显的可读性优势和BDD样式测试之外,它还使我的UITests以模块化的方式结构化,从而使我可以重用许多代码。
当然,我已经将所有这些都放入了github中,因此可以随时使用它:https://gist.github.com/ijuhoor/9062f04ff3dff3ade53de77a7c4a2451