通过xml里存储的sql语句,去遍历mysql获得相应的测试数据,然后完成测试。
优点:完全是靠数据驱动测试,在有新增接口时,无须改动代码,只需要在mysql内添加测试数据,然后新的测试场景只需要修改xml就可以了。
1.配置DataProvider_ForMysql类
用于链接数据库获取测试数据
import java.sql.*;
import java.util.*;
/**
*数据库链接配置
*/
public class DataProvider_ForMysql implements Iterator<Object[]> {
ResultSet result; //结果集
List<Map<String, String>> dataList = new ArrayList<Map<String, String>>(); //生成存放结果集的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<String, String> map = new HashMap<String, String>();
//循环每列,如果不要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<String,String> 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文件
<?xml version="1.0" encoding="UTF-8" ?>
<suite name="suite">
<test name="test">
<parameter name="valueName" value="select * from new_model"/>
<classes>
<class name="com.course.TestCase"/>
</classes>
</test>
<listeners>
<listener class-name="com.course.config.ExtentTestNGIReporterListener"></listener>
</listeners>
</suite>
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<Object[]> 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<String, String> dataMap) {
System.out.println(dataMap.toString());
}
}
无论mysql中读出多少数据,都会一条条的去执行,所以在测试场景中,需要考虑的是如何通过sql语句筛选测试数据,以及用例与用例间的数据依赖。