Lego- 美团接口自动化测试实战(详细解析)

文章介绍了Lego接口自动化测试平台的构成,包括脚本设计、用例设计思路,强调了通用性、校验、健壮性和易用性。Lego通过数据驱动和参数化提高测试用例的灵活性和维护性,使用前后置动作增强用例的健壮性,通过ReportNG生成美观的测试报告。此外,文章还讨论了如何通过网站功能进行日常维护和用例管理,以及如何通过代码覆盖率和失败原因跟踪优化测试用例。

目录:导读

 

一、概述

1.1 接口自动化概述

1.2 提高 ROI

1.3 Lego 的组成

二、脚本设计

2.1 Lego 的做法

2.2 测试脚本

2.3 配置文件

三、用例设计

3.1 一些思考

3.2 Lego 接口自动化测试用例

3.3 参数化

3.4 前后置动作

3.5 执行各部分

四、网站功能

4.1 站点开发

4.2 整体组成

4.3 使用-日常维护

4.4 用例编辑

4.5 在线调试

4.6 用例生成工具

4.7 执行结果分析

4.8 失败原因跟踪

4.9 代码覆盖率分析

4.10 用例优化方向

4.11 收集反馈/学习

五、小结

结语


一、概述

1.1 接口自动化概述

众所周知,接口自动化测试有着如下特点:

  • 低投入,高产出。

  • 比较容易实现自动化。

  • 和 UI 自动化测试相比更加稳定。

如何做好一个接口自动化测试项目呢?

我认为,一个“好的”自动化测试项目,需要从 “时间”、“人力”、“收益” 这三个方面出发,做好“取舍”。

不能由于被测系统发生一些变更,就导致花费了几个小时的自动化脚本无法执行。同时,我们需要看到“收益”,不能为了总想看到 100%的成功,而少做或者不做校验,但是校验多了维护成本一定会增多,可能每天都需要进行大量的维护。

所以做好这三个方面的平衡并不容易,经常能看到做自动化的同学,做到最后就本末倒置了。

1.2 提高 ROI

想要提高 ROI(Return On Investment,投资回报率),我们必须从两方面入手:

  1. 减少投入成本。

  2. 增加使用率。

针对“减少投入成本”

我们需要做到:

  • 减少工具开发的成本。 尽可能的减少开发工具的时间、工具维护的时间,尽可能使用公司已有的,或是业界成熟的工具或组件。

  • 减少用例录入成本。 简化测试用例录入的成本,尽可能多的提示,如果可以,开发一些批量生成测试用例的工具。

  • 减少用例维护成本。 减少用例维护成本,尽量只用在页面上做简单的输入即可完成维护动作,而不是进行大量的代码操作。

  • 减少用例优化成本。 当团队做用例优化时,可以通过一些统计数据,进行有针对性、有目的性的用例优化。

针对“增加使用率”

我们需要做到:

  • 手工也能用。 不只是进行接口自动化测试,也可以完全用在手工测试上。

  • 人人能用。 每一个需要使用测试的人,包括一些非技术人员都可以使用。

  • 当工具用。 将一些接口用例当成工具使用,比如“生成订单”工具,“查找表单数据”工具。

  • 每天测试。 进行每日构建测试。

  • 开发的在构建之后也能触发测试。 开发将被测系统构建后,能自动触发接口自动化测试脚本,进行测试。

所以,我这边开发了 Lego 接口测试平台,来实现我对自动测试想法的一些实践。先简单浏览一下网站,了解一下大概是个什么样的工具。

首页

用例维护页面

自动化用例列表

在线执行结果

用例数量统计

1.3 Lego 的组成

Lego 接口测试解决方案是由两部分组成的,一个就是刚刚看到的“网站”,另一个部分就是“脚本”。

下面就开始进行“脚本设计”部分的介绍。

二、脚本设计

2.1 Lego 的做法

Lego 接口自动化测试脚本部分,使用很常见的 Jenkins+TestNG 的结构。

Jenkins+TestNG 的结构

相信看到这样的模型并不陌生,因为很多的测试都是这样的组成方式。

将自动化测试用例存储至 MySQL 数据库中,做成比较常见的 “数据驱动” 做法。

很多团队也是使用这样的结构来进行接口自动化,沿用的话,那在以后的“推广”中,学习和迁移成本低都会比较低。

