如果已经读了上一篇文章《深入探究数据测试之一:数据测试概论》,相信大家已经对数据测试有了更加详细的理解,也有可能找到了现实测试中的具体例子。
我们第一步要做的事情,是封装你的无关操作。而这一步的基础,就是设计自动化测试用例。
什么是无关操作?无关操作是和期望操作正好相反的一个概念。
测试人员的期望操作,就是要写在自动化测试用例里面的代码的最理想状况。所以无关操作就是你不想写在自动化测试用例里面的代码。拿下面这个测试来举例:
第一个例子:假设我们要测试一个hive脚本:(如果你熟悉hive,那么你应该可以看出我代码所指的事情,如果你没有用过hive,那么就把hive看成是一种sql语言就好了)
//下面一段是期望操作
$input = "zhangsan|28|8000\n";//准备输入数据,第一行
$input.= "lisi|30|10000\n"; //准备输入数据,第二行
$input.= "wangwu|40|20000\n"; //准备输入数据,第三行
//下面一段是无关操作
file_put_contents('/tmp/staff.table', $input); //将输入的数据写入到文件
exec('hadoop fs -mkdir /table_path/staff/'); //在hadoop上建立目标文件的目录路径
exec('hive -e "create external table stuff(name string, age bigint, salary bigint) partitioned by (dp string) location \'/table_path/staff/dp=etao\';"'); //建立hive的建表语句
exec('hadoop fs -put /tmp/staff.table/table_path/staff/dp=etao/part-000'); //将我们的数据文件放到hdfs上
exec('hive -e "alter table staff add if not exists partition ( dp=etao ) location \’/table_path/staff/dp=etao\’");//调用alter table为我们的表增加一个分区,地址是刚刚上传的文件(hive的专有特性)
exec('underTestShell.sh'); //执行被测试脚本
exec('hadoop fs -cat /tmp/result.table/table_path/result/dp=etao/part-000 > /tmp/result.tmp'); //将结果表的结果下载下来
$result = file_get_contents('/tmp/result.tmp); //结果表读取到内存中
//下面一段是期望操作
assert::equal($result, "38000");
?>
上面的测试代码是我们最开始很可能写出来的代码,这样的代码面向过程,每一步都清楚的指明了他要干什么,非常直观,因为他就是我们简单的命令行命令的叠加。我相信交给别的测试人员,虽然看起来头大,但是当他了解一个hive的测试过程之后,就容易理解这样的代码了。
但是这个测试用例会在后期的维护中给测试人员带来巨大的麻烦,原因就在于,这个测试用例的无关操作太多,甚至多过了测试人员真正关心的数据准备的代码。(无关操作还是期望操作,我已经在注释中给出)这么做的坏处很多,最主要的就是以下三点:
1. 测试人员无法集中注意力在自己应该集中注意力的数据准备上,导致效率下降,这里效率下降的原因不仅仅是花时间关注无需关注的事情上,而且在不同的任务之间来回切换注意力,也会耗费大量的时间。
2. 测试代码过于冗余,导致代码无法维护。设想一下,当你拥有3个这样的测试用例的时候,如果你想修改一下其中hadoop地址的路径,这样的代码就需要将这个变化进行3次,如果有300个这样的测试用例呢?自动化测试用例的易维护性是在日常中点点滴滴进行的。
3. 不熟悉hive代码的人同学,编写这样的测试用例几乎无法独自完成。比如说你有一个同伴,对数据类型的验证和测试方法很有成就,但是对hive一窍不通,那么他需要一个人手帮他熟悉hive的流程。这导致测试人员在同是数据测试的情况下跨项目流动困难。
下面是我们期望的封装过无关操作之后的测试用例:
//下面一段是期望操作
$input = "zhangsan|28|8000\n";
$input.= "lisi|30|10000\n";
$input.= "wangwu|40|20000\n";
$underTest = new underTest();
$result = $underTest->run();
//下面一段是期望操作
assert::equal($result['result'], "38000");
?>
从上面我们可以看出来,所有的测试的过程都被一个run函数所取代。如果这么做,测试人员可以将自己的注意力放在$input的编写和$result的预期结果,也对开发的修改测试也可以方便的修改所有的东西。
这个概念也可以平移到其他自动化测试中去:
UI的自动化测试,测试人员主要关心的焦点在于业务逻辑是否跑通,而不是某一个页面元素如何定位上,UI自动测试要尽量把页面元素抽取出来,定义成面向对象的类,或者使用关键字驱动来开发。
单元测试的时候,主要需要关注的是当前开发代码的运行状况,所以会使用Mock将目前的模块所依赖的其他模块模拟出来。
这些都是封装无关操作的例子。
回顾一下,这一个小节我主要想说的是,自动化测试不是简单的把手动步骤写入脚本这么简单,而是一个和开发过程一样需要设计的过程。所以首先要想明白的事情是,你未来的几百个甚至上千个的自动化测试用例长什么样子,如何可以让这些用例最简单,最可以自描述。
下一篇文章,我们将会讲如何封装这样的无关操作。
另外,本章的自动化测试用例的设计,并不是我们认为的最完美的自动化测试用例的样本,之后我们会有其他的更新。