经常,在应用程序的业务逻辑中存在大量的这样的接口:他们接受不同的输入,然后进行或验证,或处理,进而完成相同的流程。比如网站的登录入口,用户名和密码都有长度的限制,同时也具有是否允许特殊字符的限制等,所以在我们进行其单元测试的过程中,根据不同长度的用户名和密码,以及不同的字符组合,只需要提供相同的测试代码结构,就能完成测试,不同的仅仅测试数据与期望值,但是因为每一个测试方法中的输入参数不同,我们必须为每一个输入组编写单独的测试用例,从而产生大量冗余代码,十分不便于维护。幸好,本文所述的 Feed4JUnit 良好的解决了数据与代码分离的问题,Feed4JUnit是 JUnit测试框架的扩展,它通过操作来自于文件以及不同的数据源的测试数据,使您的单元测试变得更容易编写与维护。

使用工具

Eclipse+Java+httpclient+feed4junit+Junit4

二、Feed4JUnit 的下载及安装

1. Feed4JUnit 是开源的测试组件,您可以从如下链接下载最新版本:

http://sourceforge.net/projects/feed4junit/files/

2. 解压下载的 zip包,复制整个 lib文件夹到您的 Java项目的根目录,如图 1:

图 1. 复制 lib 到项目根目录

3. 选定项目,右键选择项目的属性,然后通过 Add JARs将步骤 2中 lib 文件夹下的所有 Jar添加到项目的 BuildPath下,如图2

图 2. 添加 Jar 到 Build Path

三、使用 Feed4JUnit 实现数据与代码分离的测试

Feed4JUnit 的数据源可以包括以下几种类型-文件 (CSV或者Excel )、数据库、自定义数据源。

Feed4JUnit使用一个特殊的运行类Feeder.class,用来支持与标识参数化测试,如果您想要编写数据与代码分离的测试脚本,必须在您的测试类上增加注释@RunWith(Feeder.class)。同时,您需要使用@Test来标示您实现测试的方法,并且使用@Source来声明和接收数据源的数据,基本的代码结构如清单3所示:

清单 3. 测试代码结构

package Living;

import static org.junit.Assert.*;

import org.databene.benerator.anno.InvocationCount;

import org.databene.benerator.anno.Source;

import org.junit.After;

import org.junit.AfterClass;

import org.junit.Before;

import org.junit.BeforeClass;

import org.junit.Test;

import org.junit.runner.RunWith;

import Pub.LivingPub;

import org.databene.feed4junit.Feeder;

@RunWith(Feeder.class)

public class PushTest{

@BeforeClass

public static void setUpBeforeClass()throws Exception {

}

@AfterClass

public static void tearDownAfterClass()throws Exception {

}

@Before

public void setUp() throws Exception {

}

@After

public void tearDown() throws Exception {

}

@Test

//  @InvocationCount(1) //指定测试的次数

@Source("D:/data/Living/push.xlsx")//指定测试的数据源

public void pushTest(String cases,StringclassroomId,Stringname,

String loginToken,StringquestionUrl,StringquestionId,Stringcorrect,

String courseLevelId,Stringanswers,booleanexpected) {

assertEquals(expected, LivingPub.push(cases,classroomId,name,loginToken,questionUrl,questionId,correct,courseLevelId,answers));

}

}

以文件作为数据源

Feed4JUnit支持从 CSV或者 Excel文件里面读取数据作为输入,这里我们以Excel文件为例。

1. 在D:/data/Living/目录下创建push.xlsx数据文件,样例数据如图3,默认情况下,第一行会以列名存在,在运行过程中不会作为数据读取。

图 3. Excel 数据源

2. 创建测试类并在接收数据的测试方法上声明数据源为@Source("D:/data/Living/push.xlsx"),Excel中的数据在传递过程中会自动按照列与测试方法的参数的位置顺序进行匹配,并以行作为一个单位读取并传递给测试方法体。比如图3中的 cases列的值会做为方法的第一个参数传入方法体中,classroomId列的值会作为方法的第二个参数,以此类推。在测试进行过程中,首先在Excel文件中读取一行(包含三列),接着按照位置顺序将数据传递到方法体中(每列按顺序对应一个参数)进行执行,执行完成后读取Excel中的下一行进行相同流程的测试,其原理与Java中的迭代器十分类似。请注意当数据文件中数据的列数小于测试方法参数的个数的时候,测试会因为位置不匹配而失败。

