使用Parameters+DataProvider完成数据驱动接口测试

之前思考过几种不同的接口自动化框架的搭建结构,这是其中一种,实现的效果是:通过xml里存储的sql语句,去遍历mysql获得相应的测试数据,然后完成测试。
好处是这样做,完全是靠数据驱动测试,在有新增接口时,无须改动代码,只需要在mysql内添加测试数据,然后新的测试场景只需要修改xml就可以了。
下面讲一下简单的实现思路:

1.配置DataProvider_ForMysql类
用于链接数据库获取测试数据

import java.sql.*;
import java.util.*;

/**
 *数据库链接配置
 */
public class DataProvider_ForMysql implements Iterator {

    ResultSet result;  //结果集
    List> dataList = new ArrayList>();  //生成存放结果集的list
    int rowNum=0;     //总行数
    int curRowNo=0;   //当前行数

    public DataProvider_ForMysql(String ip, String port, String baseName,
                                 String userName, String password, String sql) throws ClassNotFoundException, SQLException {

        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = String.format("jdbc:mysql://%s:%s/%s?serverTimezone=UTC", ip, port, baseName);
        //获取连接
        Connection conn = DriverManager.getConnection(url, userName, password);
        //获取创建语句对象
        Statement stmt = conn.createStatement();
        //执行sql语句,获取查询结果集
        result = stmt.executeQuery(sql);
        //获取当前行数据
        ResultSetMetaData rd = result.getMetaData();

        //循环每行
        while (result.next()) {
            Map map = new HashMap();
            //循环每列,如果不要id,则讲i设为2
            for (int i = 1; i <= rd.getColumnCount(); i++) {
                String key = result.getMetaData().getColumnName(i);
                String value = result.getString(i);
                map.put(key,value);
            }
            dataList.add(map);
        }

        this.rowNum = dataList.size();

        conn.close();
        stmt.close();
    }


    @Override
    public boolean hasNext() {
        if(rowNum==0||curRowNo>=rowNum){
            return false;
        }else{
            return true;
        }
    }

    @Override
    public Object[] next() {
        Map s=dataList.get(curRowNo);
        Object[] d=new Object[1];
        d[0]=s;
        this.curRowNo++;
        return d;
    }

    @Override
    public void remove() {
        throw new UnsupportedOperationException("remove unsupported");
    }
}


2.配置xml文件



    
        
        
            
        
    
    
        
    

3.测试执行

public class TestCase {

    String sql;   //xml中读出的sql语句


	/**
	* 通过name来取xml文件中对应的sql语句
	*/
    @Parameters({"valueName"})
    @BeforeClass()
    public void beforeClass(String sql) {
        this.sql = sql;
    }

   
    /**
     * XML中的SQL决定了执行什么用例, 执行多少条用例, SQL的搜索结果为需要测试的测试用例
     */
    @DataProvider(name = "testData")
    private Iterator getData(){
        try {
            return new DataProvider_ForMysql(TestConfig.DB_IP, TestConfig.DB_PORT,
                TestConfig.DB_BASE_NAME,TestConfig.DB_USERNAME, TestConfig.DB_PASSWORD, sql);
        } catch (ClassNotFoundException e || SQLException e) {
            e.printStackTrace();
        } 
        return null;
    }


	/**
	*完整的测试数据,会以map的形式传递到测试方法里
	*/
    @Test(dataProvider = "testData")
    public void test(Map dataMap) {
        System.out.println(dataMap.toString());
    }
}

无论mysql中读出多少数据,都会一条条的去执行,所以在测试场景中,需要考虑的是如何通过sql语句筛选测试数据,以及用例与用例间的数据依赖。在之后的文章中,也会有这方面内容的分享。
有疑问的小伙伴可以在下方留言,我会针对问题不断优化文章内容,希望能有效的帮到更多人,谢谢~

你可能感兴趣的:(点点点工程师)