基于 Junit 的接口自动化测试框架实现

news2024/11/27 10:39:27

目录

前言:

分层的自动化测试

接口测试的意义

接口测试框架选型

我们封装的接口测试框架

接口测试关键实践

测试代码规范 (仅供参考)


前言:

基于JUnit的接口自动化测试框架可以实现对接口进行自动化测试,并提供了丰富的断言和报告功能。JUnit是一个流行的Java单元测试框架,它可以帮助开发者编写可重复执行的测试用例,并进行测试结果的验证。

分层的自动化测试

5~10 年前,我们接触的自动化测试更关注的是 UI 层的自动化测试,Mercury 的 WinRunner/QTP 是那个时代商业性自动化测试产品的典型代表,在那个时代大家单纯想的都是能用一个自动化操作的工具替代人力的点击,商业化或是私有化框架大行其道。
而分层的自动化测试倡导产品的不同阶段(层次)都需要自动化测试。在《google 软件测试之道》中,在 google 70% 的投入为单元测试(小型测试),20% 为接口/集成测试(中型测试),10% 为 UI 层的自动化测试(大型测试),也就是大家熟悉的金字塔模型,越往上自动化实现难度越大,投入产生的收益也越低(需要强调的是,UI 层的自动化测试作为最接近用户操作的测试,仍然有其存在的意义和场景)。

接口测试的意义

接口测试是验证两个或多个模块应用之间的交互(通常是采用接口的方式),测试的重点是要检查数据的交换,传递和控制管理过程,还包括处理的次数。
接口测试的核心战略在于:以保证系统的正确和稳定为核心,以持续集成为手段,提高测试效率,提升用户体验,降低产品研发成本。
接口测试要为代码的编写保驾护航,增强开发人员和测试人员的自信,让隐含的 BUG 提前暴露出来,要让开发人员在第一时间修复 BUG,要让业务测试人员在测试的时候更加顺手,最大限度得减少底层 BUG 的出现数量,要让产品研发的流程更加敏捷,要缩短产品的研发周期,最后在产品上线以后,要让用户用得更加顺畅,要让用户感觉产品服务零缺陷。
不同于单元测试,接口测试本质上还是一种黑盒的测试,所以非常适合专职测试工程师去参与和覆盖。

接口测试框架选型

1.目前接口测试框架的选型,最常见的方法是采用 jmeter,soapUI,postman,robotframework 等 UI 化的接口测试框架来做。
好处是业务测试人员可以不用或很少写测试代码,入门门槛低,前几年有很多公司都曾经开发过类似的测试框架,有前端有后端,专职的测试开发人员维护,业务测试人员只需要知道怎么操作而不需要参与具体 coding。
这种方法看起来非常高大上,但实际的问题是执行过程中主要的工作变成了测试框架的维护,非常依赖专职测试开发人员的设计和开发能力,每增加一种新的接口协议(比如 dubbo、hessian 或者内部自定义的协议)就需要在框架上增加支持;更致命的是一旦核心测试开发人员出现流动,就很容易造成整个接口测试体系的崩塌;另外对业务测试人员的技能成长也并不公平,个人已面试过太多只会使用某大公司 XXX 测试框架却完全不了解具体实现方式的工程师。
《google 软件测试之道》中早已有过预言,保密和私有化的基础测试设施并不能获得想象中的好处,这种方式意味着昂贵和迟缓,即使在公司内部的不同项目之间也很难做到复用。未来的测试基础设施必然是建立在共享代码和开源框架的基础上,测试开发人员需要更多的利用开源项目并为之贡献。
最近重读了一次这本四五年前几乎改变软件测试行业的书籍,发现里面的预言都是如此准确,当然也可以认为国内整个行业都正参照 google 的方式在进行演变。


