关于阿里云:关于接口测试自动化的总结与思考

30次阅读

共计 14504 个字符,预计需要花费 37 分钟才能阅读完成。

作者:云原生

近期,阿里云性能测试 PTS 接口测试已上线公布一段时间,本着以和大家交换如何实现高效的接口测试为出发点,本文蕴含了我在接口测试畛域的一些办法和心得,心愿大家一起探讨和分享,内容包含但不仅限于:

  • 服务端接口测试介绍
  • 接口测试自动化介绍
  • 接口测试自动化实际
  • 对于接口测试自动化的思考和总结

服务端接口测试介绍

什么是服务端?

个别所说的服务端是指为用户在 APP 或 PC 应用的互联网性能 提供数据服务 的背地的所有。以天猫精灵智能音箱系列的产品链路为例,服务端便是网关(包含网关在内)之后的链路。

什么是接口?

官网点说,是计算机系统中两个独立的部件进行信息替换的共享边界。艰深点说,就是服务端对外提供数据服务最罕用的信息替换形式。提供数据服务的服务端是个可大可小的机构,做的事大多不止一件,它做了这么多事,最终的指标是给 APP 或其它调用方应用,于是服务端就派出了几个代表,比方 API1 负责提供用户信息,API2 负责提供设施信息,API3 负责提供播放的音频信息等等。共事,服务端规定好跟 API1 通信的接头暗号是 param1,param2…,跟 API2 通信的接头暗号是 param3,param4…,而 params 就是接口参数,就是用来通知服务端你要什么服务,具体的要求是什么。接口个别由三个局部组成:协定、地址及参数。

什么是接口测试?

个别讲的接口测试指的是对某个给定接口进行功能测试,输出不同的参数时,接口返回值是否正确。下图是经典的测试金字塔模型。

在这个模型中,越往下比例会占的越高,也就是说在一个产品测试中,单元测试比例是最高的,顺次是接口测试和 UI 自动化测试,最顶端是人工测试局部。服务端接口测试在中部,承前启后,由此可见其重要性。

为什么要做接口测试?

个别做接口测试有如下起因:

  • 接口是服务端对外提供数据服务最罕用的信息替换形式,接口大部分内容都是数据,通过数据比照咱们能够揣测到零碎的逻辑,测接口其实也就是测逻辑。
  • 接口测试绝对容易实现自动化,也容易实现继续集成,且绝对 UI 自动化也比较稳定,能够缩小人工回归测试人力老本与工夫,缩短测试周期,反对后端疾速发版需要。

如何做接口测试?

后面提到,接口是由这几个组成部分:接口地址、申请协定、申请参数和预期后果。测试接口的步骤个别步骤是:发送申请 -> 解析后果 -> 验证后果

简略来说,接口测试就是参照接口文档,调用接口,看后果的返回是否跟文档阐明统一;另外,再测试一下接口对异样逻辑的解决比方非法参数或边界值。

深刻来说,接口测试的关注 重点 在于:

一、接口的数据逻辑是否正确。 咱们须要充沛了解接口的性能,外部是什么样的数据逻辑,它与上下游替换了那些信息或资源,不单纯地停留在参数调用和程序返回的表象数据。艰深地说,就是要晓得这个接口是干什么用的,用到哪里,每次调用会产生什么,而后去测验改产生的有没有产生。

二、接口对于异样参数的解决机制与上下游服务的容错。 如下图所示,被测接口 A 依赖上游服务 A,那么服务 A 异样的时候被测接口是否很好的容错就很重要,否则服务挂起或宕掉都是有可能的。另外,作为服务提供方接口 B,该当要充沛兼容不同的应用场景、或不同版本的调用方的应用,不能为了服务 E 做的需要,除了 E 其它的服务使用者都用不了了。总的来说,准则就是 “上游不牢靠,上游要兼容”

接口测试自动化介绍

为什么是接口测试自动化?

接口测试自动化,简略来讲就是性能测试用例脚本化,而后执行脚本,产生一份可视化测试报告。

为什么要做接口测试自动化?

