再次来到框架设计部分,这里说的框架设计,其实我们自己和设计框架没有啥关系,因为水平远远达不到设计这个词的含义,更多是借助第三方框架来组装框架。任何自动化测试框架,都有以下两个重要的目标:代码复用性和方便维护性。本篇先来学习下框架设计的一些理论知识或者套路,然后开始我们的基于Rest Assured框架搭建我们自己的接口自动化测试框架介绍。
框架组装步骤
第一步:分析
在框架组装之前,需要把一些前提条件给想好。这里主要的前提条件是围绕测试用例执行和管理。所以,需要用到测试框架,包括单元测试框架和其他功能测试框架。例如常见的测试框架,有TestNG, Junit, Cucumber, Robot 等, 这里我们选择TestNG,主要的原因,就是利用extent report得到更美观的测试报告。
第二步,框架选型
如果学习过Selenium自动化测试框架,我们知道常见的框架有,页面对象模型,关键字驱动,数据驱动,行为驱动,以及前面两个或者多个的混合框架。一般来说,现在采用混合框架居多。
第三部,设计/实现混合框架
这里说的混合框架,其实呢Rest Assured具备一些行为驱动的特点。然后如果你API测试用例写在excel文件中,java中借助POI这个jar包获取excel数据,然后使用TestNG的data provider这个注解来实现数据驱动。这个数据驱动,在这个框架,我暂时不引入进来。所有的API测试用例都写在TestNG管理的测试类中。
以下是这个混合框架几个关键组件。
-- Rest Assured
-- TestNG
-- Maven
-- Jenkins(CI)
-- Git&Github
我这里介绍的框架支持测试用例写在TestNG测试类中,也支持用例写在excel文件中,只不过,我暂时不介绍Excel管理用例的方式。
具体实现/开发框架
基于上面的框架选型,我大概分以下步骤来逐渐介绍这个框架的组装过程。
-- 创建一个Maven 工程
-- 更新 pom.xml文件
-- 创建文件夹结构
-- 日志模块(log4j)
-- 继承思想,测试基类BaseTest.java的设计
-- 扩充实际接口测试用例和调试测试
-- 其他工具类补充
-- 报告获取
-- Jenkins持续集成搭建
Maven工程的创建
在Java项目中,我们现在几乎全部看到的工程都是Maven工程,所以,我们也采用这个方式。我用的环境是Eclipse这款IDE,具体如何创建我就不多说,直接贴出我们的pom.xml就能看到我Maven工程的一些信息。
pom.xml内容
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.restassured</groupId>
<artifactId>RestAssured</artifactId>
<version>0.0.1-SNAPSHOT</version>
<dependencies>
<!-- https://mvnrepository.com/artifact/io.rest-assured/rest-assured -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>rest-assured</artifactId>
<version>4.0.0</version>
<scope>test</scope>
</dependency>
<!-- use to parse json document -->
<!-- https://mvnrepository.com/artifact/io.rest-assured/json-path -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-path</artifactId>
<version>4.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.rest-assured/json-schema-validator -->
<!-- validate a json response conforms to a Json schema -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>json-schema-validator</artifactId>
<version>4.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/io.rest-assured/xml-path -->
<!-- use to parse xml document -->
<dependency>
<groupId>io.rest-assured</groupId>
<artifactId>xml-path</artifactId>
<version>4.0.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.testng/testng -->
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.14.3</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hamcrest/java-hamcrest -->
<!-- match rules in assertion -->
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>java-hamcrest</artifactId>
<version>2.0.0.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>com.aventstack</groupId>
<artifactId>extentreports</artifactId>
<version>4.0.9</version>
</dependency>
</dependencies>
</project>
暂时先这么多依赖包,后面如果有需要,会补充,最后这个项目源码我会放到github上,在框架设计最后一篇文章给出github项目的信息。
TestNG在最新Eclipse的坑
例如我们下载的Eclipse是2019.3月份以后,不管是Java SE还是Java EE版本的Eclipse,你会发现,你无法根据网上搜索到的资料去正确在Eclipse上成功安装TestNG插件,这样在debug过程中,右键run as就没有TestNG这个选项菜单。这个坑我踩过,花费了一些时间,我再次强调下面这个步骤是正确的解决该问题的办法。
在开始之前,这里介绍一下最新(2019年3月以上)的Eclipse不能从Eclipse市场找到,也不能从install software中下载TestNG的这个问题。
1)打开 http://dl.bintray.com/testng-team/testng-eclipse-release/
2)点击底部 zipped 链接
3)点击下载2019年最新的TestNG版本下载 6.14.3.201902250526
4)下载 zip包 到本地,例如桌面 org.testng.eclipse.updatesite.zip
5)利用解压工具,直接解压到 E:\eclipse\dropins , 我Eclipse放在 E:\eclipse
这个工具直接解压很重要,千万要用这个方法。我尝试过解压到桌面,然后复制到dropins文件夹下,不行
6)重新启动Eclipse软件,选一个包,右键 new-others..-TestNG class,说明TestNG安装成功。
这个我在前面文章也介绍过:https://blog.csdn.net/u011541946/article/details/96477173
我这里贴两张关键的截图,下面这张解压到Eclipse下dropins文件夹是正确的效果图。如果不和我们下面截图一样,你多尝试解压到dropins文件夹,如果出现下面红圈这个文件夹,删除其他全部文件,保留这个文件夹就可以,确保这个红圈标注的文件夹下有testNG的内容。可以多尝试几个testNG版本,例如6.14.0 和6.14.3版本。
重启Eclipse之后,如果创建一个类向导页面能看到TestNG, 或者下面这个运行的时候出现菜单,说明TestNG环境就好了。
说实话这个TestNG插件安装确实可能不顺利,需要耗费一些时间,确实没有Junit方便,如果Junit能够有好的报告方式,我早就想用Junit来代替TestNG了。
项目文件夹创建
这个文件夹创建过程,其实就包含了我们框架搭建的思想,一开始我们大概是这个结构。
到了具体Maven工程上,我先给一个截图,效果是这样
上面我们主要在src.test.java下写代码,我没有选择在src.main.java写代码,这里不需要。一个TestBase父类,全部测试用例类都继承这个父类,好处就不说了这里,学Java得应该得明白这个道理。一个包下全面放测试用例,还有一个工具类utils包,先空着。有一个config.properties文件,里面就服务器地址和端口信息,因为我们这套测试用例开发出来,能够在测试环境和准生产环境和线上环境去执行用例。至于为什么放src/test/resource下,这是maven工程的特点,不需要纠结。全部日志内容打印到logs/restAPI.log文件。
日志模块
在Java项目中,永远逃不开log4j组件来处理日志。这个在我前面文章也有介绍如何集成Log4j来到我们具体项目中。https://blog.csdn.net/u011541946/article/details/76038697
这里我简化一下log4j.properties的配置,精简一下,我们只需要在/logs/restAPI.log和Eclipse控制台输出日志就可以,不需要什么HTML格式的日志文件。以下是项目根目录下log4j.properties配置内容。
# Root logger option
log4j.rootLogger=INFO,file,stdout
# Direct log message to a log file
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./logs/restAPI.log
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
# Direct log message to stdout(eg. Eclipse)
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n
这个每一项什么意思,有些我们很容易看懂,有些看不到没关系,我们下面贴一个日志效果,你对比着看看就能明白全部配置的含义。
2019-09-01 16:29:21 INFO CaseDemo1:36 - host: https://reqres.in
2019-09-01 16:29:21 INFO CaseDemo1:37 - port: 80
2019-09-01 16:29:21 INFO CaseDemo1:12 - First test case
2019-09-01 16:29:26 INFO CaseDemo2:36 - host: https://reqres.in
2019-09-01 16:29:26 INFO CaseDemo2:37 - port: 80
2019-09-01 16:29:26 INFO CaseDemo2:12 - Second test case
每行日志分成四段,第一列是时间日期,精确到秒,你也可以精确到毫秒,无关紧要。第二列是日志级别,场景有INFO,DEBUG,ERROR等。第三列是当然执行的类名称和代码行,第四列是我们程序员写的msg,这个msg具体内容是程序员在代码中写死的。
配置文件读取
来看看配置文件如何读取,前面我们介绍过,现在换一个API来读取properties文件。
# api host info
Host=https://reqres.in
# default port
Port=80
这个ResourceBundle是专门读取properties配置文件,比我们使用IO流读取代码简单。具体读取代码我合并到测试基类中去,直接写到静态代码块中,会加载类之后执行静态代码块读取操作。
TestBase.java设计
目前我就把读取之后的服务器地址和端口赋值给一个静态变量,然后写一段初始化日志的模块,这样每个用例就直接使用logger.info()这样和调用System.out.println()一样方便。
package com.anthony.base;
import java.util.ResourceBundle;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.testng.annotations.BeforeClass;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
public class TestBase {
public static RequestSpecification httpRequest;
public static Response response;
public Logger logger;
public static String serverHost;
public static String port;
static {
// 用于加载properties文件
// 注意这里不需要文件扩展名.properties
ResourceBundle rb = ResourceBundle.getBundle("config");
serverHost = rb.getString("Host");
port = rb.getString("Port");
}
@BeforeClass
public void setup() {
String className = this.getClass().getName();
logger = Logger.getLogger(className);
PropertyConfigurator.configure("log4j.properties");
logger.setLevel(Level.DEBUG);
logger.info("host: " + serverHost);
logger.info("port: " + port);
}
}
目前只有两部分,一部分是服务器和端口信息读取,第二部分是@BeforeClass中,方便没一个子类都能直接调用日志模块写入到日志文件,日志文件中第三类class名称输出就来源这块代码。后面我会把Rest Assured中一些全局变量和方法都添加到这个TestBase类中来。
测试类
写两个测试用来继承TestBase,来测试下资源文件读取和日志输出。
package com.anthony.cases;
import org.testng.annotations.Test;
import com.anthony.base.TestBase;
public class CaseDemo1 extends TestBase {
@Test
public void test1() {
logger.info("First test case ");
}
}
package com.anthony.cases;
import org.testng.annotations.Test;
import com.anthony.base.TestBase;
public class CaseDemo2 extends TestBase {
@Test
public void test1() {
logger.info("Second test case ");
}
}
先在Demo1中运行TestNG,然后在Demo2中运行TestNG, 只要你TestNG环境没问题,两个用例都运行成功,刷新/logs文件夹,打开restAPI.log文件,看看日志。
这里看到每个用例都执行了TestBase类中的@BeforeClass中代码,这就是继承,由于日志冗余,我这里把父类中@BeforeClass下两行logger.info()代码注释掉。