课前准备
上节课作业: https://testerhome.com/topics/16170
SessionFilter
使用与代码剖析
数据驱动
- csv yaml读取lib https://github.com/FasterXML/jackson-dataformats-text
导入依赖
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-csv</artifactId>
<version>2.8.8</version>
</dependency>
csv驱动
package offline3;
import com.fasterxml.jackson.databind.MappingIterator;
import com.fasterxml.jackson.dataformat.csv.CsvMapper;
import com.fasterxml.jackson.dataformat.csv.CsvSchema;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ErrorCollector;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List;
import static org.hamcrest.Matchers.equalTo;
@RunWith(Parameterized.class)
public class AssertionTestData {
@Rule
public ErrorCollector collector = new ErrorCollector();
/* public static List<TestData> data(){
ArrayList<TestData> datas=new ArrayList<>();
datas.add(new TestData(1, 2));
datas.add(new TestData(2, 2));
return datas;
}*/
@Parameterized.Parameters
public static List<TestData> dataCSV() throws IOException {
return readFromCSV();
}
public static List<TestData> readFromCSV() throws IOException {
ArrayList<TestData> data=new ArrayList<TestData>();
CsvMapper mapper = new CsvMapper();
CsvSchema schema = mapper.schemaFor(TestData.class);
//mapper.enable(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);
File csvFile = new File(AssertionTestData.class.getResource("../data/testdata.csv").getFile()); // or from String, URL etc
MappingIterator<TestData> it = mapper.readerFor(TestData.class).with(schema).readValues(csvFile);
while (it.hasNext()) {
TestData row = it.next();
data.add(row);
}
return data;
}
@Parameterized.Parameter
public TestData data;
@Test
public void assertions(){
collector.checkThat(data.getReal(), equalTo(data.getExpect()));
}
}
数据模型
package offline3;
public class TestData {
public int getReal() {
return real;
}
public void setReal(int real) {
this.real = real;
}
private int real;
public int getExpect() {
return expect;
}
public void setExpect(int expect) {
this.expect = expect;
}
private int expect;
}
数据文件
1,2
3,4
1,1
2,2
3,3
3,5
YAML与json数据
public static List<TestData> readFromYAML() throws IOException {
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
List<TestData> data = mapper.readValue(
new File(AssertionTestData.class.getResource("/data/testdata.yaml").getFile()),
new TypeReference<List<TestData>>(){}
);
return data;
}
public static List<TestData> readFromJSON() throws IOException {
ObjectMapper mapper = new ObjectMapper();
List<TestData> data = mapper.readValue(
new File(AssertionTestData.class.getResource("/data/testdata.json").getFile()),
new TypeReference<List<TestData>>(){}
);
return data;
}
YAML数据源
- real: 1
expect: 1
real2: 2
expect2: 2
- real: 1
expect: 2
real2: 2
expect2: 2
- real: 1
expect: 1
real2: 2
expect2: 2
- real: 1
expect: 1
real2: 2
expect2: 3
JSON数据源
[
{
"real": 1,
"expect": 1,
"real2": 2,
"expect2": 4
},
{
"real": 1,
"expect": 2,
"real2": 2,
"expect2": 2
}
]
读取配置文件
public static void write(String filePath){
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
try {
mapper.writeValue(new File(filePath), new MeiTuanConfig());
} catch (IOException e) {
e.printStackTrace();
}
}
public static MeiTuanConfig load(String filePath){
ObjectMapper mapper = new ObjectMapper(new YAMLFactory());
MeiTuanConfig conf=new MeiTuanConfig();
try {
conf=mapper.readValue(new File(filePath), MeiTuanConfig.class);
} catch (IOException e) {
e.printStackTrace();
}
return conf;
}
测试用例管理
三种至关重要的顺序控制
- 套件级别的顺序控制
- 继承关系里的初始化顺序
- 单个类里的执行顺序
企业微信演练
Swagger
Dubbo
小作业1
创建一个三层的继承关系,所有的Class里都添加上类级别的初始化BeforeClass和方法级别的初始化Before,打印下所有方法的执行流程。
A->B->C->3个用例
作业2
读取一个三行两列的csv数据,这个数据里是字符串,断言两个字符串是否相等
作业3
从YAML文件里读取3个数据,两个数字,一个字符串。构建一个数据驱动的测试用例,根据两个数字的相加,判断是否等于字符串。
作业4
完成企业微信的接口测试用例体系。提前演练,下节课重点实训。把完整的项目代码上传到github并把仓库地址贴到回复里。
拔高题
做一个小的基于yaml的接口测试工具,支持发送请求和断言。
- given:
queryParam:
- key: value
headers:
- key: "content-type"
value: "json"
request: get/post
when:
request: get/post
url: "https://qyapi.weixin.qq.com/cgi-bin/gettoken"
then:
statusCode: 200
body:
- errcode: 0
- given:
queryParam:
- key: value
header:
- key: "content-type"
value: "json"
request: get/post
when:
request: get/post
url: "https://qyapi.weixin.qq.com/cgi-bin/gettoken"
then:
statusCode: 200
body:
- errcode: 0
public class HttpTest {
static List<HttpTestStep> testcase;
@BeforeClass
public static void beforeClass(){
//testcase=load(yaml)
}
@Test
public void run(){
for(HttpTestStep step: testcase){
RequestSpecification requestSpecification=given();
if(step.given.request=="get"){
requestSpecification.when().get(step.given.url);
}
requestSpecification.then().statusCode(200);
}
}
}