不论什么样的测试形式,都是为了验证性能与发现 bug。那为什么要做接口测试自动化呢?一句话概括就是是为了节俭人力老本。具体来说,包含以下几点:

  • 加重本人工作量,把测试从干燥的重复劳动的人工测试中解放出来;
  • 帮助手工测试实现很难模仿或无奈模仿的的工作;
  • 进步工作效率,比方测试环境的自动化编译、打包、部署、继续集成甚至继续交付等。
  • 帮助定位问题,比方接口层发现问题了,能够通过增加的 traceID 定位到日志谬误或错误代码行,
  • 尽早发现 bug,主动告诉测试人员。一旦发现问题,立刻告诉测试人员,疾速高效。

接口测试自动化的标准

这里联合我平时在做接口测试时的一些教训,总结了一些接口测试自动化的标准,抛砖引玉,欢送大家补充。

文档筹备

磨刀不误砍柴工,筹备好分具体的接口相干文档可能帮忙后续接口自动化测试工作的高效开展。相干文档包含但不限于一下内容:

1.《需要文档》,明确定义了:接口背地的业务场景,即该接口是干什么用的,用到哪里,每次调用会产生什么等;

2.《接口文档》,明确定义了:接口名,各个入参值,各个返回值,和其余相干信息;

3.《UI 交互图》,明确定义了:各单页面需展现的数据;页面之间的交互等;

4.《数据表设计文档》,明确定义了:表字段规定、表 N 多 N 关系(一对一、一对多、多对多)等;

务必和相干需求方确认好文档中的信息是牢靠且最新的,只有依赖牢靠的文档能力设计出正确详尽的接口用例,能力失去最正确的后果。

明确接口测试自动化须要的性能

1. 校验(断言)

测试断言是自动化测试中的测试通过条件,用于判断测试用例是否合乎预期。所以反对对返回值校验是一个必须的性能。

2. 数据隔离

数据隔离就是指具体的申请接口、参数、校验等数据做到与代码相隔离,便于保护,一旦须要调整接口用例、新增接口用例时可很疾速的找到地位。隔离的另一个益处就是可复用,框架能够推广给其余团队,使用者能够应用雷同的代码,只须要依据要求填写各自用例即可测试起来。

3. 数据传递

做到数据隔离可保护后,数据传递是另外一个更重要的需要。接口测试时,首先咱们会实现单接口解耦,后续依照业务场景组合多个接口。而数据传递是则是组合多个接口的必要条件,它让接口用例之间能够做到向下传参。举个例子,咱们通过设施信息查问接口查问到以后天猫精灵音箱的设施信息,该接口会返回一个 UUID,接下来咱们要通过用户信息查问接口去查问以后设施绑定的用户信息,此时第二个接口的申请数据是须要从第一个接口用例中的返回中提取的。

4. 性能函数

理论的业务场景测试会须要各种辅助性能的反对,比方随机生成工夫戳,申请 ID,随机的手机号码或地位信息等等,此时咱们就须要代码能够反对做到辨认对应关键字时能够执行对应的性能函数进行填充。

5. 可配置

目前测试环境包含但不限于日常、预发一、预发二、线上等等,因而用例不单单只能在一个环境上执行,须要同一份接口用例能够在日常、预发、线上等多个环境都能够执行。所以框架须要做到可配置,便于切换,调用不同的配置文件能够在不同的环境执行。

6. 日志

日志蕴含执行的具体执行接口、申请形式、申请参数、返回值、校验接口、申请工夫、耗时等要害信息,日志的益处一来是能够便于在新增用例有问题时疾速定位出哪里填写有问题,二来是发现 bug 时不便向开发反馈提供数据,开发能够从触发工夫以及参数等信息疾速定位到问题所在。

7. 可视化报告

用例执行后,就是到了向团队展现后果的时候了,一个可视化的报告能够便于团队成员理解到每次自动化接口用例执行的胜利数、失败数等数据。

8. 可继续集成

对于曾经有测试用例并测试实现的接口,咱们心愿可能造成回归用例,在下一个版本迭代或上线之前,通过已有用例进行一个回归测试,确保新上线的性能不影响已有性能。因而,这就须要接口自动化测试是可继续集成的而不是一次性的。