2.使用 junit、testng 等 java 接口框架,直接编写测试代码去测试,同时对一些重复性的工作抽象建立基础库或方法。
有点类似于单元测试,这种方法扩展性好实现灵活,作为程序员可以用代码实现灵活的场景组织和功能,只要稍微二次开发一下,但需要测试工程师有一定的编码基础。 
这种方式在前几年实施的难度还是比较大,因为在市场上要找到懂 java 代码的测试工程师都寥寥无几,但在对测试工程师开发能力要求越来越多的今天实施难度已没有想象中困难,java/python 等语言的编码能力也已成为我们团队招聘时的基本要求。
另外提下,这里使用 java 而不用其他语言的原因,主要是团队的技术储备 java 是强项,拥有丰富的开源测试库,而且一般互联网公司的产品基本都是采用 java 框架进行开发,和开发团队技术栈保持一致非常有必要性。

我们封装的接口测试框架

有很多公司做了各种不同的接口框架,都是基于自己公司的业务基础设计开发。我们基于自己的业务特点(为避免广告嫌疑,尽量我不提及具体公司的信息),也封装了自己的接口测试框架 gtest-framework,在开发人员的单元测试中也正逐渐使用。
gtest-framework 要做的事情:
1.前置数据准备和自动清理。
2.常见接口协议的实现和封装。
3.依赖注入配置方式的支持。
4.如文件、图片、xml、字符等各类通用处理方法的集成。
5.断言方式的扩展等。

接口测试关键实践

1.数据准备
接口测试的数据准备,一般是指数据库的数据准备,有时候还包括文件和缓存的数据准备。具体实现可以从下面几个方面去考虑
(1)硬编码的方式准备测试数据,在写测试代码的时候,使用到什么数据就插入什么数据。为了避免数据重复,很多人会习惯于使用随机字符或随机数(这种方法可能造成测试用例不稳定,尽量避免)。
(2)可以直接通过调用其他 API 的方式准备测试数据,这种情况在测试最上层服务的时候比较有用,比如测试购买商品,就需要准备要购买的商品数据,购买商品的用户数据,这个时候,可以直接调用生成商品的 api 和生成用户的 api 直接生成测试数据。此方法实现简单,但前提是需要具备相应的 api 并且此 api 功能正确。
(3)使用 excel 或 xml 准备测试数据,这种准备测试数据的方式,主要针对对象数据的准备,比如可以将一条商品数据对应 excel 中的一条数据,因为一般开发都会使用 pojo 映射,而在准备测试数据的时候,这些 pojo 对象属性的设置往往是重复和大工作量的,用 excel 或 XML 方式准备,则可以减少在代码当中重复去准备这些数据。
一般我们使用的是 2/3 两种方式,其中 3 这种方式主要利用 dbunit、spring-test、unitils 等测试框架的特性经二次开发增加自定义注解,很轻松的导入 excel 或 xml 格式的文件并在测试完成后对数据进行自动回滚。

/** 
* @ClassName: TestJdbcDataSet 
* @Description: 采用自定义TestDataSet注解方式准备测试数据,推荐。
* @author Cay.Jiang   
* @date 2017年7月10日 上午9:10:29 
*  
*/
public class TestJdbcDataSet extends BaseCase{
    Map<String, Object> args = new HashMap<String, Object>();
    @Test
    @TestDataSet(locations={"/tmp/domaininfo.xls"},dsNames={"mysqlDataSource"})
    public void test01_mysql(){
        args.put("selfdomain", "baidupc2");
        List<Map<String, Object>> result=JdbcUtil.queryData(mysqlJdbcTemplate, "domaininfo", args);
        System.out.println(result);
        assertEquals("合作商接入名称",result.get(0).get("remark"));
    }
}

上面代码中的/tmp/domaininfo.xls 参见:domaininfo.xls ,其中 Excel 格式以 Sheet 名为表名,第一行定义了字段名称,其余行为对应的数据。


