精华内容
下载资源
问答
  • 接口自动化测试框架

    2018-04-02 22:38:53
    搭建接口自动化测试框架 搭建接口自动化测试框架 搭建接口自动化测试框架 搭建接口自动化测试框架
  • 主要介绍了java接口自动化测试框架及断言详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 一个完整可用的接口自动化框架源码含接口数据及设计文档,该框架对于想从事接口自动化的小伙伴,可以直接使用,对于从事多年的接口自动化的框架的人员,也有一定的借鉴意义。
  • 基于java接口自动化框架

    千次阅读 2018-03-07 16:53:11
    框架简介 APIAutoTest是处理API接口的轻量级自动化测试框架Java语言实现,基于TestNG测试框架,支持持续集成,自动构建与测试。框架介绍数据驱动设计,使用TestNG中的@DataProvider读取Excel中存储的自动化测试...

    框架简介

            APIAutoTest是处理API接口的轻量级自动化测试框架,Java语言实现,基于TestNG测试框架,支持持续集成,自动构建与测试。

    框架介绍

    1. 数据驱动设计,使用TestNG中的@DataProvider读取Excel中存储的自动化测试用例
    2. 基于TestNG测试框架
    3. 使用HttpClient发送Http请求,并统一接口response返回值为String
    4. 使用fastJson和Jsoup进行数据解析,由于请求返回值的统一,解析数据异常方便,方便接入不同接口类型的数据
    5. 独立封装的检查点“Jsonpath”检查点,极大方便检查点的设置
    6. 在线报告以及Email报告
    7. 持续集成、持续交付、自动构建与测试
    8. mock环境

    框架组件

    •  Maven进行项目、依赖管理
    • HttpClient进行通信
    • TestNG测试框架管理测试脚本以及测试驱动
    • FastJson/Jsoup用于数据解析
    • AssertJ用于检查点设置
    • ExtentReports输出具备图表分析的报告
    • SVN+Jenkins实现持续集成

    框架执行流程

    测试执行的流程(代码层):

    • 测试执行的入口为TestNG的XML文件
    • 获取测试用例的脚本,测试用例执行分为测试前(@BeforeTest),测试中(@Test),测试后(@AfterTest)
    • @BeforeTest:获取/解析测试数据(Excel文件),接口关联参数化,Cookie装载等
    • @Test:初始化httpclient对象,执行请求,获取响应并转换成String等
    • @AfterTest:jsonpath检查点,对于接口正确/错误请求的逻辑处理
    • 生成在线ExtentReports报告/日志
    • Email报告,测试结果通知测试相关人员

    用例设计管理

    • 通过TestNG的@DataProvider获取Excel测试数据

    • 将数据的表头与数据存储在map中,具体使用时方便

    • jsonpathPoint:jsonpath检查点,框架特点之一,极大的方便断言的编写

    • 前后缀的使用:通过前后缀使用来区分统一作用的数据,如请求参数:params

    • 是否运行/检查控制:通过编写测试用例时就可以控制该用例是否运行,是否检查

    • 不足之处:一个接口的测试数据对应一个Excel文件/Sheet表,后期数据量太大

    总结

         接口自动化测试在这个追求效率的时代,逐渐的取代UI自动化测试,而做接口自动化测试的工具很多,比如soapUI,postman,jmeter等等,但是这些通用的工具的可扩展性以及跟项目的契合度上并不是十分合适。 框架的作用在于使测试脚本编写变得简单,增强测试脚本的可维护性,容错率等,提高测试脚本的编写效率,从而提高测试效率。

    展开全文
  • 主要介绍了Java接口自动化测试框架设计 Get请求方法和测试,框架设计我们只是介绍基本的组件,而且框架设计没有想象那么难,一步一步跟着做就会了。这篇我们来演示,如果通过Java代码来实现一个用纯代码实现Http中的...
  • E:\最全面的Java接口自动化测试实战\第3章 手工接口测试到自动化框架设计 E:\最全面的Java接口自动化测试实战\第4章 企业级代码管理工具git的应用 E:\最全面的Java接口自动化测试实战\第5章 测试框架TestNG E:\最...
  • 接口测试框架 https://blog.csdn.net/qq_15283475/article/details/106494544 com.bjci.api #包名 ApiInfoModel.java ## Api类 ExcelUtills.java ##操作excel的类 HandlsUtils.java ##根据judge分发不同的...
  • 自动测试:基于Java语言的接口自动化
  • AutoTest:基于java语言的接口自动化
  • Java接口自动化测试框架

    千次阅读 2019-11-21 12:07:20
    自动化测试框架 1. 测试框架TestNG 1.1 适合测试人员使用的原因 (1)比Junit涵盖功能更全面的测试框架 (2)Junit更适合隔离性比较强的单元测试 (3)TestNG更适合复杂的集成测试 1.2 基本介绍 (1)基本注解:...

    一. 自动化测试框架

    在这里插入图片描述

    1. 测试框架TestNG

    1.1 适合测试人员使用的原因

    (1)比Junit涵盖功能更全面的测试框架
    (2)Junit更适合隔离性比较强的单元测试
    (3)TestNG更适合复杂的集成测试

    1.2 基本介绍

    (1)基本注解:决定执行顺序
    例:
    @Test:标记一个类或方法作为测试的一部分
    @beforeTest、@afterTest:做前置或后置处理
    (2)属性
    例:
    groups:分组测试
    dependsOnGroups:依赖测试
    description:描述
    (3)测试套件
    组织测试类一起执行的或者一组行为的测试用例的集合,由一个XML文件标记

    2. 测试报告ExtentReport

    2.1 添加测试类

    ExtentTestNGIReporterListener

    2.2 基本配置

    在测试套件中 @listener标签下添加监听器

    3. HttpClient

    一个HTTP客户端编程工具,可用来发送请求、接收响应

    4. MyBatis

    持久层框架,支持定制化 SQL、存储过程以及高级映射。
    可以使用简单的 XML 或注解来配置和映射原生信息。

    5. MySQL

    存储测试用例

    二. 编写步骤及文件目录结构

    1. 测试用例的表结构设计

    在这里插入图片描述

    2. 基础配置文件设计

    在这里插入图片描述

    2.1 pom.xml:引入第三方依赖包

    配置httpclient、json、mybatis、mysql、lombok、extentreports、testng的各种依赖

    <?xml version="1.0" encoding="UTF-8"?>
    <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">
        <parent>
            <artifactId>AutoTest</artifactId>
            <groupId>Chapter</groupId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <modelVersion>4.0.0</modelVersion>
    
        <artifactId>Chapter12</artifactId>
    
        <dependencies>
            <dependency>
                <groupId>org.apache.httpcomponents</groupId>
                <artifactId>httpclient</artifactId>
                <version>4.1.2</version>
            </dependency>
            <dependency>
                <groupId>org.json</groupId>
                <artifactId>json</artifactId>
                <version>20170516</version>
            </dependency>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.4.4</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>1.16.14</version>
            </dependency>
            <dependency>
                <groupId>com.relevantcodes</groupId>
                <artifactId>extentreports</artifactId>
                <version>2.41.1</version>
            </dependency>
            <dependency>
                <groupId>com.vimalselvam</groupId>
                <artifactId>testng-extentsreport</artifactId>
                <version>1.3.1</version>
            </dependency>
            <dependency>
                <groupId>com.aventstack</groupId>
                <artifactId>extentreports</artifactId>
                <version>3.0.6</version>
            </dependency>
            <dependency>
                <groupId>org.testng</groupId>
                <artifactId>testng</artifactId>
                <version>6.10</version>
            </dependency>
            <dependency>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
                <version>1.0.4</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
            </dependency>
        </dependencies>
    </project>
    

    2.2 databaseConfig.xml:数据库配置文件

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    
    <configuration>
        <!-- 注册对象的空间命名 -->
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <!-- 1.加载数据库驱动 -->
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <!-- 2.数据库连接地址 -->
                    <property name="url" value="jdbc:mysql://localhost:3306/course?serverTimezone=GMT"/>
                    <!-- 数据库用户... -->
                    <property name="username" value="root"/>
                    <!-- 数据库密码... -->
                    <property name="password" value="12345678"/>
                </dataSource>
            </environment>
        </environments>
        <!-- 注册映射文件:java对象与数据库之间的xml文件路径! -->
        <mappers>
            <mapper resource="mapper/SQLMapper.xml"/>
        </mappers>
    </configuration>
    

    2.3 application.properties:接口信息配置文件

    test.url=http://localhost:8080
    
    #登陆接口uri
    login.uri=/v1/login
    

    2.4 testng.xml:用以执行所有testng的测试套件

    <?xml version="1.0" encoding="UTF-8" ?>
    <suite  name="用户管理系统测试套件">
        <test name="用户管理系统测试用例">
            <classes>
                <class name="com.tester.cases.LoginTest">
                    <methods>
                        <include name="loginTrue"/>
                        <include name="loginFalse"/>
                    </methods>
                </class>       
            </classes>
        </test>
        <listeners>
            <listener class-name="com.tester.config.ExtentTestNGIReporterListener"/>
        </listeners>
    </suite>
    

    2.5 SQLMapper.xml:用以存储所有测试用例的SQL语句

    <?xml version="1.0" encoding="UTF-8" ?>
    
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.tester.model">
        <!--获取登陆接口case-->
        <select id="loginCase" parameterType="Integer" resultType="com.tester.model.LoginCase">
            select *from logincase where id=#{id};
        </select>
     </mapper>
    

    3. model层、config层、utils层、cases层

    在这里插入图片描述

    3.1 model层:放置各个接口的数据配置文件+InterfaceName枚举

    3.1.1 放置登录接口的数据配置文件LoginCase.java

    package com.tester.model;
    
    import lombok.Data;
    
    @Data
    public class LoginCase {
        private int id;
        private String userName;
        private String password;
        private String expected;
    }
    

    3.1.2 InterfaceName.java

    package com.tester.model;
    
    public enum InterfaceName {
        LOGIN
    }
    

    3.2 Config层:配置信息TestConfig类+ExtentTestNGReportListener类

    3.2.1TestConfig类:声明各个测试用例的URL、和之后要用的一些全局变量

    package com.tester.config;
    
    import lombok.Data;
    import org.apache.http.client.CookieStore;
    import org.apache.http.impl.client.DefaultHttpClient;
    
    
    
    @Data
    public class TestConfig {
        //登陆接口uri
        public static String loginUrl;
        //声明http客户端
        public static DefaultHttpClient defaultHttpClient;
        //用来存储cookies信息的变量
        public static CookieStore store;
    }
    

    3.2.2 ExtentTestNGReportListener类:测试报告配置

    package com.tester.config;
    
    
    import com.aventstack.extentreports.ExtentReports;
    import com.aventstack.extentreports.ExtentTest;
    import com.aventstack.extentreports.ResourceCDN;
    import com.aventstack.extentreports.Status;
    import com.aventstack.extentreports.model.TestAttribute;
    import com.aventstack.extentreports.reporter.ExtentHtmlReporter;
    import com.aventstack.extentreports.reporter.configuration.ChartLocation;
    import com.aventstack.extentreports.reporter.configuration.Theme;
    import org.testng.*;
    import org.testng.xml.XmlSuite;
    
    import java.io.File;
    import java.util.*;
    
    public class ExtentTestNGIReporterListener implements IReporter {
        //生成的路径以及文件名
        private static final String OUTPUT_FOLDER = "test-output/";
        private static final String FILE_NAME = "index.html";
    
        private ExtentReports extent;
    
        @Override
        public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, String outputDirectory) {
            init();
            boolean createSuiteNode = false;
            if(suites.size()>1){
                createSuiteNode=true;
            }
            for (ISuite suite : suites) {
                Map<String, ISuiteResult> result = suite.getResults();
                //如果suite里面没有任何用例,直接跳过,不在报告里生成
                if(result.size()==0){
                    continue;
                }
                //统计suite下的成功、失败、跳过的总用例数
                int suiteFailSize=0;
                int suitePassSize=0;
                int suiteSkipSize=0;
                ExtentTest suiteTest=null;
                //存在多个suite的情况下,在报告中将同一个一个suite的测试结果归为一类,创建一级节点。
                if(createSuiteNode){
                    suiteTest = extent.createTest(suite.getName()).assignCategory(suite.getName());
                }
                boolean createSuiteResultNode = false;
                if(result.size()>1){
                    createSuiteResultNode=true;
                }
                for (ISuiteResult r : result.values()) {
                    ExtentTest resultNode;
                    ITestContext context = r.getTestContext();
                    if(createSuiteResultNode){
                        //没有创建suite的情况下,将在SuiteResult的创建为一级节点,否则创建为suite的一个子节点。
                        if( null == suiteTest){
                            resultNode = extent.createTest(r.getTestContext().getName());
                        }else{
                            resultNode = suiteTest.createNode(r.getTestContext().getName());
                        }
                    }else{
                        resultNode = suiteTest;
                    }
                    if(resultNode != null){
                        resultNode.getModel().setName(suite.getName()+" : "+r.getTestContext().getName());
                        if(resultNode.getModel().hasCategory()){
                            resultNode.assignCategory(r.getTestContext().getName());
                        }else{
                            resultNode.assignCategory(suite.getName(),r.getTestContext().getName());
                        }
                        resultNode.getModel().setStartTime(r.getTestContext().getStartDate());
                        resultNode.getModel().setEndTime(r.getTestContext().getEndDate());
                        //统计SuiteResult下的数据
                        int passSize = r.getTestContext().getPassedTests().size();
                        int failSize = r.getTestContext().getFailedTests().size();
                        int skipSize = r.getTestContext().getSkippedTests().size();
                        suitePassSize += passSize;
                        suiteFailSize += failSize;
                        suiteSkipSize += skipSize;
                        if(failSize>0){
                            resultNode.getModel().setStatus(Status.FAIL);
                        }
                        resultNode.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",passSize,failSize,skipSize));
                    }
                    buildTestNodes(resultNode,context.getFailedTests(), Status.FAIL);
                    buildTestNodes(resultNode,context.getSkippedTests(), Status.SKIP);
                    buildTestNodes(resultNode,context.getPassedTests(), Status.PASS);
                }
                if(suiteTest!= null){
                    suiteTest.getModel().setDescription(String.format("Pass: %s ; Fail: %s ; Skip: %s ;",suitePassSize,suiteFailSize,suiteSkipSize));
                    if(suiteFailSize>0){
                        suiteTest.getModel().setStatus(Status.FAIL);
                    }
                }
    
            }
    //        for (String s : Reporter.getOutput()) {
    //            extent.setTestRunnerOutput(s);
    //        }
    
            extent.flush();
        }
    
        private void init() {
            //文件夹不存在的话进行创建
            File reportDir= new File(OUTPUT_FOLDER);
            if(!reportDir.exists()&& !reportDir .isDirectory()){
                reportDir.mkdir();
            }
            ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter(OUTPUT_FOLDER + FILE_NAME);
            // 设置静态文件的DNS
            //怎么样解决cdn.rawgit.com访问不了的情况
            htmlReporter.config().setResourceCDN(ResourceCDN.EXTENTREPORTS);
    
            htmlReporter.config().setDocumentTitle("api自动化测试报告");
            htmlReporter.config().setReportName("api自动化测试报告");
            htmlReporter.config().setChartVisibilityOnOpen(true);
            htmlReporter.config().setTestViewChartLocation(ChartLocation.TOP);
            htmlReporter.config().setTheme(Theme.STANDARD);
            htmlReporter.config().setCSS(".node.level-1  ul{ display:none;} .node.level-1.active ul{display:block;}");
            extent = new ExtentReports();
            extent.attachReporter(htmlReporter);
            extent.setReportUsesManualConfiguration(true);
        }
    
        private void buildTestNodes(ExtentTest extenttest, IResultMap tests, Status status) {
            //存在父节点时,获取父节点的标签
            String[] categories=new String[0];
            if(extenttest != null ){
                List<TestAttribute> categoryList = extenttest.getModel().getCategoryContext().getAll();
                categories = new String[categoryList.size()];
                for(int index=0;index<categoryList.size();index++){
                    categories[index] = categoryList.get(index).getName();
                }
            }
    
            ExtentTest test;
    
            if (tests.size() > 0) {
                //调整用例排序,按时间排序
                Set<ITestResult> treeSet = new TreeSet<ITestResult>(new Comparator<ITestResult>() {
                    @Override
                    public int compare(ITestResult o1, ITestResult o2) {
                        return o1.getStartMillis()<o2.getStartMillis()?-1:1;
                    }
                });
                treeSet.addAll(tests.getAllResults());
                for (ITestResult result : treeSet) {
                    Object[] parameters = result.getParameters();
                    String name="";
                    //如果有参数,则使用参数的toString组合代替报告中的name
                    for(Object param:parameters){
                        name+=param.toString();
                    }
                    if(name.length()>0){
                        if(name.length()>50){
                            name= name.substring(0,49)+"...";
                        }
                    }else{
                        name = result.getMethod().getMethodName();
                    }
                    if(extenttest==null){
                        test = extent.createTest(name);
                    }else{
                        //作为子节点进行创建时,设置同父节点的标签一致,便于报告检索。
                        test = extenttest.createNode(name).assignCategory(categories);
                    }
                    //test.getModel().setDescription(description.toString());
                    //test = extent.createTest(result.getMethod().getMethodName());
                    for (String group : result.getMethod().getGroups())
                        test.assignCategory(group);
    
                    List<String> outputList = Reporter.getOutput(result);
                    for(String output:outputList){
                        //将用例的log输出报告中
                        test.debug(output);
                    }
                    if (result.getThrowable() != null) {
                        test.log(status, result.getThrowable());
                    }
                    else {
                        test.log(status, "Test " + status.toString().toLowerCase() + "ed");
                    }
    
                    test.getModel().setStartTime(getTime(result.getStartMillis()));
                    test.getModel().setEndTime(getTime(result.getEndMillis()));
                }
            }
        }
    
        private Date getTime(long millis) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(millis);
            return calendar.getTime();
        }
    }
    

    3.3 utils层: 抽取公用的方法ConfigFile类+DatabaseUtil类

    3.3.1 ConfigFile类:对各个测试用例的URL进行赋值

    package com.tester.utils;
    
    import com.tester.model.InterfaceName;
    
    import java.util.Locale;
    import java.util.ResourceBundle;
    
    public class ConfigFile {
        public static ResourceBundle bundle=ResourceBundle.getBundle("application", Locale.CHINA);
        public static String getUrl(InterfaceName name){
            String address=bundle.getString("test.url");
            String uri="";
            String testUrl;
         
            if(name==InterfaceName.LOGIN){
                uri=bundle.getString("login.uri");
            }
            
            testUrl=address+uri;
            return testUrl;
        }
    }
    

    3.3.2 DatabaseUtil类:配置一个getSqlSession()方法

    作用是执行配置文件SQLMapper中的SQL语句

    package com.tester.utils;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.IOException;
    import java.io.Reader;
    
    public class DatabaseUtil {
        public static SqlSession getSqlSession() throws IOException {
            //获取配置的资源文件
            Reader reader= Resources.getResourceAsReader("databaseConfig.xml");
            //得到SqlSessionFactory,使用类加载器加载xml文件
            SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(reader);
            //得到sqlsession对象,这个对象就能执行配置文件中的sql语句啦
            SqlSession session=factory.openSession();
            return session;
        }
    }
    

    3.4 cases层:用来放接口的测试用例

    package com.tester.cases;
    
    import com.tester.config.TestConfig;
    import com.tester.model.InterfaceName;
    import com.tester.model.LoginCase;
    import com.tester.utils.ConfigFile;
    import com.tester.utils.DatabaseUtil;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.methods.HttpPost;
    import org.apache.http.entity.StringEntity;
    import org.apache.http.impl.client.DefaultHttpClient;
    import org.apache.http.util.EntityUtils;
    import org.apache.ibatis.session.SqlSession;
    import org.json.JSONObject;
    import org.testng.Assert;
    import org.testng.annotations.BeforeTest;
    import org.testng.annotations.Test;
    
    import java.io.IOException;
    
    public class LoginTest {
        @BeforeTest(groups = "loginTrue",description = "测试准备工作,获取HttpClient对象")
        public void beforeTest(){
            TestConfig.getUserInfoUrl= ConfigFile.getUrl(InterfaceName.GETUSERINFO);
            TestConfig.getUserListUrl=ConfigFile.getUrl(InterfaceName.GETUSERLIST);
            TestConfig.addUserUrl=ConfigFile.getUrl(InterfaceName.ADDUSERINFO);
            TestConfig.loginUrl=ConfigFile.getUrl(InterfaceName.LOGIN);
            TestConfig.updateUserInfoUrl=ConfigFile.getUrl(InterfaceName.UPDATEUSERINFO);
    
            TestConfig.defaultHttpClient=new DefaultHttpClient();
        }
    
        @Test(groups = "loginTrue",description = "用户成功登陆接口")
        public void loginTrue() throws IOException {
            SqlSession session= DatabaseUtil.getSqlSession();
            LoginCase loginCase=session.selectOne("loginCase",1);
            System.out.println(loginCase.toString());
            System.out.println(TestConfig.loginUrl);
    
            //下边的代码为写完接口的测试代码
            String result=getResult(loginCase);
            //处理结果,就是判断返回结果是否符合预期
            Assert.assertEquals(loginCase.getExpected(),result);
        }
    
    
    
        @Test(groups = "loginFalse",description = "用户登录接口失败")
        public void loginFalse() throws IOException {
            SqlSession session=DatabaseUtil.getSqlSession();
            LoginCase loginCase=session.selectOne("loginCase",2);
            System.out.println(loginCase.toString());
            System.out.println(TestConfig.loginUrl);
    
            //下边的代码为写完接口的测试代码
            String result=getResult(loginCase);
            //处理结果,就是判断返回结果是否符合预期
            Assert.assertEquals(loginCase.getExpected(),result);
        }
    
        private String getResult(LoginCase loginCase) throws IOException {
            //下边的代码为写完接口的测试代码
            HttpPost post=new HttpPost(TestConfig.loginUrl);
            JSONObject param=new JSONObject();
            param.put("userName",loginCase.getUserName());
            param.put("password",loginCase.getPassword());
            //设置请求头信息,设置header
            post.setHeader("content-type","application/json");
            //将参数信息添加到方法中
            StringEntity entity=new StringEntity(param.toString(),"utf-8");
            post.setEntity(entity);
            //声明一个对象来进行响应结果的存储
            String result;
            //执行post方法
            HttpResponse response=TestConfig.defaultHttpClient.execute(post);
            //获取响应结果
            result= EntityUtils.toString(response.getEntity(),"utf-8");
            System.out.println(result);
    
            TestConfig.store=TestConfig.defaultHttpClient.getCookieStore();
            return result;
        }
    }
    
    展开全文
  • java接口自动化.txt

    2020-02-18 18:38:24
    第01章 接口自动化测试整体认知 第02章 接口测试的用例设计 第03章 手工接口测试到自动化框架设计 第04章 企业级代码管理工具git的应用 第05章 测试框架TestNG 第06章 测试报告 第07章 Mock接口框架的应用实战...
  • 接口自动化框架

    2018-03-23 22:35:56
    接口自动化源码
  • 一些场景必须登录后才可以使用,这就需要在后续的接口中使用登录后产生的session,本章主要介绍如何获取session,及把参数传递到其他的接口中;我的接口是查询接口,无参数 一、登录需要的参数 package ...

    使用场景:

    一些场景必须登录后才可以使用,这就需要在后续的接口中使用登录后产生的session,本章主要介绍如何获取session,及把参数传递到其他的接口中;我的接口是查询接口,无参数

    一、登录需要的参数

    package com.qa.parameters;
    public class Manager {
        private String account;
        private String loginPwd;
        private String partnerCode;
        
        public Manager(){
            
        }
        
        public Manager(String account,String loginPwd,String partnerCode){
            super();
            this.loginPwd=loginPwd;
            this.account=account;
            this.partnerCode=partnerCode;
        }
        
        public String getAccount() {
            return account;
        }
        public void setAccount(String account) {
            this.account = account;
        }
        public String getLoginPwd() {
            return loginPwd;
        }
        public void setLoginPwd(String loginPwd) {
            this.loginPwd = loginPwd;
        }
        public String getPartnerCode() {
            return partnerCode;
        }
        public void setPartnerCode(String partnerCode) {
            this.partnerCode = partnerCode;
        } 
    }

    二、在base类中定义session,我把他放在此处的想法是因为后续的test类都需要继承此类,若在此定义了即为全局变量,后续只要使用到session的地方可以直接使用;把登录也放到此类也是这种想法

    package com.qa.base;
    import java.io.IOException;
    import java.util.Map;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.util.EntityUtils;
    import org.testng.Assert;
    import org.testng.annotations.BeforeClass;
    import org.testng.annotations.Test;
    import com.alibaba.fastjson.JSONObject;
    import com.qa.parameters.Manager;
    import com.qa.restclient.RestClient;
    import com.qa.utils.PropertiesUtils;
    import com.qa.utils.fatjson.FastjsonUtils;
    
    /**
     * 该类可以当成所有测试类的模板基类,其他需要测试的类继承该类
     * session,token等需要全局使用的均需要在此类中进行定义;若测试需要登录可在本类进行登录
     * @author jff
     * @date 2018年9月25日
     * @version V1.0.1
     */
    public abstract class BaseApi {
        protected String hostManager;
        protected static String sessionKey;
        
        @BeforeClass
        public void setUp() {
            hostManager=PropertiesUtils.getConfigValue("HOSTMANAGER");        
        }
        
        //由于登陆后后面的接口需要使用它的返回值,所以提取到此类,以后的测试类只需继承,添加依赖即可
        @Test
        public void loginManagerAppTestd() throws ClientProtocolException, IOException{
    
            String url=hostManager+"/parkingManager/applogin/loginIn";
    
            Manager manager = new Manager("yanczapp","8ddcff3a80f4189ca1c9d4d902c3c909","0571001");
            Map<String, String> map=FastjsonUtils.toMap(FastjsonUtils.toJson(manager));
            System.out.println("my out**********"+map);
            CloseableHttpResponse closeableHttpResponse = RestClient.postForm(url, map, null);
            
            //断言状态码是不是200
            int statusCode = closeableHttpResponse.getStatusLine().getStatusCode();
            Assert.assertEquals(statusCode,Constants.RESPNSE_STATUS_CODE_200,"status code is not 200");
        
            //断言响应json内容中name和job是不是期待结果
            String responseString = EntityUtils.toString(closeableHttpResponse.getEntity());
            System.out.println("my out**********"+responseString);
            JSONObject res = FastjsonUtils.toJsonObject(responseString);
    
             //提取session,并把它赋值给sessionkey,sessionKey 作为全局变量其他接口可以直接使用
            sessionKey = FastjsonUtils.toMap(res.getString("data")).get("session_key");
            System.out.println("data**********: " + res.getString("message"));
            System.out.println("data**********: " + sessionKey);
            
            String account=FastjsonUtils.toMap(res.getString("data")).get("account");
            Assert.assertEquals(account,"yanczapp" ,"account code is not error");
        }
    }

    三、config.properties

    HOSTMANAGER=http://111.aaa.cn

     

    四、编写测试类,这个需要添加一个依赖,依赖登录接口,意思就是说登录接口成功后此用例才能执行

    添加dependsOnMethods即可

    package manager;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    import org.apache.http.client.ClientProtocolException;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.util.EntityUtils;
    import org.apache.log4j.Logger;
    import org.testng.Assert;
    import org.testng.annotations.Test;
    import com.alibaba.fastjson.JSONObject;
    import com.qa.base.BaseApi;
    import com.qa.base.Constants;
    import com.qa.restclient.RestClient;
    import com.qa.utils.fatjson.FastjsonUtils;
    
    public class LoginManagerAppTest2 extends BaseApi{
        private final static Logger Log=Logger.getLogger(LoginManagerAppTest2.class);
      
        //依赖那个方法,如果依赖多个方法可使用逗号分隔loginManagerAppTestd,loginManagerApp
        @Test(dependsOnMethods = {"loginManagerAppTestd"})
        public void query() throws ClientProtocolException, IOException {
            String url=hostManager+"/parkingManager/apprecovered/querySumOrderAmountByCondition";
            
            
            Map<String, String> headers = new HashMap<String, String>();
            headers.put("token", "aaaa");
            
            Map<String, String> params = new HashMap<String, String>();
            params.put("session_key", sessionKey);
            CloseableHttpResponse closeableHttpResponse = RestClient.postForm(url, params, headers);
            
            //断言响应是不是期待结果
            String responseString = EntityUtils.toString(closeableHttpResponse.getEntity());
            Log.info("my out**********"+responseString);
            JSONObject res1  = FastjsonUtils.toJsonObject(responseString);
            Log.info("code**********: " + res1.getString("code"));
            
            //断言状态码是不是200
            int statusCode = RestClient.getStatusCode(closeableHttpResponse);
            Assert.assertEquals(statusCode,Constants.RESPNSE_STATUS_CODE_200,"status code is not 200");
        }  
    }
    

     

    展开全文
  • Java接口自动化测试框架设计-1-开发环境的搭建

    万次阅读 多人点赞 2018-05-21 23:58:05
    废话不多说,刚开始,尽量详细,通过一步一步,手把手教会你搭建接口自动化测试的基础项目环境。 一.前提条件 我这里来一个约定,有以下前提条件。1.本机环境安装了maven并配置环境变量2.本机环境安装了Eclipse...

          本篇作为这个系列第一篇,主要介绍基础环境搭建过程。废话不多说,刚开始,尽量详细,通过一步一步,手把手教会你搭建接口自动化测试的基础项目环境。

     

    一.前提条件

     

    我这里来一个约定,有以下前提条件。

    1.本机环境安装了maven并配置环境变量

    2.本机环境安装了Eclipse软件

    3.本机环境安装了Java jdk 8版本

    4.本机需要能连接上互联网

     

           我这里还是选择了Eclipse,当然如果你有IntellijIDEA,当然也可以,我以下截图都是以Eclipse软件界面为准。如果没有接触过maven,不知道如何安装环境,请参考我这篇文章:https://blog.csdn.net/u011541946/article/details/78085989

     

    二.Eclipse上创建一个Maven工程

     

    在Eclipse中,点击File-new-project,选择Maven Project,如下图。


    点击多次Next按钮,直到出现下面界面。

     

           参考上面红圈位置,填写Group Id和Artifact Id,其中Artifact Id在Eclipse中反映出来就是项目名称,点击Finish按钮,Eclipse中新建的项目结构如下图。

     

           把main和test下包和相关class文件(自动生成的)删除,因为我们接下来不使用Junit,而是使用TestNG, 如果删除,后面我们编辑pom.xml的时候会报错。找到下面图红圈,删除这两个包。


    删除之后,test和main下都是空的文件结构。


    接下来,我们就编辑pom.xml,并添加一些我们需要的第三方插件lib的依赖和引用。

     

    三.添加必要的组件依赖

     

    在maven项目下,找到pom.xml文件,右键,打开方式选择记事本。


           我们先把junit的maven依赖给删除,然后这里,我们举例添加httpclient,因为我们需要做基于Java语言的接口自动化测试,httpclient和httpcore这两个是主要的组件。通过学习如何添加httpclient过程,其他的lib包就参考就能学会。

     

    1)打开浏览器,打开百度,搜索httpclient maven


    上面两个链接都可以,这里我选择第二个链接打开。

    2)点击第二个链接


    把上面红圈的文本内容复制到Eclipse项目中的pom.xml文件,添加之后如下效果。


    3)在Eclipse上的pom.xml,按下ctrl+s,保存之后,会发现依赖包自动下载到本地


    只要在pom.xml文件中输入正确的组件依赖文本内容,保存之后自动下载相关依赖包到本地(红圈位置)

    4)依次添加其他组件

    从上面httpclient组件添加过程,我们学会了一个基于mava依赖的组件添加到本地工程的过程,下面我们需要添加httpcore, testing, fastjson


         Httpcore主要是网络相关的组件,我们使用Http请求就需要网络相关底层方法。Testng主要是取代junit,是一个单元测试框架,方便我们编写接口自动化用例。Fastjson是阿里巴巴的一个json的开源的组件,据说是最快的json的组件,主要用来json序列化和反序列操作。

         到这里,我们就把基础的开发环境给搭建好了,接下来我们写一个Get请求的过程。

     

    展开全文
  • 这个接口自动化测试框架到目前为止,我们已经完成了Get请求的封装和必要的工具类的支持。...所以,这个Java接口自动化测试框架的核心就是Get和POST请求方法的封装过程。 1.POST接口举例浏览器打开https://re...
  • Java接口自动化测试框架学习(三)

    万次阅读 多人点赞 2018-09-14 16:53:32
    前面项目已创建好,依赖包添加完成,testng也已添加 项目结构如下: 1.设计配置文件 在src/main/java下新建一个包:...然后在src/main/java下新建一个包:com.qa.base,新建一个TestBase.java,这个...
  • 通过testng.xml生成extentreport测试报告 一、说明: 使用TestNg的Report监听器,不嵌入具体执行代码,仅需在配置文件中新增监听器即可。 ...(可在代码中修改) 一个suite且一个test配置的情况下,会将执行的用例...
  • 接口自动化测试框架搭建

    千次阅读 2021-03-08 23:07:00
    一、原理及特点参数放在XML文件中进行管理用httpClient简单封装一个httpUtils工具类测试用例管理使用了testNg管理,使用了TestNG参数测试,通过xml文件来执行case。测试报告这里用到第三方的包ReportNG 项目组织用...
  • Java接口自动化测试框架设计-2-Get请求方法和测试

    万次阅读 多人点赞 2018-05-22 00:11:42
    这篇开始,我来介绍通过代码逐步实现接口自动化测试框架的设计过程。先不要着急,框架设计我们只是介绍基本的组件,而且框架设计没有想象那么难,一步一步跟着做就会了。这篇我们来演示,如果通过Java代码来实现一个...
  • 所以,对于即将开始的http接口测试需求,立马花了两天时间搭建了一个http接口自动化测试框架用于测试后期回归测试,实在是被大量的重复手工执行搞怕了。最方便的方法就是用python直接写代码,代码和测试数据分离,...
  • Java接口自动化测试框架学习(一)

    万次阅读 2018-08-14 16:58:48
    3.本机环境安装了Java jdk 8版本 maven环境的安装: 1.下载Maven http://maven.apache.org/download.cgi 2.配置环境变量 2.1解压至C盘 2.2打开环境配置,如下: 2.3配置路径,Maven官网说,可以配置一...
  • 前面说过了,如果你稍微懂得TestNG这个单元测试框架,到目前这个简单的Java接口自动化测试框架主体的骨架部分已经完成设计并实现。这篇,继前篇的基础上,把测试用例中获取响应状态码和响应数据转换成JSON格式这些...
  • E:\最全面的Java接口自动化测试实战\第3章 手工接口测试到自动化框架设计 E:\最全面的Java接口自动化测试实战\第4章 企业级代码管理工具git的应用 E:\最全面的Java接口自动化测试实战\第5章 测试框架TestNG E:\最...
  • 最近比较忙,在抽时间写练习的demo及优化,请大家耐心等待 ...不需要写代码的自动化框架 自动化测试框架: JMeter + Ant + Jenkins【 windows 版】:https://www.cnblogs.com/UncleYong/p/10739519.html...
  • Post类型的接口通常有请求参数,请求参数也是json类型,所以需要写一个类将请求参数序列成json对象 以常见的登录接口为例 新建一个package,和postParameters类   package com.qa.Parameters; public ...
  • java接口自动化测试源码 , 技术问题qq群:524212543 , 版本更新 v2.3 2018/01/28 增加发送邮件服务器配置项,修复终端乱码 v2.2 2018/01/20 更新说明文件和democase v2.1 2018/01/09 更新最新chromewebdriver解决...
  • 个人觉得这个工具比任何自动化测试框架都好使,使用关键字和数据双驱动,不需要写一行代码,无需维护脚本,只需要维护用例数据。Web元素只需要在Chrome中复制xPath即可,定位非常高效。 工具安全无木马,目的只为...
  • 手把手教你搭建java接口自动化测试框架(三):基础代码填充 手把手教你搭建java接口自动化测试框架(三):基础代码填充 base包下新建TestBase.java package com.qa.base; import java.io.FileInputStream; ...
  • 前言:目前Mock技术已经比较成熟,在日常的工作中Mock也可以给我们带来很大的遍历,本篇文章将会使用Moco框架,一步一步搭建一套Mock Server,使得接口自动化测试更加的提前,也能够使得前后端分离。 共识与痛点...
  • 接口自动化框架实践】1、IDEA + TestNG + Maven + spring接口自动化框架搭建 1、打开idea开发工具,在菜单栏选择File–>New–>Project…–>Maven,直接点击next 2、输入artifactId、artifactId以及...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 282,694
精华内容 113,077
关键字:

java接口自动化框架

java 订阅
友情链接: cpp11_thread-master.zip