接口测试自动化框架选型

联合咱们对接口测试自动化框架的需要及目前市场上的很多测试工具的特点,总结成下表:

这里简略列举一下:

1、fiddler

fiddler 是一个 HTTP 协定调试代理工具,Web 和手机测试都会用到,同时也反对接口测试。它可能记录并查看所有你的电脑和互联网之间的 http 通信,设置断点,查看所有的“进出”Fiddler 的数据(指 cookie [ 1] ,html,js,css 等文件)。

具体介绍见:

https://www.telerik.com/fiddler

[1] cookie:

https://baike.baidu.com/item/…

2、postman

它是 Google 开发的一个插件,装置在 Chrome 浏览器上,能反对不同接口测试申请,能够治理测试套件和自动化运行。弱点是自动化断言性能不弱小,不能和 Jenkins、代码治理库进行继续集成测试。

3、wireshak

这是一款抓包工具,反对 TCP、UDP、HTTP 等协定。如果做底层网络数据测试,个别都须要用到它,然而用作接口测试,它就有点不敌对。因为刷新数据太快,不好定位每个操作对应的接口。

4、soupUI

soapUI 是一个开源测试工具,通过 soap/http 来查看、调用、实现 Web Service 的性能 / 负载 / 合乎性测试。该工具既可作为一个独自的测试软件应用,也可利用插件集成到 Eclipse,maven2.X,Netbeans 和 intellij 中应用。把一个或多个测试套件(TestSuite)组织成我的项目,每个测试套件蕴含一个或多个测试用例(TestCase),每个测试用例蕴含一个或多个测试步骤,包含发送申请、承受响应、剖析后果、扭转测试执行流程等。该工具可能反对接口自动化测试和接口性能测试,也反对和 Jenkins 做继续集成测试。

具体介绍见:

https://www.soapui.org/

5、Java 代码做接口测试

为什么要用代码做接口自动化测试呢?一些工具性能是有限度,很多公司须要一些特定的性能,工具不反对,只好用代码进行开发。个别用 Java 做自动化测试,次要利用 httpclient.jar 包,而后利用 JUnit 或者 TestNG 这样的单元测试工具,进行测试用例的开发,接着在 Jenkins 或咱们的 aone 上创立一个 job,进行继续集成测试。

6、Python 代码做接口测试

和 Java 一样,用 Python 做接口测试,能够利用一个功能强大的第三方库 Requests,它能不便地创立接口自动化用例。Python 下的单元测试框架,个别采纳 unittest。生成测试报告,个别抉择 HTMLTestRunner.py。同样,能够联合 Jenkins 做继续集成测试。

接口测试自动化实际

TestNG 与 JUnit 比照

综合性比照

我在日常测试工作中,应用的比拟多的自动化测试工具是 Java 代码做接口测试,这里先介绍下我对单元测试工具 TestNG 和 JUnit 的比照。先用一张表格总结一下他们的特点比照。

TestNG 与 JUnit 的相同点如下:

1、都有注解,即都应用 annotation,且大部分 annotation 雷同;

2、都能够进行单元测试(Unit test);

3、都是针对 Java 测试的工具;

TestNG 与 JUnit 的不同点如下:

1、TestNG 反对的注解更丰盛,如 @ExpectedExceptions、@DataProvider 等;

2、JUnit 4 中要求 @BeforeClass、@AfterClass 办法申明为 static,这就限度了该办法中应用的变量必须是 static。而 TestNG 中 @BeforeClass 润饰的办法能够跟一般函数齐全一样;

3、JUnit 只能应用 IDE 运行,TestNG 的运行形式有:命令行、ant 和 IDE;

4、JUnit 4 依赖性十分强,测试用例间有严格的先后顺序。前一个测试不胜利,后续所有的依赖测试都会失败。TestNG 利用 @Test 的 dependsOnMethods 属性来应答测试依赖性问题。某办法依赖的办法失败,它将被跳过,而不是标记为失败。