​多数据集:
@TestDataDataSet(locations={"Data1.xls","Data2.xls"},dsNames={"dsNameA","dsNameB"}),Data1.xls 的数据会插入 dsNameA 所指的数据库中,Data2.xls 的数据会插入 dsNameB 所指的数据库中
2.断言
常见的断言方式有 JUnit 自带的 Assert 和 Hamcrest。JUnit 自带的断言方法功能十分有限只能满足最基本的需求。Hamcrest 相对来讲功能丰富一些,但是该库已经多年不更新。而且 Hamcrest 和 JUnit 自带的断言方法一样,有个致命的缺点,就是当一个 case 中有多个断言时,如果其中一个断言失败,那么在它之后的断言都不会执行。这里向大家推荐一款新的断言神器 AssertJ。
AseertJ: 号称流式断言。什么是流式,常见的断言器一条断言语句只能对实际值断言一个校验点,而 AseertJ 支持一条断言语句对实际值同时断言多个校验点,这样使得断言的语句更加简洁适合阅读。AseertJ 还支持一次性执行所有断言,然后收集所有失败的断言一起反馈。当然除此之外 AseertJ 还有很多其他特性,可以参考官方文档慢慢挖掘。下面将举例说明一下 AseertJ 的优势:

public class TestCase extends BaseCase{
    UserProfileBO user = new UserProfileBO();
    @Before
    public void init(){
        user.setAddress("杭州");
        user.setMobile("1386800000");
        user.setUserName("测试账号");
    }

    /*
     * JUnit 内置的断言
     * 
     * 1、其中一个断言失败后,后面所有断言将不会执行。
     * 2、支持的断言方法较少
     * 
     */
    @Test
    public void testAssertJUnit(){

        Assert.assertEquals("地址",user.getAddress(),"宁波");
        Assert.assertEquals("手机",user.getMobile(),"13868000000");
        Assert.assertEquals("手机",user.getUserName(),"测试");

        Assert.assertNotNull(user.getMobile());
        Assert.assertTrue(user.getMobile().startsWith("138"));
        Assert.assertTrue(user.getMobile().length() == 11);

    }

    /*
     * Hamcres 断言
     * 
     * 1、其中一个断言失败后,后面所有断言将不会执行。
     * 2、支持的断言方法丰富,但是已经多年不更新。
     * 
     */
    @Test 
    public void testHamcrestMatchers() {  

        MatcherAssert.assertThat(user.getAddress(), equalTo("宁波"));  
        MatcherAssert.assertThat(user.getMobile(), equalTo("13868000000"));  
        MatcherAssert.assertThat(user.getUserName(), equalTo("测试"));  

        MatcherAssert.assertThat(user.getMobile(), allOf(is(nullValue()),startsWith("136")));  
    }

    /*
     * AssertJ 断言
     * 
     * 1、支持所有断言执行后,失败断言统一反馈。
     * 2、支持的断言方法丰富。
     * 3、支持流式断言,方便阅读。
     * 
     */
    @Test
    public void testAssertJ(){

        //断言集合,执行所有断言后,失败断言统一反馈。
        SoftAssertions.assertSoftly(softly -> {
            softly.assertThat(user.getAddress().equals("宁波"));
            softly.assertThat(user.getMobile().equals("13868000000"));
            softly.assertThat(user.getUserName().equals("测试"));
        });

        //流式断言
        Assertions.assertThat(user.getMobile())
            .isNotNull()
            .startsWith("136")
            .hasSize(11);

    }
}

3.jenkins 集成接口测试
(1)设置测试代码的仓库地址及身份信息


(2)设置 maven 运行参数
希望执行部分接口用例,可以通过-Dtest=XXX(测试类名) 的方式执行指定的 case,多个类名用逗号 “,” 隔开


(3)设置 Job 执行机制,下图表示每天定时执行


4.pipeline 参数注入
前面写 pipeline 的时候提过,我们的接口测试代码是需要支持外部参数注入的,比如测试的服务地址,不同的分支代码可能部署在不同测试服务器上,需要在 pipeline 中通过参数化的方式驱动对不同的服务器进行接口测试。
这里我们可以使用 maven 的-D(Properties 属性)来实现,举例如下:
(1) dubbo 使用 properties 配置文件,但具体参数使用 ${key}占位符方式打包替换


