Functional Testing in iOS

什么是Function Testing(摘自wikipedia

Functional testing is a quality assurance (QA) process and a type of black-box testing that bases its test cases on the specifications of the software component under test. Functions are tested by feeding them input and examining the output, and internal program structure is rarely considered (not like in white-box testing). Functional testing usually describes what the system does.

为什么需要Functional Testing

在讨论这个问题前先来一些对比:

  1. Functional Tesing vs Unit Testing Unit Testing关注点在于单独的代码片段,可信度较高且易扩展,是从开发者的视角来编写的。相对Functional Testing来说更快,你可以很快地为某段代码编写测试,执行速度快,能够更快的定位bug。但是它并不关心产品的业务逻辑,所以当单元测试通过并不能保证你的产品能够满足业务需求。
  2. Functional Testing vs Integration Testing Integration Testing主要用于不同module、system等之间的集成测试。Unit Testing用于保证每个代码片段能够独立地正确工作,但是并不能保证他们集成在一起能够正确工作。你需要集成测试将不同的功能模块集成在一起来进行测试。但是相对Functional Testing来说它还是不能保证某个feature能够得到预期的结果。

下面的Test Pyramid摘自Martin Fowler的 文章,越高层次产生的用户价值会更高且更慢,越低层次的产生的价值更低且更快,你所写的任何一行单元测试代码对于你的用户来说都是不可见的,他能感知到的只能通过UI来体现。可以看出我们需要很多的单元测试来保证我们的代码质量,这对开发人员来说是有巨大价值的,它能够帮开发人员快速发现且定位问题。

Test Pyramid

Funtional testing 属于UI测试,UI测试包含行为和外观。Functional testing从用户行为这个维度来保证了代码的质量。比如我需要对用户登录进行测试,我需要测试的点就可能涵盖用户点击了登录,需要看到界面上有相应的提示,成功之后需要到达主界面等。

BDD 与 Functional Testing

在敏捷实践中我们通过BDD(Behavior-driven development)来帮助我们完成Functional testing。BDD鼓励软件项目中的开发者、QA和非技术人员或商业参与者之间的协作,让其能够在一个共同的基础上达成共识。

BDD的框架很多,下面简单的罗列了一下:

框架

语言

Cucumber

Ruby

JBehave

Java

RBehave

Ruby

Specflow

C#

它们基本上都是基于Gherkin作为DSL在不同语言上的实现,让我们可以用自然语言去书写我们的代码。

用BDD来为某个feature书写测试通常包含以下几个部分:

  • 一个简单的Title
  • 对测试场景进行简单描述
  • 验收步骤以及预期行为的描述

在对验收步骤进行描述的时候通常会用到这样的格式"Given ... When ... Then ",各自的含义如下

  1. Given: 测试的前置条件
  2. When: 指定用户的行为
  3. Then: 验证结果

因此,如果用这样的格式去描述用户登录的场景就大概应该是:

  1. Given 用户打开登录界面
  2. When 用户填写账号和密码后点击登录按钮
  3. Then 用户登录成功来到主界面。

当然除了这几个关键字,可能你还会接触到And、But、Or等,使用它们可以增加代码的可读性。 通过自然语言的描述,业务专家、QA或者其他没有技术背景的人也可以很明确地明白这个测试是在干什么。

针对于iOS开发,苹果本身的XCTest不能很好的支持我们写Functional testing。它基于assert来完成测试,而很多时候assert所表达的含义也很难理解,同时它相对来说也比较难mock。所以我们可能还需要一些工具来方便我们写Functional Testing。

下面简单的列了一些iOS开发中能够用来UI Testing的框架:

框架

语言

支持平台

Calabash

Gherkin \ Ruby

iOS \ Android

EarlGrey

OC \ Swift

iOS

Frank

Gherkin \ Ruby

iOS \ MAC

KIF

OC \ Swift

iOS

UI Test

OC \ Swift

iOS

Calabash和Frank都是基于Cucumber,但是Calabash有着更丰富的特性,比如更丰富的内建步骤、更多的手势支持等,支持的平台也更加丰富,使用范围更广。

EarlyGrey是google推出的,内建同步机制,测试会在与UI进行交互前自动等待动画、网络请求等事件,当然它还是允许你手动处理同步。它会确保执行动作前,UI处于稳定的状态。EarlGrey基于XCTest,因此在Xcode中你可以很容易的建立一个测试用例类。当然在我写下这篇文章的时候它还存在一些问题,比如不支持3D Touch,不能和Address Sanitizer一起工作等,完整的列表在这里

具体使用哪种工具大家可以根据自己项目的实际情况来考虑,我目前的项目中使用的是Calabash。

使用Calabash-iOS写Functional Testing

要想在你的iOS工程中使用Calabash你需要一定的步骤安装依赖包以及配置工程,可以移步到Calabash查看具体的步骤。

一切都设置好了之后,工程目录下会多一个叫features的目录,顾名思义里面会包含你需要测试的feature。 比如我需要对登录进行测试。我在目录下新建一个叫做login.feature的文件,然后开始描述测试的用户场景:

Feature: User login flow

  Scenario: User can login with correct account number and password
    Given I can open the login page
    When I type "myname" into the account number input field
    And I type "mypassword" into the password input field
    And I click then login button
    Then I can login successful and see home page

另外,Calabash内建了很多的steps,但是不一定额能够完全满足你的需求,你可能还需要一些自定义的步骤,自定义的步骤都放在step_definitions里面。 比如我需要定义输入账号这个步骤:

When(/^I type "(.*?)" i into the account number input field$/) do |value|
  @login_page.touch_account_field
  keyboard_enter_text value
end

当描述好feature,并且定义好了步骤之后,这样一个用例测试就完成了,接下来你可以通过cucumber命令来执行它。

为了方便调试,Calabash还提供一个的命令行工具,通过命令calabash-ios console来使用。 比如你要查找出当前成为焦点的输入框,然后让它停止输入状态,你可以像下面这个样子

query "textField isFirstResponder:1", :resignFirstResponder

在这里支持的命令和在step定义里支持的命令是一样的,所以在你不确定的时候,可以通过命令行工具快速的检验一下。

最后

在CI中加入UI的自动化测试,可以的降低时间成本提升生产力。但是这并不是银弹,还得结合自身项目,用多少,怎么用都得仔细去考虑。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏林德熙的博客

如何使用 C# 爬虫获得专栏博客更新排行

昨天,梦姐问我们,她存在一个任务,找到 关注数排行100 和 浏览量排行100 的专栏博客,在2017年还有更新的专栏。 梦姐说他要出去一趟,M大神在吃饭,于是...

14610
来自专栏Java技术栈

12 个非常有趣的 Linux 命令!

-a An accident seems to happen. You'll feel pity for people who cry for help.

19740
来自专栏FreeBuf

逆向工厂(一):从hello world开始

* 本文原创作者:追影人,本文属FreeBuf原创奖励计划,未经许可禁止转载 前言 从本篇起,逆向工厂带大家从程序起源讲起,领略计算机程序逆向技术,了解程序的运...

48880
来自专栏极客生活

真正好用的python库

这个库是我安装完python环境后第一个安装的库,装上这个库再开始写代码才有底气,作者 Kenneth Reitz 是公认python领域代码写的最好的两个人之...

16330
来自专栏xdecode

后端架构师技术图谱

转自: GitHub/architect-awesome , 大体结构如下(更新时间: 2018-06-22)

1.7K60
来自专栏微信公众号:Java团长

不可多得的后端架构师技术图谱!内附参考资料!

由于知识点众多,特整理在GitHub上,微信外链限制,无法在文本中直接加上超链接,有需要的欢迎Start/Fork,地址如下:

16920
来自专栏陈本布衣

Spring基础篇——DI/IOC和AOP原理初识

前言   作为从事java开发的码农,Spring的重要性不言而喻,你可能每天都在和Spring框架打交道。Spring恰如其名的,给java应用程序的开发带了...

26270
来自专栏Albert陈凯

2018-08-05 没有测试用例的代码,根本不应该跑在服务器上

在实际测试中,一个单元可以小到一个方法,也可以大到包含多个类。从定义上讲,单元测试和集成测试是有严格的区分的,但是在实际开发中它们可能并没有那么严格的界限。如果...

26150
来自专栏玉树芝兰

如何在Jupyter Notebook中使用Python虚拟环境?

如何在使用Jupyter Notebook时,解决Python虚拟环境间的切换问题?本文一步步帮你拆解。希望你能够避免踩坑的痛苦,把更多的时间花在愉快的编程上。

40030
来自专栏mwangblog

git,版本控制界的魔术师(1/18/2018)

11420

扫码关注云+社区

领取腾讯云代金券