5、对于 n 个不同参数组合的测试,JUnit 4 要写 n 个测试用例。每个测试用例实现的工作根本是雷同的,只是办法的参数有所扭转。TestNG 的参数化测试只须要一个测试用例,而后把所须要的参数加到 TestNG 的 xml 配置文件中或应用 @DataProvider 形式注入不同的参数。这样的益处是参数与测试代码拆散,非程序员也能够批改参数,同时批改无需从新编译测试代码。

6、JUnit 4 的测试后果通过 Green/Red bar 体现,TestNG 的后果除了 Green/Red bar,还有 Console 窗口和 test-output 文件夹,对测试后果的形容更加具体,不便定位谬误。

具体个性比照

上面具体介绍一下 TestNG 与 JUnit 个性比照:

1、框架整合:

Spring+TestNG+Maven 整合:

  • pom.xml 中减少 testng 依赖:
<dependency>
  <groupId>org.testng</groupId>
  <artifactId>testng</artifactId>
  <version>6.8.8</version>
  <scope>test</scope>
</dependency>
  • 测试类减少 1 条注解 @ContextConfiguration(locations = “classpath:applicationContext.xml”) 并继承 AbstractTestNGSpringContextTests,范例如下
@ContextConfiguration(locations = "classpath:applicationContext.xml") 
public class BaseTest extends AbstractTestNGSpringContextTests{     
      @Test
      public void testMethods()     {         ......} 
}

Spring+JUnit+Maven 整合:

  • pom.xml 中减少 JUnit 依赖:
<!--Junit 版本 --><dependency>  <groupId>junit</groupId>  <artifactId>junit</artifactId>  <version>4.4</version>  <scope>test</scope></dependency>
  • 测试类减少 2 条注解

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations = “classpath:applicationContext.xml”), 如下:

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = "classpath:applicationContext.xml") 
public class BaseTest{     
    @Test     
    public void testMethods()     {         ......} 
}
2、注解反对

次要区别以下两点:

1、在 JUnit 4 中,咱们必须申明“@BeforeClass”和“@AfterClass”办法作为静态方法。TestNG 在办法申明中更灵便,它没有这个束缚。

2、在 JUnit 4 中,正文命名约定有点凌乱,例如“Before”,“After”和“Expected”,咱们并不真正理解“Before”和“After”之前的内容,以及要测试中的“预期”办法。TestiNG 更容易了解,它应用相似“BeforeMethod”,“AfterMethod”和“ExpectedException”就很明了。

3. 异样测试

“异样测试”是指从单元测试中抛出的异样,此性能在 JUnit 4 和 TestNG 中都可实现。

JUnit 4

@Test(expected = ArithmeticException.class) public void divisionWithException() {   int i = 1/0;}

TestNG

@Test(expectedExceptions = ArithmeticException.class) public void divisionWithException() {   int i = 1/0;}
4. 疏忽测试

疏忽测试意思是在单元测试哪些是能够被疏忽的,这个个性在两个框架都曾经实现。

JUnit 4

@Ignore("Not Ready to Run")  @Test public void divisionWithException() {      System.out.println("Method is not ready yet"); }

TestNG

@Test(enabled=false) public void divisionWithException() {      System.out.println("Method is not ready yet"); }
5. 超时测试

工夫测试意思是如果一个单元测试运行的工夫超过了一个指定的毫秒数,那么测试将终止并且标记为失败的测试,这个个性在两个框架都曾经实现。

JUnit 4

@Test(timeout = 1000)  public void infinity() {      while(true);  }

TestNG

@Test(timeOut = 1000)  public voi
6. 套件测试

“套件测试”是指捆绑几个单元测试并一起运行。此性能在 JUnit 4 和 TestNG 中都可实现。然而,两者都应用十分不同的办法来实现它。

JUnit 4

“@RunWith”和“@Suite”用于运行套件测试。上面的类代码示意在 JunitTest3 执行之后,单元测试“JunitTest1”和“JunitTest2”一起运行。所有的申明都是在类内定义的。

@RunWith(Suite.class) @Suite.SuiteClasses({JunitTest1.class,         JunitTest2.class}) public class JunitTest3 {}

TestNG

XML 文件用于运行套件测试。以下 XML 文件示意单元测试“TestNGTest1”和“TestNGTest2”将一起运行。