(2) maven 的 pom 文件中指定对应配置文件中的参数值 (此处指定的参数值会被通过 maven -D 传递过来的参数值覆盖)


此处注意:还需要启动 resources 的 filter 过滤器
(3) 使用 maven 命令行设置属性值


并对该值进行参数化支持 pipeline 传参


5.pipeline 代码实现

stage('接口自动化测试') {
      steps{
          echo "starting interfaceTest......"
          script {
           //为确保jetty启动完成,加了一个判断,确保jetty服务器启动可以访问后再执行接口层测试。
           timeout(5) {
               waitUntil {
                  try {
                      //确保jetty服务的端口启动成功
                      sh "nc -z ${serverIP} ${jettyPort}"
                      //sh "wget -q http://${serverIP}:${jettyPort} -O /dev/null"
                      return true
                  } catch (exception) {
                      return false
                      }
                  }
              }
          //将参数IP和Port传入到接口测试的job,需要确保接口测试的job参数可注入
           build job: ITEST_JOBNAME, parameters: [string(name: "dubbourl", value: "${serverIP}:${params.dubboPort}")]
          }
      }
  }

测试代码规范 (仅供参考)

1.测试项目命名规范
接口测试:
一般需要独立测试项目,测试项目的命名规则为:“test-“+ 被测试的项目名,如 test-kano
单元测试:
不需要重建独立测试项目,和开发代码放在同一项目即可。
2.测试目录定义规范
测试代码统一放在测试项目的 “src/test/java” 下。
测试配置文件统一放置在 “src/test/resources” 下。
3.包名定义规范
与被测试项目中的包名一致
4.测试类命名规范
测试类的命名规则是:以 Test 开头,以它要测试的对象的名称结尾,例如
Test+ 被测试的业务、Test+ 被测试的接口、Test+ 被测试的类
另外一种方式是:以 Test 结尾,以它要测试的对象的名称开头,例如
被测试的业务 +Test、被测试的接口 +Test、被测试的类 +Test
视个人习惯而定,为了 case 定位方便,目前测试团队一般用第一种。
5.测试用例命名规范
测试用例的命名规则是:test+ 用例操作_条件状态,统一使用 lowerCamelCase 风格,必须遵从驼峰形式。
单词的约定与测试类命名同
6.接口测试代码常见约束

(1)数据清理和构造
@BeforeClass @Before中做数据准备等相关操作
--加载测试类以前需要加载所有测试用例共同的场景数据,同时在运行单个测试用例的时候加载特别的测试数据
@AfterClass @After中做测试数据清理等相关操作
--在执行完相关测试以后清理用例现场
(2)断言
--不要做无谓的断言
在测试模式下, 有时会情不自禁的滥用断言. 这种做法会导致维护更困难, 需要极力避免. 仅对测试方法名指示的特性进行明确测试,因为对于一般性代码而言, 保证测试代码尽可能少是一个重要目标
--使用显式断言方式
应该总是优先使用 assertEquals(a, b) 而不是 assertTrue(a == b), 因为前者会给出更有意义的测试失败信息. 在事先不确定输入值的情况下, 这条规则尤为重要
--断言的参数顺序要合适
(3)测试用例保持独立
--确保测试代码独立于项目代码之外
--为了保证测试稳定可靠且便于维护, 测试用例之间决不能有相互依赖, 也不能依赖执行的先后次序.
(4)测试代码要考虑错误处理
--如果前面的代码执行失败, 后续语句会导致代码崩溃, 剩下的测试都无法执行. 任何时候都要为测试失败做好准备, 避免单个失败的测试项中断整个测试套件的执行
--不要写自己的 catch 代码块,即只有 test 失败的情况,不应该存在 catch 情况

  作为一位过来人也是希望大家少走一些弯路

