关于接口测试自动化的总结与思考(二)

发表于:2022-11-18 09:40

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:阿里云云栖号    来源:知乎

  接口测试自动化实践
  TestNGJunit 对比
  · 综合性对比
  我在日常测试工作中,使用的比较多的自动化测试工具是 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 中都实现。然而,两者都使用非常不同的方法来实现它。
  Junit4 参数化测试:
  步骤如下:
  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);      
      } 
  }
  缺点:
  ·一个测试类只能有一个静态的参数构造方法;
  · 测试类需要使用@RunWith(Parameterized.class),无法兼容 spring-test 的 runner
  · @RunWith(SpringJUnit4ClassRunner.class),会导致无法通过注解注入待测服务
  · 需要在测试类中添加一个构造方法(一种冗余设计)
  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"); 
  }
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号