<suite name="My test suite">   
  <test name="testing">
    <classes>
      <class name="com.fsecure.demo.testng.TestNGTest1" />
      <class name="com.fsecure.demo.testng.TestNGTest2" />
    </classes>   
  </test>
</suite>

TestNG 能够做捆绑类测试,也能够捆绑办法测试。凭借 TestNG 独特的“分组”概念,每种办法都能够与一个组合相结合,能够依据性能对测试进行分类(分组)。例如,上面是一个有四个办法的类,三个组(method1,method2 和 method3)

@Test(groups="method1") public void testingMethod1() {   System.out.println("Method - testingMethod1()"); } 
@Test(groups="method2") public void testingMethod2() {   System.out.println("Method - testingMethod2()"); } 
@Test(groups="method1") public void testingMethod1_1() { System.out.println("Method - testingMethod1_1()"); } 
@Test(groups="method4") public void testingMethod4() { System.out.println("Method - testingMethod4()"); }

应用以下 XML 文件,能够仅应用组“method1”执行单元测试。

<suite name="My test suite">   
  <test name="testing">       
    <groups>       
      <run>         
        <include name="method1"/>       
      </run>     
    </groups>     
    <classes>        
      <class name="com.fsecure.demo.testng.TestNGTest" /></classes>   
  </test> 
</suite>
7. 参数化测试

**“参数化测试”是指单位测试参数值的变动。此性能在 JUnit 4 和 TestNG 中都实现。然而,两者都应用十分不同的办法来实现它。

JUnit 4 参数化测试:

  • 步骤如下:
    1. 通过 @Parameters 标识动态参数构造方法
    2. 通过测试类构造方法引入参数
    3. 测试方法应用参数
@RunWith(value = Parameterized.class) 
public class JunitTest {       
    private int number;       
    public JunitTest6(int number) {this.number = number;}     
    
    @Parameters      
    public static Collection<Object[]> data() {Object[][] data = new Object[][] { { 1}, {2}, {3}, {4} };        
        return Arrays.asList(data);      
    }      
    
    @Test      
    public void pushTest() {System.out.println("Parameterized Number is :" + number);      
    } 
}
  • 毛病:
  1. 一个测试类只能有一个动态的参数构造方法;
  2. 测试类须要应用 @RunWith(Parameterized.class),无奈兼容 spring-test 的 runner
  3. @RunWith(SpringJUnit4ClassRunner.class),会导致无奈通过注解注入待测服务
  4. 须要在测试类中增加一个构造方法(一种冗余设计)

TestNG 参数化测试:

  • 步骤如下:
    1. 通过 @dataProvider 注解标识参数构造方法
    2. 测试方法在注解 @Test 中通过 dataProvider 属性指定参数构造方法,便可在测试方法中应用参数
@Test(dataProvider = "Data-Provider-Function")     
public void parameterIntTest(Class clzz, String[] number) {System.out.println("Parameterized Number is :" + number[0]);       
    System.out.println("Parameterized Number is :" + number[1]);     
}

除此之外,TestNG 还反对通过 testng.xml 结构参数:

public class TestNGTest {@Test @Parameters(value="number") 
    public void parameterIntTest(int number) {System.out.println("Parameterized Number is :" + number);     
    } 
}

XML 文件的内容如下

<suite name="My test suite">   
  <test name="testing">     
    <parameter name="number" value="2"/>     
    <classes>        
      <class name="com.fsecure.demo.testng.TestNGTest" />     
    </classes>   
  </test> 
</suite>
8. 依赖测试

“参数化测试”示意办法是依赖性测试,它将在所需办法之前执行。如果依赖办法失败,则所有后续测试将会被跳过,不会被标记为失败。

JUnit 4

JUnit 框架着重于测试隔离; 目前它不反对此性能。

TestNG

它应用“dependOnMethods”来实现依赖测试如下

@Test public void method1() {System.out.println("This is method 1"); 
}
@Test(dependsOnMethods={"method1"}) 
public void method2() {System.out.println("This is method 2"); 
}

TestNG 接口自动化实际

参数化测试示例

以 DeviceStatusHSFService 为例,测试类如下:

public class DeviceStatusHSFServiceTest {