在这里我给大家分享一些自动化测试前进之路的必须品,希望能对你带来帮助。

(软件测试相关资料,自动化测试相关资料,技术问题答疑等等)

相信能使你更好的进步!

点击下方小卡片

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/769821.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

PALO ALTO NETWORKS 的新一代防火墙如何保护企业安全

轻松采用创新技术、阻止网络攻击得逞并专注更重要的工作 IT 的快速发展已改变网络边界的面貌。数据无处不在&#xff0c;用户可随时随地从各类设备访问这些数据。同时&#xff0c;IT 团队正在采用云、分析和自动化来加速新应用的交付以及推动业务发展。这些根本性的转变带来了…

Kakfa - 多副本架构

文章目录 基本架构Kafka 多副本架构概念优点缺点 图解多副本架构小结 基本架构 Kafka 多副本架构 概念 Kafka 是一个高性能、分布式的消息系统&#xff0c;被广泛应用于各种场景中。在 Kafka 中&#xff0c;多副本架构是保证数据可靠性的重要手段之一。 多副本架构指的是将同…

【动手学深度学习】--12.深度卷积神经网络AlexNet

文章目录 深度卷积神经网络AlexNet1.AlexNet2.模型设计3.激活函数4.模型实现5.读取数据集6.训练AlexNet 深度卷积神经网络AlexNet 学习视频&#xff1a;深度卷积神经网络 AlexNet【动手学深度学习v2】 官方笔记&#xff1a;深度卷积神经网络&#xff08;AlexNet&#xff09; …

Qt的三大优势,打造高效工业软件开发:

强大的跨平台特性&#xff1a;Qt拥有优良的跨平台支持&#xff0c;可以在众多操作系统上运行&#xff0c;包括Microsoft Windows、Linux、Solaris、HP-UX、FreeBSD、QNX等等。这使得开发者可以轻松地将应用程序部署到不同的平台上&#xff0c;提高开发效率和覆盖范围。 面向对…

基于R语言的水文、水环境模型优化技术及快速率定方法与多模型案例实践

在水利、环境、生态、机械以及航天等领域中&#xff0c;数学模型已经成为一种常用的技术手段。同时&#xff0c;为了提高模型的性能&#xff0c;减小模型误用带来的风险&#xff1b;模型的优化技术也被广泛用于模型的使用过程。模型参数的快速优化技术不但涉及到优化本身而且涉…

linux之Ubuntu系列(七)用户管理 终端命令 su 切换用户

# 切换用户 zenxx:su - sup # 录入sup 密码 supxx:$ 切换root用户

Bard:Google AI开始支持中文对话和看图说话了

说起时下火爆的生成式AI&#xff0c;并不是只有ChatGPT。Bard也是一个很优秀的产品&#xff0c;并且刚刚发布的很多有趣的新功能。文末告诉你如何访问Bard。 Google AI在最近的更新中发布了Bard&#xff0c;一个新的语言模型。Bard支持多种语言&#xff0c;包括中文&#xff0…

linux之Ubuntu系列(五)用户管理、查看用户信息 终端命令

创建用户 、删除用户、修改其他用户密码的终端命令都需要通过 sudo 执行 创建用户 设置密码 删除用户 sudo useradd -m -g 组名 新建用户名 添加新用户 -m&#xff1a;自动建立用户 家目录 -g&#xff1a;指定用户所在的组。否则会建立一个和用户同名的组 设置新增用户的密码&…

7、PHP语法要点2

1、or 和 ||&#xff0c;&& 和 and 都是逻辑运算符&#xff0c;效果一样&#xff0c;但是其优先级却不一样。&&、||的优先级在赋值运算符之前&#xff0c;or和and在赋值运算符之后。 2、字符串变量及数组可以在echo输出时双引号内、双引号外均可引用&#xff…

Android Studio Flutter 开发配置