2.2 测试脚本

首先来简单看一下目前的脚本代码:

public class TestPigeon {
    String sql;
    int team_id = -1;

    @Parameters({"sql", "team_id"})
    @BeforeClass()
    public void beforeClass(String sql, int team_id) {
        this.sql = sql;
        this.team_id = team_id;
        ResultRecorder.cleanInfo();
    }

    /**
     * XML中的SQL决定了执行什么用例, 执行多少条用例, SQL的搜索结果为需要测试的测试用例
     */
    @DataProvider(name = "testData")
    private Iterator<Object[]> getData() throws SQLException, ClassNotFoundException {
        return new DataProvider_forDB(TestConfig.DB_IP, TestConfig.DB_PORT, 
            TestConfig.DB_BASE_NAME,TestConfig.DB_USERNAME, TestConfig.DB_PASSWORD, sql);
    }

    @Test(dataProvider = "testData")
    public void test(Map<String, String> data) {
        new ExecPigeonTest().execTestCase(data, false);
    }

    @AfterMethod
    public void afterMethod(ITestResult result, Object[] objs) {...}

    @AfterClass
    public void consoleLog() {...}
}

复制代码

测试脚本结构

有一种做法我一直不提倡,就是把测试用例直接写在 Java 文件中。这样做会带来很多问题:修改测试用例需要改动大量的代码;代码也不便于交接给其他同学,因为每个人都有自己的编码风格和用例设计风格,这样交接,最后都会变成由下一个同学全部推翻重写一遍;如果测试平台更换,无法做用例数据的迁移,只能手动的一条条重新输入。

所以“测试数据”与“脚本”分离是非常有必要的。

网上很多的范例是使用的 Excel 进行的数据驱动,我这里为什么改用 MySQL 而不使用 Excel 了呢?

在公司,我们的脚本和代码都是提交至公司的 Git 代码仓库,如果使用 Excel……很显然不方便日常经常修改测试用例的情况。使用 MySQL 数据库就没有这样的烦恼了,由于数据与脚本的分离,只需对数据进行修改即可,脚本每次会在数据库中读取最新的用例数据进行测试。同时,还可以防止一些操作代码时的误操作。

这里再附上一段我自己写的DataProvider_forDB方法,方便其他同学使用在自己的脚本上:

import java.sql.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * 数据源 数据库
 *
 * @author yongda.chen
 */
public class DataProvider_forDB implements Iterator<Object[]> {

    ResultSet rs;
    ResultSetMetaData rd;

    public DataProvider_forDB(String ip, String port, String baseName, 
        String userName, String password, String sql) throws ClassNotFoundException, SQLException {
        
        Class.forName("com.mysql.jdbc.Driver");
        String url = String.format("jdbc:mysql://%s:%s/%s", ip, port, baseName);
        Connection conn = DriverManager.getConnection(url, userName, password);
        Statement createStatement = conn.createStatement();

        rs = createStatement.executeQuery(sql);
        rd = rs.getMetaData();
    }

    @Override
    public boolean hasNext() {
        boolean flag = false;
        try {
            flag = rs.next();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return flag;
    }

    @Override
    public Object[] next() {
        Map<String, String> data = new HashMap<String, String>();
        try {
            for (int i = 1; i <= rd.getColumnCount(); i++) {
                data.put(rd.getColumnName(i), rs.getString(i));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        Object r[] = new Object[1];
        r[0] = data;
        return r;
    }

    @Override
    public void remove() {
        try {
            rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

复制代码

2.3 配置文件

上面图中提到了“配置文件”,下面就来简单看一下这个 XML 配置文件的脚本:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Pigeon Api测试" parallel="false">

    <test name="xxx-xxx-service">
        <parameter name="sql"
                   value="SELECT * FROM API_PigeonCases 
                   WHERE team_id=2
                   AND isRun=1
                   AND service='xxx-xxx-service'
                   AND env='beta';"/>
        <classes>
            <class name="com.dp.lego.test.TestPigeon"/>
        </classes>
    </test>

    <listeners>
        <listener class-name="org.uncommons.reportng.HTMLReporter"/>
        <listener class-name="org.uncommons.reportng.JUnitXMLReporter"/>
    </listeners>
</suite>

复制代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值