    private DeviceStatusHSFService deviceStatusHSFService;
    @BeforeTest(alwaysRun = true)
    public void beforeTest() {String envName = System.getProperty("maven.env");  // 运行环境可配置
        SwitchENV switchEnv = new SwitchENV(envName);    // 运行环境可配置
        deviceStatusHSFService = HsfRepository.getConsumer(DeviceStatusHSFService.class, switchEnv.getEnv(),
            "HSF", switchEnv.getHsfVersion(), "aicloud-device-center", switchEnv.getTargetIp()).getTarget();}

    @Test(dataProvider = "updateDeviceStatus", dataProviderClass = DeviceStatusHSFServiceTestDataProvider.class)
    public void updateDeviceStatusTest(Long userId, String uuid, DeviceStatus deviceStatus){Result<Boolean> result = deviceStatusHSFService.updateDeviceStatus(userId, uuid, deviceStatus);
        System.out.println("traceId:"+EagleEye.getTraceId()+result.toString());
        Boolean res = result.getResult();
        assertTrue(res);
    }
}

其中通过 SwitchENV 类实现运行环境可配置:

/**
 * 自定义环境配置
 */
public class SwitchENV {

    /**
     * 运行环境
     */
    private Env env;

    /**
     * hsf 环境
     */
    private String hsfVersion;

    /**
     * 指标机器
     */
    private String targetIp;

    /**
     * 环境名称
     */
    private String envName;

    public SwitchENV(String envName) {Properties prop = new Properties();

        // TODO: 本地自动化测试切换环境专用
        if (envName == null) {envName = "pre1";}

        switch (envName) {

            case "online": {InputStream in = SwitchENV.class.getClassLoader().getResourceAsStream("config/application-online.properties");
                try {prop.load(in);
                } catch (IOException e) {e.printStackTrace();
                }
                env = Env.ONLINE;
                break;
            }
            case "pre1": {InputStream in = SwitchENV.class.getClassLoader().getResourceAsStream("config/application-pre1.properties");
                try {prop.load(in);
                } catch (IOException e) {e.printStackTrace();
                }
                env = Env.PREPARE;
                break;
            }
            case "pre2": {InputStream in = SwitchENV.class.getClassLoader().getResourceAsStream("config/application-pre2.properties");
                try {prop.load(in);
                } catch (IOException e) {e.printStackTrace();
                }
                env = Env.PREPARE;
                break;
            }
            case "pre3": {InputStream in = SwitchENV.class.getClassLoader().getResourceAsStream("config/application-pre3.properties");
                try {prop.load(in);
                } catch (IOException e) {e.printStackTrace();
                }
                env = Env.PREPARE;
                break;
            }
            default:
                try {throw new Exception("环境变量输出谬误!");
                } catch (Exception e) {e.printStackTrace();
                }
                break;
        }
        hsfVersion = prop.getProperty("hsfVersion").trim();
        targetIp= prop.getProperty("targetIp").trim();
        this.envName = envName;
    }

    public Env getEnv() {return env;}

    public String getHsfVersion() {return hsfVersion;}

    public String getTargetIp() {return targetIp;}

    public String getEnvName() {return envName;}

}

测试参数全副放在 DeviceStatusHSFServiceTestDataProvider 类中,实现具体的申请接口、参数、校验等数据做到与代码相隔离。

/**
 * 自定义环境配置
 */
public class SwitchENV {

    /**
     * 运行环境
     */
    private Env env;

    /**
     * hsf 环境
     */
    private String hsfVersion;

    /**
     * 指标机器
     */
    private String targetIp;

    /**
     * 环境名称
     */
    private String envName;

