其他测试框架 测试开发之路----数据驱动及其变种

孙高飞 · 2016年05月03日 · 最后由 孙高飞 回复于 2016年06月28日 · 298 次阅读

本系列其他文章:
第一部分:测试开发之路 ---- 框架中数据的管理策略
第二部分:测试开发之路 ---- 数据驱动及其变种
第三部分:测试开发之路 ---- 可读性,可维护性,可扩展性
第四部分:测试开发之路 ---- 可读性,可维护性,可扩展性 (续)

  趁着放假开始这个系列的第二个话题,数据驱动。这个应该属于是个做测试的就知道也做过的话题,这里也算老生重谈了。这一篇帖子没有特别大的技术含量。就是对数据驱动的形式做一下讨论。就叙述以下我经历过的数据驱动的形式吧。 因为鄙人是 java 出身的,所以以下例子均为 java+testng 为背景。

最开始的数据驱动:例如 testng 自带的机制

  熟悉 testng 的小伙伴一定已经把 data provider 用烂了。我不细讲了,各位不用 java 的也一定对数据驱动熟的不能再熟了。直接简单介绍下。

@Test(dataProvider = "marNew", dataProviderClass = Dataprovider.class)
    public void testcase(String methodName, Params info) {

  上面的代码就是 testng 最简单的例子了,测试方法想要什么数据,直接写在参数里。然后@Test标签指定用哪个 data provider 就好了。

@DataProvider(name = "marNew")
    public static Iterator<Object[]> TestDataProvider(Method method) throws Exception {

  这个就是 data provider 的接口了。只要用注解定义一下,返回一个迭代器就好了。迭代器里的参数会自动的传递给测试方法的参数列表。不细表了,大家都知道。

改造后的数据驱动:当最原始的这个数据驱动应用的很好的时候,我们发现了一些问题。

  1. 代码里定义这些数据可读性不是很好
  2. 仍然有些代码是重复的,例如定义一个 javaBean,一个 List 等
  3. data provider 散落在测试脚本的各个包里,希望能分层出去到另一个文件里
  4. data provider 在测试的源代码中,而且是以代码形式定义,不会写代码的人想通过定义测试数据来添加 case 成为了不可能

  于是我们就想到了把参数定义在一个 excel 里。于是就变成了下面这样。

  这样就决了很多问题了,例如可读性问题,现在看起来很方便。数据分层出来了,而且最重要的是,我们现在可以有一种模式就是:自动化人员写脚本,业务人员通过数据文件写用例这样效率高多了。但是我们还是有一个问题没有解决----代码重复,我们发现通过 excel 文件搞这事有个最大的问题----无法定义复杂类型的数据。 例如说一个 list,例如说一个对象类型。 我们只能定义 String,int 这种基本数据类型。然后需要在脚本中构建这些对象。 这样就太不爽了,很多重复的代码。而且我们希望脚本里只有测试逻辑,没有构建数据的操作。

继续改造:为了定义复杂类型的参数,我们把 excel 换成 xml

  面向对象的编程语言中,一个复杂类型其实也是个树形结构。所以我们这一次使用本身就是树形结构的 XML 试一下。

<methods methodName="cancel" invokeType="Spring" className="com.bj58.daojia.ordercenter.agent.house.NurseOrderService">
    <params alias="订单不存在" dataFile="cancel.xls">
        <in type="long" name="orderId">123123</in>
        <in type="String" name ="cancelReason">cancelReason</in>
        <in type="Enum" name ="cancelType" path="com.bj58.daojia.ordercenter.enums.CancelOrderReasonEnum">DUPLICATE_ORDER</in>
        <in type="String" name ="operator">sungaofei</in>
        <in type="Enum" name ="operateSource" path="com.bj58.daojia.ordercenter.enums.OperateSourceEnum">BACK</in>
        <out type="Object" name ="OperationResult" path="com.bj58.daojia.ordercenter.dto.support.OperationResult">
            <subP type ="Boolean" name="result">false</subP>

            <subP name="message" type="Map">
                <subP name="key" type="Map">
                    <subP name="key" type="Integer">2</subP>
                </subP>
                <subP name="value" type="Map">
                    <subP name="value" type="String">订单不存在</subP>
                </subP>
            </subP>
        </out>
    </params>

    <params alias="已取消的订单无法再次取消">
        <in type="long" name="orderId">47077048011000</in>
        <in type="String" name ="cancelReason">cancelReason</in>
        <in type="Enum" name ="cancelType" path="com.bj58.daojia.ordercenter.enums.CancelOrderReasonEnum">DUPLICATE_ORDER</in>
        <in type="String" name ="operator">sungaofei</in>
        <in type="Enum" name ="operateSource" path="com.bj58.daojia.ordercenter.enums.OperateSourceEnum">BACK</in>
        <out type="Object" name ="OperationResult" path="com.bj58.daojia.ordercenter.dto.support.OperationResult">
            <subP type ="Boolean" name="result">false</subP>

            <subP name="message" type="Map">
                <subP name="key" type="Map">
                    <subP name="key" type="Integer">7</subP>
                </subP>
                <subP name="value" type="Map">
                    <subP name="value" type="String">已取消的订单无法再次取消</subP>
                </subP>
            </subP>
        </out>
    </params>

  OK,这次爽多了可以看到上面的 xml 文件中,我们可以定义Object类型,其实就是 javaBean 啦,通过递归算法我们可以定义无线复杂的数据类型。具体实现可以参考我这篇帖子NO_CODE 接口自动化测试框架. 但是我们突然又发现一个问题,我们这个机制很多都是通过 java 反射机制做的类型转换算法。既然我们都可以自动化类型转换了,那我们也可以让框架帮我们做更多的事。

接着改造:关键字驱动

  江湖传闻,关键字驱动是数据驱动进化而来。我是不知道是不是这样,当初定义这俩货的时候,我还不知道在哪呢。不过在我这,确实是这样的。接上面的例子,我们发现利用 java 反射,框架已经可以帮我们做参数类型的自动转型了。既然反射这么强大,那让它帮我们多做点事情吧。

<methods methodName="cancel" invokeType="Spring" className="com.bj58.daojia.ordercenter.agent.house.NurseOrderService">

  我们加几个属性,把方法名和类的路径告诉框架。注:invokeType中的Spring的意思是获取对象的方式。我们清一色用 spring 传递 dubbo 协议,所以写的是 Spring(HTTP 协议的也一样,就是不传类路径,传 URL 了)。OK 这样框架就可能帮我们调用接口了。我们接着来。

<params alias="订单不存在" dataFile="cancel.xls">

  记得我们上一节说的注册式数据管理么?这个dataFile就是像框架注册数据了。

<out type="Object" name ="OperationResult" path="com.bj58.daojia.ordercenter.dto.support.OperationResult">
            <subP type ="Boolean" name="result">false</subP>

            <subP name="message" type="Map">
                <subP name="key" type="Map">
                    <subP name="key" type="Integer">2</subP>
                </subP>
                <subP name="value" type="Map">
                    <subP name="value" type="String">订单不存在</subP>
                </subP>
            </subP>
        </out>

  out标签,验证返回值。框架根据接口返回值与 xml 定义的预期的结果做比较。依然支持复杂数据类型。

<database database_name="dbwww58com_emclottery">
            <table table_name="t_app_nurse_order" where="order_id=1234567890988">
                    <row>
                        <field field_name="order_id">1234567890988</field>
                        <field field_name="nanny_type">1</field>

  database标签,帮助拼 sql 验证数据库。

改造一切你想要的:通过定义 XML 标签,我们增加 skip 用例的功能,我们可以规定什么验证什么不验证。等等

  自动化测试的 4 个步骤,数据准备,调用被测功能,验证结果,销毁数据。我们发现框架都帮我们做了。OK 了,那还写个毛线的脚本。我们就关键字驱动了,没有脚本,xml 文件就是脚本。不论 http 还是 rpc 协议我们全能让业务人员做了。

  OK 至此我这篇也写完了。。。虽然我不情愿说,但是老婆又催我去睡觉了。。有关关键字驱动的实现看我第一篇帖子NO_CODE 接口自动化测试框架

如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
共收到 11 条回复 时间 点赞

mark

—— 来自 TesterHome 官方 安卓客户端

速度 9 质量 9

#2 楼 @nickli 额。这个速度9,质量9是什么意思?

@ycwdaaaa 就是非常的意思!O(∩_∩) O

真棒,有想法的年轻人

目前公司很多接口都是 rpc 协议的,rpc 协议是怎么调用 ?求教

#6 楼 @839999304a RPC 其实就是一个调用方式么。关键就是你怎么获取协议接口。所以基本上是开发怎么调用,你就怎么调用。我们之前用的 spring 配置的 dubbo 协议接口。所以直接用 spring 获取协议对象,java 反射调用接口。

数据定义在 xml 里面,读取出来的时候都是 String 类型
但为什么一定得转型成实际的数据类型呢,接口的入参全部由读取出来字符串拼接组成会有什么问题吗,本来也不需要传数据类型的吧?
这里不是很明白,求解惑。。

#8 楼 @snowmaster java 是强类型语言的。不转不行。它不像 python 这种弱类型语言,不管什么都往参数里放就行

#9 楼 @ycwdaaaa 我去网上找找看些实例,现在感觉还是不是很理解,之后要是还是没弄懂再来求解_^

挺棒的,我还停留在 excel 管理测试 case 阶段。目前没有复杂的数据类型需要拼接,少数比较复杂的输入数据,是通过修改模板数据文件来实现的。接下来我也试试这么做,看看能不能提高效率。

孙高飞 [该话题已被删除] 中提及了此贴 06月28日 10:51
孙高飞 [该话题已被删除] 中提及了此贴 06月28日 10:51
孙高飞 [该话题已被删除] 中提及了此贴 06月28日 10:51
孙高飞 测试开发之路--持续集成 中提及了此贴 11月23日 00:52
孙高飞 测试开发之路----框架中数据的管理策略 中提及了此贴 12月02日 02:47
孙高飞 测试开发之路----概要 中提及了此贴 03月13日 05:13
孙高飞 测试开发之路----数据驱动及其变种 中提及了此贴 12月21日 01:53
需要 登录 后方可回复, 如果你还没有账号请点击这里 注册