接口测试响应验证
如何在测试过程中验证接口没有 Bug?
- 通过接口响应值
- 通过查询数据库信息辅助验证
接口测试数据清理
自动化测试过程中,会产生大量的脏数据,如何处理?
- 通过 Delete 接口删除
- 自动化测试使用干净的测试环境,每次自动化测试执行完成之前或之后做数据还原
数据库操作注意事项
直接对数据库做查询之外的操作是非常危险的行为
- 权限管理严格的公司数据库权限给的非常低
- 表结构复杂,随便删除数据会影响测试,甚至会导致系统出现异常
接口自动化测试常用的数据库操作
- Python 技术栈:章节《常用第三方库pymsql》
- Java 技术栈:《常用标准库:数据库操作-JDBC》
接口自动化测试常用的数据库操作
- 连接与配置 2. 查询数据与断言
- Python 技术栈:章节《常用第三方库pymsql》
- Java 技术栈:《常用标准库:数据库操作-JDBC》
数据库信息
- 主机: litemall.hogwarts.ceshiren.com
- 端口: 13306
- 用户名: test
- 密码: test123456
注意:只有查询权限
数据库封装
创建一个工具类,输入SQL,返回查询结果
mysql mysql-connector-java 8.0.30public class DatabaseUtils {
Statement statement;
Connection conn;
// 初始化数据库信息
public DatabaseUtils(String DB_URL, String USER, String PASS) {
try {
Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
statement = conn.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
}
// 根据 sql 返回在数据库查询的信息
public List<String> getResultStringListBySQL(String sql_query, String columnLabel){
List<String> resList = new ArrayList<>();
try {
ResultSet resultSet = statement.executeQuery(sql_query);
while (resultSet.next()){
resList.add(resultSet.getString(columnLabel));
}
}catch (SQLException e) {
e.printStackTrace();
}
return resList;
}
}
数据库结合断言优化
- 查询 litemall 数据库返回的数据
- 辅助完成断言
public class DatabaseTest {
static final String DB_URL = "jdbc:mysql://litemall.hogwarts.ceshiren.com:13306/litemall?useSSL=false";
static final String USER = "test";
static final String PASS = "test123456";
static final String QUERY = "select * from litemall_cart where user_id=1 and deleted=0";
@Test
void getDataBySql() {
// 初始化数据库工具类
DatabaseUtils databaseUtils = new DatabaseUtils(DB_URL, USER, PASS);
// 提取查询结果中所有的goods_name
List<String> dataResult = databaseUtils.getResultStringListBySQL(QUERY, "goods_name");
// 断言数据库数据是否包含hogwarts
assertTrue(dataResult.contains("hogwarts"));
}
}
数据库封装-优化(选修)
- 问题: 数据库查询的信息,不一定所有的信息返回的类型都是String,封装的工具类不够通用
- 解决方案:优化工具类,把查询到的所有数据集转换成一个json结构体,使用JsonPath把对应的信息获取到。
<dependency>
<groupId>org.jooq</groupId>
<artifactId>jooq</artifactId>
<version>3.11.11</version>
</dependency>
<dependency>
<groupId>com.jayway.jsonpath</groupId>
<artifactId>json-path</artifactId>
<version>2.6.0</version>
<scope>test</scope>
</dependency>
public class DatabaseUtils {
Statement statement;
Connection conn;
public DatabaseUtils(String DB_URL, String USER, String PASS) {
try {
Connection conn = DriverManager.getConnection(DB_URL, USER, PASS);
statement = conn.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
}
public String getResultSetBySQL(String sql_query) {
// 格式转换将ResultSet 转换为 标准的json格式,方便完成断言。
try {
ResultSet resultSet = statement.executeQuery(sql_query);
// 获取所有
ResultSetMetaData md = resultSet.getMetaData();
int numCols = md.getColumnCount();
// 获取所有的数据表列名
List<String> colNames = new ArrayList<>();
for (int i = 1; i <= numCols; i++) {
String name = md.getColumnName(i);
colNames.add(name);
}
// 返回一个json结构的查询结果
return DSL.using(conn)
.fetch(resultSet)
.map(new RecordMapper() {
@Override
public JSONObject map(Record r) {
JSONObject obj = new JSONObject();
colNames.forEach(cn -> obj.put(cn, r.get(cn)));
return obj;
}
}).toString();
} catch (SQLException e) {
e.printStackTrace();
}
// 如果异常,return 空 json,不影响后续逻辑执行
return "{}";
}
}