Lego-美团接口自动化测试实践

Lego是一个接口自动化测试平台,采用Jenkins+TestNG结构,使用MySQL存储测试用例,支持参数化和前后置动作,提供在线调试和用例生成工具,结合ReportNG生成测试报告,便于测试结果分析和用例优化。

一、概述

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 
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值