3. 运行测试,因为 Feed4Junit是 JUnit的扩展,所以运行方式与 JUnit完全相同,即以 JUnit运行即可,运行结果如图 4所示,我们可以看到,Data.xls中的数据已全部传入测试方法并运行。

图 4. 运行结果示例

四、测试公共类及http模拟客户端实现

接口请求公共类及http模拟客户端:

1、 接口请求公共类代码:

public static boolean  push(String cases,String classroomId,String name,
String loginToken,String questionUrl,String questionId,String correct,
String courseLevelId,String answers) {
String url="xxxx";
Map<String, String> headers=new HashMap<String,String>();
Map<String, String> params=new HashMap<String,String>();
params.put("classroomId", classroomId);
params.put("name", name);
params.put("loginToken", loginToken);
JSONObject question=new JSONObject();
question.put("questionUrl", questionUrl);
question.put("questionId", questionId);
question.put("correct", correct);
question.put("courseLevelId", courseLevelId);
question.put("answers", answers);
params.put("question", question.toString());
String responseContent = PublicClient.getInstance().sendHttpGet(url, params,headers);
System.out.println(cases+"result:" + responseContent); 
JSONObject js=JSONObject.fromObject(responseContent);
String rscode=js.getString("code");
System.out.println(rscode);
//判断返回值
if (rscode.equals("10001"))
return false;
if (rscode.equals("10101"))
return false;
if (rscode.equals("10002"))
return false;
if (rscode.equals("10103"))
return false;
if (rscode.equals("10102"))
return false;
if (rscode.equals("10104"))
return false;
if (rscode.equals("11001"))
return false;
if (rscode.equals("11002"))
return false;
if (rscode.equals("999999"))
return false;
return true;
}

2、 模拟客户端代码:

public String sendHttpGet(String httpUrl,Map<String, String> params,Map<String, String> Headers) { 
// StringBuffer param = new StringBuffer();  
//        int i = 0;  
        if(params != null && !params.isEmpty()){
List<NameValuePair> pairs = new ArrayList<NameValuePair>(params.size());
for(Map.Entry<String,String> entry : params.entrySet()){
String value = entry.getValue();
if(value != null){
pairs.add(new BasicNameValuePair(entry.getKey(),value));
}else {
pairs.add(new BasicNameValuePair(entry.getKey(),""));
}
}
try {
httpUrl += "?" + EntityUtils.toString(new UrlEncodedFormEntity(pairs, "UTF-8"));
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
HttpGet httpGet = new HttpGet(httpUrl);
   if (Headers != null && !Headers.isEmpty()) {  
            for (Entry<String, String> entry : Headers.entrySet()) {  
            // 排除掉空值 
                if (entry.getValue() != null) {  
                httpGet.addHeader(entry.getKey(), entry.getValue()  
                            .toString());  
                } else {
                httpGet.setHeader(entry.getKey(), ""); 

            }  
        }
return sendHttpGet(httpGet);
}

/**
* 发送Get请求
* @param httpGet
* @return
*/
private String sendHttpGet(HttpGet httpGet) {
CloseableHttpClient httpClient = null;
CloseableHttpResponse response = null;
HttpEntity entity = null;
String responseContent = null;
try {
// 创建默认的httpClient实例.
httpClient = HttpClients.createDefault();
httpGet.setConfig(requestConfig);
// 执行请求
response = httpClient.execute(httpGet);
entity = response.getEntity();
responseContent = EntityUtils.toString(entity, "UTF-8");
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
// 关闭连接,释放资源
if (response != null) {
response.close();
}
if (httpClient != null) {
httpClient.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return responseContent;
}

接口测试自动化框架搭建相关推荐

  1. 4个步骤,搭建接口测试自动化框架

    背景 在上一篇文章中,我们回顾了当前主流的几种接口测试自动化框架.今天将分享如何通过4个步骤,自己搭建一套完整的接口测试自动化框架. 搭建框架四部曲 框架的第一步 搭建框架的第一步是根据我们选择的自动 ...

  2. Java+Rest-Assrued+Gradle+Allure搭建接口测试自动化框架

    背景 上一篇<4个步骤,搭建接口测试自动化框架>我分享了如何搭建接口测试自动化框架的理论部分,今天我们就利用Java+Rest-Assrued+Gradle+Allure来搭建一个完整的接 ...

  3. 接口测试自动化框架汇总

    背景 前两篇文章我们介绍了如何使用Postman和cURL手工执行接口测试用例,不过如果项目需要长期开发和维护的话,我们就需要开始考虑自动化测试了.自动化测试第一步就是框架选型.所以本篇将介绍目前主流 ...

  4. 【App自动化框架搭建流程及其思路】

    App自动化框架搭建流程 之前公司我所在的业务是关于sdk的一些业务,为了缓解我们sdk组的功能测试大量重复性业务.我搭建了一套App自动化框架,现已投入日常的使用.这篇文章简单的介绍下我这个App自 ...

  5. pytest接口自动化框架搭建

    目录: 一.设计思路-整体框架: 二.具体框架搭建 1.公共方法-common 1.1.yaml_util.py 1.2.excel_util.py 1.4.text_ util.py 1.5.exc ...

  6. python自动化(五)接口自动化:4.接口自动化框架搭建实战

    一.业务分析 我们这里以企业微信的添加成员业务为例,来讲解我们的自动化测试框架. 企业微信接口文档:https://work.weixin.qq.com/api/doc/90000/90135/901 ...

  7. 自动化框架搭建面试题

    面试 1.接口自动化和web自动化有多少case ?覆盖率是多少?全部执行完需要多久? 2.接口自动化测试怎么做? web自动化测试怎么做? 3.什么是POM模式?为什么要使用它? 4.说说你对数据驱 ...

  8. Web UI自动化框架搭建

    本篇博文只从项目架构角度,提供一些建议供参考.不涉及具体代码编写.目前市场上主流的免费开源工具就是Selenium.大家可以根据自己项目技术栈,选择合适的语言+外加Unit Test框架,来构建自己的 ...

  9. Appnium(三)企业微信UI自动化框架搭建

    前言 本章主要讲述针对[企业微信App]进行AppUI自动化测试框架的搭建 ps:这里底层用的是Appnium,另外写了一下底层Uiautomator2的简单搭建 UIautomator2框架搭建实战 ...

最新文章

  1. laravel多种安装方法
  2. 为什么要 conda 作用_烤箱预热有什么作用?为什么烘焙一定要预热烤箱?怎么正确预热?...
  3. 苹果平板买哪款最好?
  4. freemarker取数
  5. js 使用replace替换、全部替换、替换动态数据方法
  6. netty实战-概述
  7. 计算机复制教程,介绍几款常用的屏幕拷贝工具,快速抓取电脑画面
  8. pytorch转onnx报错的可能原因traced region did not have observable data dependence
  9. 一键部署k8s集群(三节点)
  10. 在Groovy中使用字符串
  11. 用python画分析曲线图
  12. 高德地图ar步行导航使用教程分享
  13. 一些英文网站,字幕下载网站
  14. No.14 交易平台初探【交易平台系列①】
  15. linux kernel有线网卡驱动enc28j60分析 一
  16. [Revit教程]斑马:如何自学Revit#S002
  17. 游戏开发存档版本号的妙用
  18. HTML5-布局篇( 总结 )
  19. imx8qxp正常倒车
  20. 物联网技术的发展趋势

热门文章

  1. oracle 添加外键,报“未找到父项关键字”
  2. linux之删除vi残留的swp文件
  3. docker简单介绍----存储
  4. 《精通软件性能测试与LoadRunner最佳实战》—第1章1.1节软件测试基础
  5. Office 365 Sway-移动设备推送利器
  6. cocos2d-x 观察者模式
  7. 免费资源下载:暗色色系的超棒搜索框和下拉菜单UI欣赏
  8. 汽车系统实现--搜索功能
  9. Packt发布了2018年技能提升报告
  10. 图片 和 base64 互转