    public SwitchENV(String envName) {Properties prop = new Properties();

        // TODO: 本地自动化测试切换环境专用
        if (envName == null) {envName = "pre1";}

        switch (envName) {

            case "online": {InputStream in = SwitchENV.class.getClassLoader().getResourceAsStream("config/application-online.properties");
                try {prop.load(in);
                } catch (IOException e) {e.printStackTrace();
                }
                env = Env.ONLINE;
                break;
            }
            case "pre1": {InputStream in = SwitchENV.class.getClassLoader().getResourceAsStream("config/application-pre1.properties");
                try {prop.load(in);
                } catch (IOException e) {e.printStackTrace();
                }
                env = Env.PREPARE;
                break;
            }
            case "pre2": {InputStream in = SwitchENV.class.getClassLoader().getResourceAsStream("config/application-pre2.properties");
                try {prop.load(in);
                } catch (IOException e) {e.printStackTrace();
                }
                env = Env.PREPARE;
                break;
            }
            case "pre3": {InputStream in = SwitchENV.class.getClassLoader().getResourceAsStream("config/application-pre3.properties");
                try {prop.load(in);
                } catch (IOException e) {e.printStackTrace();
                }
                env = Env.PREPARE;
                break;
            }
            default:
                try {throw new Exception("环境变量输出谬误!");
                } catch (Exception e) {e.printStackTrace();
                }
                break;
        }
        hsfVersion = prop.getProperty("hsfVersion").trim();
        targetIp= prop.getProperty("targetIp").trim();
        this.envName = envName;
    }

    public Env getEnv() {return env;}

    public String getHsfVersion() {return hsfVersion;}

    public String getTargetIp() {return targetIp;}

    public String getEnvName() {return envName;}

}

思考与总结

对于接口自动化测试,从用例设计到测试脚本实现,总结起来,须要咱们具备如下思维:

  • 模块化思维
  • 数据驱动思维
  • 关键字驱动思维

模块化思维

对于咱们的接口自动化测试工程而言,须要可能创立 小而独立 的能够形容的模块、片断以及待测应用程序的脚本。这些树状构造的小脚本组合起来,就能组成能用于特定的测试用例的脚本。

数据驱动思维

简而言之,就是 测试脚本与测试数据拆散 。让测试数据独立于测试脚本独自存在,解除脚本与数据之间的强耦合。测试脚本不再负责管理测试数据,而测试数据在数据驱动测试中会以文件或者数据库的模式存在。脚本每次执行会机械的从数据文件或者数据库中读入测试数据,依据测试数据的不同走进不同的测试门路。在整个测试中,测试脚本是变化无穷的,它始终机械的执行它自身的代码,而 活着的是咱们的测试数据集 ,咱们通过不同的数据管制测试脚本中代码的走向。这个思维可能防止测试数据杂糅在测试脚本中,不便测试数据的扩大。再者,在自动化测试中,为了维持回归测试的稳固统一,测试脚本该当尽量避免更改。在非数据驱动的状况下,恰好违反了这一准则。自动化测试中,随着我的项目的深刻,测试脚本将会继续增多,测试数据和脚本揉在一起?保护起来将会是一件恐怖的事件,出错在劫难逃,所以这时不要这样做,让数据和脚本拆散,保持 死的代码,活的数据 ,保护的大部分工作将只 面向数据

关键字驱动思维

这是一种更为高级的数据驱动测试,核心思想是将测试用例的每个步骤独自封装成一个函数,以这个函数名作为关键字,将函数名及传参写入文件中,每个步骤映射一行文件。通过解析文件的每行内容,将 内容拼成一个函数调用 ,调用封装好的步骤函数,就能够一步步执行测试案例。在一个关键字驱动测试中,待测应用程序的性能和每个测试的执行步骤将被一起写到一个表中。这一个思维通过 很少的代码来产生大量的测试用例。同样的代码在用数据表来产生各个测试用例的同时被复用。

当咱们的测试思维越凑近上述三种类型的思维,接口测试的实现将越自动化。随着人工智能的一直倒退,AI 浪潮下也将诞生更多的自动化测试工具,比方采纳人工智能技术,通过某种自适应的算法来迭代咱们的测试用例,生成测试脚本。这意味着,将来测试人员的致力方向将在设计出更加牢靠、高效的自动化用例生成工具、脚本构建工具与测试执行工具,而原先那些重复劳动的人工测试工作就让聪慧的机器帮咱们做吧。

最初

PTS 接口测试收费公测中,欢送大家试用。

更多交换,欢送进钉钉群沟通,PTS 用户交换钉钉群号:44850859。

正文完
 0