1.目录
- TestNG框架基础
- Rest-assured框架基础
- 接口用例编写与管理
- 接口用例运行与维护
2.接口测试框架选择
常见框架(界面化工具,针对不会编码的测试人员)
- Jmeter性能测试工具,不具备完备的接口测试框架功能
- Robotframework
- PostMan
推荐框架:
- RestAssured
- HttpClient
- SoapUI
- Swagger
Maven工程
Maven工程标准目录结构
目录结构 | 目录说明 |
src/main/java | 应用/代码源码 |
src/main/resources | 应用/代码的资源文件 |
src/main/filters | 资源过滤文件 |
src/main/webapp | web应用源码 |
src/test/java | 测试代码 |
src/test/resources | 测试资源 |
src/test/filters | 测试资源过滤文件 |
src/it | 集成测试(主要用于插件) |
src/assembly | 组装描述文件 |
src/site | 网站 |
LICENSE.md | 项目许可文件 |
NOTICE.md | 通知文件 |
README.md | 项目说明书 |
命令 | 功能说明 |
编译:mvn compile | src/main/java目录Java源码编译生成class,存放于target目录下 |
测试:mvn test | src/test/java目录编译,并执行用例 |
清理:mvn clean | 删除target目录,也就是将class文件等删除 |
打包:mvn package | 生成压缩文件:Java项目#jar包;web项目#war包,也是放在target目录下 |
安装:mvn install | 将压缩文件(jar或war)上传到本地仓库 |
部署:mvn deploy | 将压缩文件上传私服 |
TestNG是Java中的一套测试框架,它基于JUnit思想并强化了测试注解,可以灵活应用于各种测试场景。
@BeforeGroups:此测试组内的所有测试都运行之前
@AfterGroups:此测试组内的所有测试都运行之后
@BeforeClass:测试类之前运行
@AfterClass:测试类之后运行
@BeforeTest:测试方法前运行,只运行一次
@AfterTest:测试方法后运行,只运行一次
@BeforeMethod:每个测试方法之前都运行
@AfterMethod:每个测试方法之后都运行
创建一个maven项目,在src/test/java下新建pakcage命名为com.csj2018,并在这个package新建2个Java文件,用于熟悉testNG
引入依赖
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>
Lesson1.java
package com.csj2018;
import org.testng.annotations.*;
public class Lesson1 {
@BeforeTest
public void beforeTest(){
System.out.println("@BeforeTest");
}
@AfterTest
public void afterTest(){
System.out.println("@AfterTest");
}
@BeforeClass
public void setUp(){
System.out.println("@BeforeClass 测试类运行");
}
@AfterClass
public void tearDown(){
System.out.println("@AfterClass");
}
@BeforeMethod
public void beforeMethod(){
System.out.println("@BeforeMethod");
}
@AfterMethod
public void afterMethod(){
System.out.println("@AfterMethod");
}
@BeforeGroups(groups = "add")
public void beforeGroups(){
System.out.println("@BeforeGroups");
}
@AfterGroups(groups = "add")
public void afterGroups(){
System.out.println("@AfterGroup");
}
@Test(groups = "add",priority = 10) //值越小,优先级越高,默认0,按方法名顺序执行
public void test01(){
System.out.println("@Test 测试方法test01 测试组add by Lesson1");
}
@Test(groups = "update",invocationCount = 5,threadPoolSize = 3,priority = 3)//invocationCount指定运行次数,threadPoolSize指定线程数即并发量
public void test02(){
System.out.println("@Test 测试方法test02 测试组update by Lesson1");
}
}
Demo1.java
package com.csj2018;
import org.testng.annotations.Test;
public class Demo1 {
@Test(invocationCount = 2)
public void test01(){
System.out.println("@Test test01 by Demo1");
}
}
preference-Plugins安装创建TestNG XML的插件->选中工程,右键->Create testNG XML->自动生成testng.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite" verbose="1">
<test verbose="2" preserve-order="true" name="lesson1"><!--测试名称-->
<classes>
<class name="com.csj2018.Lesson1"><!--测试类的路径-->
<methods>
<include name="test01"/>
<include name="test02"/>
<!--<include name="afterMethod"/>-->
</methods>
</class>
<class name="com.csj2018.Demo1">
<methods>
<include name="test01"/>
</methods>
</class>
</classes>
</test>
</suite>
执行xml文件
创建testngGroup.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="All Test Suite" verbose="1">
<test verbose="2" preserve-order="true" name="lesson1"><!--测试名称-->
<groups>
<run>
<include name="add" /><!--只跑add组-->
</run>
</groups>
<classes>
<class name="com.csj2018.Demo1" />
<class name="com.csj2018.Lesson1" />
</classes>
</test>
</suite>
将run中的代码替换
```#xml
断言Hamcrest-Matchers
对象:
- equalTo-测试对象相等使用Object.equals方法
- hasToString-测试Object.toString方法
- instanceOf, isCompatibleType-测试类型
- notNullValue, nullValue-测试null
- someInstance-测试对象实例
集合:
- hasEntry, hasKey, hasValue-测试一个Map包含一个实体,key或value
- hasItem, hasItems-测试一个集合包含一个元素
- hasItemInArray-测试一个数组包含一个元素
数字:
- closeTo-测试浮点值接近给定的值
文本:
- equalToIgnoringCase-测试字符串相等忽略大小写
- equalToIgnoringWhiteSpace-测试字符串忽略空白
- containsString, endsWith, startWith-测试字符串匹配
保险起见,先倒入依赖
<!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-all -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hamcrest/hamcrest-core -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-core</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
测试类
package com.csj2018;
import org.testng.annotations.Test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static org.hamcrest.Matchers.*;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.StringContains.containsString;
import static org.hamcrest.core.StringStartsWith.startsWith;
import static org.junit.Assert.assertThat;
public class HamcrestDemo {
/**
* 数值型断言
*/
@Test
public void testInt(){
Integer i = 1 + 1;
assertThat(i,is(2));
assertThat(i,not(3));
}
/**
* 字符串断言
*/
@Test
public void testString(){
String a = "hello world";
assertThat(a,equalTo("Hello World".toLowerCase()));
assertThat(a,equalToIgnoringCase("Hello World"));
assertThat(a,containsString("hello"));
assertThat(a,startsWith("hello"));
}
/**
* 数组
*/
@Test
public void testArray(){
String[] a = {"丰田","本田","大众","奇瑞"};
assertThat(a,hasItemInArray("大众"));
}
/**
* 集合断言
*/
@Test
public void testList(){
List<String> list = new ArrayList<String>();
list.add("Das Auto");
list.add("Nissan");
list.add("Honda");
assertThat(list,hasItem("Das Auto"));
}
/**
* map断言
*/
@Test
public void testMap(){
Map<String,String> map = new HashMap<>();
map.put("大众","朗逸");
map.put("丰田","卡罗拉");
assertThat(map,hasEntry("大众","朗逸"));
assertThat(map,hasKey("大众"));
assertThat(map,hasValue("卡罗拉"));
}
}