You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
12 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 15 | 过不了的坎聊聊GUI自动化过程中的测试数据
在前面几篇文章中我从页面操作的角度介绍了GUI自动化测试讲解了页面对象模型和业务流程封装今天我将从测试数据的角度再来谈谈GUI自动化测试。
为了顺利进行GUI测试往往需要准备测试数据来配合测试的进行如果不采用事先数据准备的方式测试效率将会大打折扣而且还会引入大量不必要的依赖关系。
以“用户登录”功能的测试为例如果你的目的仅仅是测试用户是否可以正常登录比较理想的方式是这个用户已经存在于被测系统中了或者你可以通过很方便的方式在测试用例中生成这个用户。否则难道你要为了测试用户登录功能而以GUI的方式当场注册一个新用户吗显然这是不可取的。
其实从这里你就可以看出测试数据准备是实现测试用例解耦的重要手段你完全不必为了测试GUI用户登录功能而去执行用户注册只要你能够有方法快速创建出这个登录用户就可以了。
在正式讨论测试数据的创建方法前我先来分析一下GUI测试中两种常见的数据类型
* 第一大类是测试输入数据也就是GUI测试过程中通过界面输入的数据。比如“用户登录”测试中输入的用户名和密码就就属于这一类数据再比如数据驱动测试中的测试数据也是指这一类。
* 第二大类是为了完成GUI测试而需要准备的测试数据。比如“用户登录”测试中我们需要事先准备好用户账户以便进行用户的登录测试。今天我分享的测试数据创建的方法也都是围着这一部分的数据展开的。
那么接下来,我就带你一起去看看创建测试数据的方法都有哪些,以及它们各自的优缺点,和适用场景。
从创建的技术手段上来讲,创建测试数据的方法主要分为三种:
1. API调用
2. 数据库操作;
3. 综合运用API调用和数据库操作。
从创建的时机来讲,创建测试数据的方法主要分为两种:
1. 测试用例执行过程中实时创建测试数据我们通常称这种方式为On-the-fly。
2. 测试用例执行前事先创建好“开箱即用”的测试数据我们通常称这种方式为Out-of-box。
**在实际项目中对于创建数据的技术手段而言最佳的选择是利用API来创建数据只有当API不能满足数据创建的需求时才会使用数据库操作的手段。**
实际上往往很多测试数据的创建是基于API和数据库操作两者的结合来完成即先通过API创建基本的数据然后调用数据库操作来修改数据以达到对测试数据的特定要求。
**而对于创建数据的时机在实际项目中往往是On-the-fly和Out-of-box结合在一起使用。**
对于相对稳定的测试数据比如商品类型、图书类型等往往采用Out-of-box的方式以提高效率而对于那些只能一次性使用的测试数据比如商品、订单、优惠券等往往采用On-the-fly的方式以保证不存在脏数据问题。
接下来,我就先从测试数据创建的技术手段开始今天的分享吧。
## 基于API调用创建测试数据
先看一个电商网站“新用户注册”的例子当用户通过GUI界面完成新用户注册信息填写后向系统后台递交表单系统后台就会调用createUser的API完成用户的创建。
而互联网产品尤其是现在大量采用微服务架构的网站这个API往往以Web Service的形式暴露接口。那么在这种架构下你完全可以直接调用这个API来创建新用户而无须再向后台递交表单。
由于API通常都有安全相关的token机制来保护所以实际项目中通常会把对这些API的调用以代码的形式封装为测试数据工具Test Data Utility
这种方式最大的好处就是测试数据的准确性直接由产品API保证缺点是并不是所有的测试数据都有相关的API来支持。
另外对需要大量创建数据的测试来说基于API调用方式的执行效率即使采用了并发机制也不会十分理想。为了解决执行效率的问题就有了基于数据库操作的测试数据创建手段。
## 基于数据库操作创建测试数据
实际项目中并不是所有的数据都可以通过API的方式实现创建和修改很多数据的创建和修改直接在产品代码内完成而且并没有对外暴露供测试使用的接口。
那么,这种情况下,你就需要通过直接操作数据库的方式来产生测试数据。
同样地我们可以把创建和修改数据的相关SQL语句封装成测试数据工具以方便测试用例的使用。但是如果你正尝试在实际项目中运用这个方法不可避免地会遇到如何才能找到正确的SQL语句来创建和修改数据的问题。
因为,创建或修改一条测试数据往往会涉及很多业务表,任何的遗漏都会造成测试数据的不准确,从而导致有些测试因为数据问题而无法进行。
那么,现在我就提供两个思路来帮你解决这个问题:
1. 手工方式。查阅设计文档和产品代码找到相关的SQL语句集合。或者直接找开发人员索要相关的SQL语句集合。
2. 自动方式。在测试环境中先在只有一个活跃用户的情况下通过GUI界面操作完成数据的创建、修改然后利用数据库监控工具获取这段时间内所有的业务表修改记录以此为依据开发SQL语句集。
需要注意的是,这两种思路的前提都是,假定产品功能正确,否则就会出现“一错到底”的尴尬局面。
基于数据库操作创建测试数据的最大好处是可以创建和修改API不支持的测试数据并且由于是直接数据库操作执行效率会远远高于API调用方法。
但是数据库操作这种方式的缺点也显而易见数据库表操作的任何变更都必须同步更新测试数据工具中的SQL语句。
但很不幸的是在实际项目中经常出现因为SQL语句更新不及时而导致测试数据错误的问题而且这里的数据不准确往往只是局部错误因此这类问题往往比较隐蔽只有在特定的测试场景下才会暴露。
所以在实际工程项目中需要引入测试数据工具的版本管理并通过开发流程来保证SQL的变更能够及时通知到测试数据工具团队。
## 综合运用API调用和数据库操作创建测试数据
你如果已经理解了基于API调用和基于数据库操作创建测试数据这两类方法那么综合运用这两类方法就是使得测试数据工具能够提供更多种类的业务测试数据。
具体来讲当你要创建一种特定的测试数据时你发现没有直接API支持但是可以通过API先创建一个基本的数据然后再通过修改数据库的方式来更新这个数据以此来达到创建特定测试数据的要求。
比如你需要创建一个已经绑定了信用卡的新用户如果创建新用户有直接的API而绑定信用卡需要操作数据库那这种情况下就需要综合运用这两种方式完成测试数据工具的开发。
## 实时创建数据On-the-fly
**GUI测试脚本中在开始执行界面操作前我们往往会通过调用测试数据工具实时创建测试数据也就是On-the-fly方式。**
这种方式不依赖被测试系统中的任何原有数据,也不会对原有数据产生影响,可以很好地从数据层面隔离测试用例,让测试用例实现“自包含”。
从理论上讲On-the-fly是很好的方法但在实际测试项目中却并不是那么回事儿往往会存在三个问题
1. **在用例执行过程中实时创建数据,导致测试的执行时间比较长。** 我曾经粗略统计过一个大型Web GUI自动化测试项目的执行时间将近30%的时间都花在了测试数据的准备上。
2. **业务数据的连带关系,导致测试数据的创建效率非常低。** 比如,你需要创建一个订单数据,而这个订单必然会绑定买家和卖家,以及订单商品信息。
如果完全基于On-the-fly模式你就需要先实时创建买家和卖家这两个用户然后再创建订单中的商品最后才是创建这个订单本身。
显然,这样的测试数据创建方式虽然是“自包含”的,但创建效率非常低,会使得测试用例执行时间变得更长,而这恰恰与互联网产品的测试策略产生冲突。
3. **更糟糕的情况是,实时创建测试数据的方式对测试环境的依赖性很强。** 比如你要测试用户登录功能基于On-the-fly方式你就应该先调用测试数据工具实时创建一个用户然后再用这个用户完成登录测试。
这时创建用户的API由于各种原因处于不可用的状态这种情况在采用微服务架构的系统中很常见那么这时就会因为无法创建用户而无法完成用户登录测试。
基于这三种常见问题实际项目中还会引入Out-of-box方式即在执行测试用例前预先创建好测试数据准备测试数据。
## 事先创建测试数据Out-of-box
**Out-of-box的含义是开箱即用也就是说已经在被测系统中预先创建好了充足的、典型的测试数据。这些数据通常是在搭建测试环境时通过数据库脚本“预埋”在系统中的后续的测试用例可以直接使用。**
Out-of-box的方式有效解决了On-the-fly的很多问题但是这种方法的缺点也很明显主要体现在以下三个方面
1. **测试用例中需要硬编码hardcode测试数据额外引入了测试数据和用例之间的依赖。**
2. **只能被一次性使用的测试数据不适合Out-of-box的方式。** 测试用例往往会需要修改测试数据,而且有些测试数据只能被一次性使用。比如,一个商品被买下一次后就不能再用了;再比如,优惠券在一个订单中被使用后,就失效了,等等。所以如果没有很好的全局测试数据管理,很容易因为测试数据失效而造成测试失败。
3. **“预埋”的测试数据的可靠性远不如实时创建的数据。** 在测试用例执行过程中,经常会出现测试数据被修改的情况。比如,手动测试,或者是自动化测试用例的调试等情况。
## On-the-fly和Out-of-box的互补
基于On-the-fly和Out-of-box的优缺点和互补性在实际的大型测试项目中我们往往会采用两者相结合的方式从测试数据本身的特点入手选取不同的测试数据创建方式。
针对应该选择什么时机创建测试数据,结合多年的实践经验,我为你总结了以下三点:
1. 对于相对稳定、很少有修改的数据建议采用Out-of-box的方式比如商品类目、厂商品牌、部分标准的卖家和买家账号等。
2. 对于一次性使用、经常需要修改、状态经常变化的数据建议使用On-the-fly的方式。
3. 用On-the-fly方式创建测试数据时上游数据的创建可以采用Out-of-box方式以提高测试数据创建的效率。以订单数据为例订单的创建可以采用On-the-fly方式而与订单相关联的卖家、买家和商品信息可以使用Out-of-box方式创建。
其实,为了更好地解决测试数据本身组合的复杂性和多样性,充分发挥测试数据工具的威力,还有很多大型企业的最佳实践值得讨论,在本专栏后面的测试数据章节,我会再为你详细介绍。
## 总结
今天我从创建测试数据的技术手段和时机两个方面介绍了GUI测试数据的准备。
在实际测试项目中往往需要综合运用API调用和数据库操作来创建测试数据并且会根据测试数据自身的特点分而治之地采用On-the-fly和Out-of-box的方式以寻求数据稳定性和数据准备效率之间的最佳平衡。
## 思考题
你所在的公司是如何准备GUI测试的测试数据的遇到了哪些问题对应的有哪些解决方案呢
欢迎你给我留言。