近来比较闲&#xff0c;就研究下Flutter 开发&#xff0c;在此记录下studio 配置过程&#xff0c;时间是2023.7.19 在 Windows 操作系统上安装和配置 Flutter 开发环境 1.首先下载 Flutter SDKhttps://storage.flutter-io.cn/flutter_infra_release/releases/stable/windows/…

【极简,亲测,解决】Too many levels of symbolic links

前言&#xff08;与内容无关&#xff09; 帖子看多了&#xff0c;让我产生一种错觉&#xff0c;就是生产这些帖子的人都是机器人吗&#xff1f;是活着的吗&#xff1f;乱七八糟的转载和明显错误的结论太多了。 原因 原因是 链接的层数过多&#xff0c;已经产生了回路。 大概…

【案例教程】基于Python机器学习、深度学习技术提升气象、海洋、水文领域实践应用能力

Python是功能强大、免费、开源&#xff0c;实现面向对象的编程语言&#xff0c;能够在不同操作系统和平台使用&#xff0c;简洁的语法和解释性语言使其成为理想的脚本语言。除了标准库&#xff0c;还有丰富的第三方库&#xff0c;Python在数据处理、科学计算、数学建模、数据挖…

C++:const修饰指针

const修饰符常常需要在c中使用到&#xff0c;需要注意到他对于指针修饰的时候的不同区别。 #include<iostream> using namespace std; int main() {//1.const修饰指针int a 10;int b 10;const int* p &a;//指针指向的值不可以改&#xff0c;指针的指向可以改// …

麒麟系统开发笔记(十二):在国产麒麟系统上编译GDAL库、搭建基础开发环境和基础Demo

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/131805718 红胖子网络科技博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软硬…

ifconfig不是eth0(eth1/2/3/4其他网卡)的解决办法

1. 编辑你网卡的配置文件 /etc/sysconfig/network-scripts/ifcfg-eth0&#xff0c;更改eth0中HWADDR 更改为eth1网卡的信息&#xff08;这里是16位的mac地址&#xff09; 2. 编辑配置文件 vi /etc/udev/rules.d/70-persistent-net.rules 打开该文件&#xff0c;这时你会发现&…

思政课程,如何提升学习体验?

学校思政课程是中国高等教育中的一门重要课程&#xff0c;旨在培养学生的马克思主义理论素养、思想道德素质和社会责任感。 学校思政课程的开展&#xff0c;对于培养学生的全面发展和提升社会主义核心价值观具有重要意义。它不仅帮助学生理解和把握社会历史发展规律&#xff0c…

切面+注解方式实现sql注入,实现数据权限控制

前言&#xff1a;诸君谨记&#xff0c;你知道的越多&#xff0c;你就知道越少&#xff0c;良好的代码前篇一律&#xff0c;靠谱的架构&#xff0c;可以让程序开发效率提高&#xff0c;且运行稳如老狗&#xff0c;哈哈&#xff0c;言归正传 话说面试官问你&#xff0c;你对系统数…

VideoPipe可视化视频结构化框架更新总结

新增实例分割相关支持 增加了基于mask-rcnn的实例分割插件和相关sample。 1 #include "VP.h"2 3 #include "../nodes/vp_file_src_node.h"4 #include "../nodes/infers/vp_mask_rcnn_detector_node.h"5 #include "../nodes/track/vp_sort_…

vite 引入局部组件 必须带.vue

11:03:47 AM [vite] Internal server error: Failed to resolve import “./components/layoutsHeader” from “src/views/layouts/layouts.vue”. Does the file exist? 在这里插入图片描述

Apple Logic Pro 10.7.9 - 音频编辑

Apple Logic Pro 10.7.9 - 音频编辑 Logic Pro 10.7.9 MainStage 3.6.4 (Universal) 请访问原文链接&#xff1a;https://sysin.org/blog/apple-logic-pro/&#xff0c;查看最新版。原创作品&#xff0c;转载请保留出处。 作者主页&#xff1a;sysin.org Logic Pro X 10.3&…