zoukankan      html  css  js  c++  java
  • TestNG进行接口测试,脚本及可维护性框架

    注: 以下内容引自http://blog.csdn.net/u010321474/article/details/49977969

    TestNG进行接口测试,脚本及可维护性框架

    原创 2015年11月22日 15:10:30
    • testng被普遍使用于基于java和spring的系统结构中,用于保证系统功能,本身testng的特点

      1.结构清晰

    2.支持多种数据源

    3.可与maven集成

    4.环境/数据准备方便

    可用于系统中对外提供的接口进行接口测试脚本的编写(单元测试则一般用junit完成)。

    经典的测试脚本,一般分为三个步骤:

    1.数据和环境初始化;

    2.执行被测接口调用;

    3.断言判断。

    负责任和健壮的测试脚本,一般还要进行测试数据初始化,测试依赖的环境的调整(如业务开关打开),在执行完测试脚本后,进行数据的清理,如环境的恢复和测试遗留数据的清理。

    下面记录一个简单的接口测试编写过程:

    被测接口:

    [java] view plain copy
      
     1 package net.test.testng.service;  
     2   
     3 /** 
     4  * interface to be tested. 
     5  * @author T0DD 
     6  * 
     7  */  
     8 public interface ToBeTestedService {  
     9     /** 
    10      * return a string. 
    11      * @return  
    12      */  
    13     public String returnString();  
    14       
    15     /** 
    16      * return a obj 
    17      * @return 
    18      */  
    19     public Object returnObject();  
    20   
    21 }

    被测接口实现:
    [java] view plain copy
       
     1 package net.test.testng.service.impl;  
     2   
     3 import java.sql.SQLException;  
     4   
     5 import net.test.testng.model.Result;  
     6 import net.test.testng.service.DataBaseDAO;  
     7 import net.test.testng.service.FunctionSwitch;  
     8 import net.test.testng.service.ToBeTestedService;  
     9   
    10 public class ToBeTestedServicezImpl implements ToBeTestedService {  
    11   
    12     protected DataBaseDAO dataBaseDAO;  
    13   
    14     protected FunctionSwitch functionSwitch;  
    15   
    16     @Override  
    17     public String returnString() {  
    18         return "a string";  
    19     }  
    20   
    21     @Override  
    22     public Object returnObject() {  
    23   
    24         functionSwitch.setAvaiable(true);  
    25   
    26         Object queriedData = null;  
    27         try {  
    28             queriedData = dataBaseDAO.readData("select * from test db;");  
    29         } catch (SQLException e) {  
    30             return new Result(false, "DB error.", null);  
    31         }  
    32   
    33         return new Result(true, "Switch turned on and queried successed.",  
    34                 queriedData);  
    35     }  
    36   
    37 }  
      
    其中两个方法,一个非常简单的方法,returnString,只返回一个“a string";另一个,根据业务开关代开与否,进行数据库的读操作,组装result对象返回,result定义为:
    [java] view plain copy
      
     1 package net.test.testng.model;  
     2   
     3 public class Result {  
     4   
     5     public boolean isSuccess;  
     6   
     7     public String errorMsg;  
     8   
     9     public String succesMsg;  
    10   
    11     public Object data;  
    12   
    13     public Result(boolean isSuccess, String msg, Object data) {  
    14         super();  
    15         this.isSuccess = isSuccess;  
    16         if (isSuccess) {  
    17             this.succesMsg = msg;  
    18         } else {  
    19             this.errorMsg = msg;  
    20         }  
    21         this.data = data;  
    22     }  
    23   
    24     public boolean isSuccess() {  
    25         return isSuccess;  
    26     }  
    27   
    28     public void setSuccess(boolean isSuccess) {  
    29         this.isSuccess = isSuccess;  
    30     }  
    31   
    32     public String getErrorMsg() {  
    33         return errorMsg;  
    34     }  
    35   
    36     public void setErrorMsg(String errorMsg) {  
    37         this.errorMsg = errorMsg;  
    38     }  
    39   
    40     public String getSuccesMsg() {  
    41         return succesMsg;  
    42     }  
    43   
    44     public void setSuccesMsg(String succesMsg) {  
    45         this.succesMsg = succesMsg;  
    46     }  
    47   
    48     public Object getData() {  
    49         return data;  
    50     }  
    51   
    52     public void setData(Object data) {  
    53         this.data = data;  
    54     }  
    55   
    56 }  
       
     
    重点,测试类
    [java] view plain copy
      
     1 package net.test.testng.servicetest;  
     2   
     3 import java.sql.SQLException;  
     4   
     5 import net.test.testng.model.Result;  
     6 import net.test.testng.service.DataBaseDAO;  
     7 import net.test.testng.service.FunctionSwitch;  
     8 import net.test.testng.service.ToBeTestedService;  
     9   
    10 import org.testng.Assert;  
    11 import org.testng.annotations.AfterClass;  
    12 import org.testng.annotations.AfterMethod;  
    13 import org.testng.annotations.BeforeClass;  
    14 import org.testng.annotations.BeforeMethod;  
    15 import org.testng.annotations.Test;  
    16   
    17 public class ToBeTestedServiceTest {  
    18   
    19     protected FunctionSwitch functionSwitch;  
    20   
    21     protected DataBaseDAO dataBaseDAO;  
    22   
    23     protected boolean env;  
    24   
    25     protected ToBeTestedService toBeTestedService;  
    26   
    27     @BeforeClass  
    28     public void initEnv() {  
    29         env = functionSwitch.isAvaiable();  
    30         if (functionSwitch.setAvaiable(true)) {  
    31             Assert.fail("Prepare environment error!");  
    32         }  
    33     }  
    34   
    35     @BeforeMethod  
    36     public void initData() {  
    37         try {  
    38             dataBaseDAO.insert("insert into db data...");  
    39         } catch (SQLException e) {  
    40             Assert.fail("Init database error!");  
    41         }  
    42     }  
    43   
    44     @Test  
    45     public void testReturnString() {  
    46   
    47         String result = toBeTestedService.returnString();  
    48   
    49         Assert.assertNotNull(result);  
    50   
    51         Assert.assertEquals(result, "a string");  
    52     }  
    53   
    54     @Test  
    55     public void testReturnObject() {  
    56           
    57         Object result = toBeTestedService.returnObject();  
    58   
    59         Assert.assertNotNull(result);  
    60   
    61         if (!(result instanceof Result)) {  
    62             Assert.fail("Error return type.");  
    63         }  
    64   
    65         Assert.assertTrue(((Result) result).isSuccess());  
    66   
    67         Assert.assertNotNull(((Result) result).getSuccesMsg());  
    68   
    69         Object dbData = null;  
    70         try {  
    71             dbData = dataBaseDAO.readData("insert into db data...");  
    72         } catch (SQLException e) {  
    73             Assert.fail("read data from db error.");  
    74         }  
    75         Assert.assertEquals(((Result) result).getData(), dbData);  
    76   
    77     }  
    78   
    79     @AfterMethod  
    80     public void cleanData() {  
    81         try {  
    82             dataBaseDAO.delete("insert into db data...");  
    83         } catch (SQLException e) {  
    84             Assert.fail("Delete database error!");  
    85         }  
    86     }  
    87   
    88     @AfterClass  
    89     public void restoreEnv() {  
    90         functionSwitch.setAvaiable(env);  
    91     }  
    92   
    93 } 
     
     
    说明:

    1.其中beforeClass注解下,为整个test case运行所需要的基本环境,包括业务开关,上下游业务中所需要的其他服务的引入以及服务引入成功的判断,如果有一个服务都没有引入成功,其实该test case就没有必要执行,也就不需要浪费测试资源去执行了。

    2.beforeMethod注解下,可以提供本次测试方法(服务中有两个方法,其中一个就依赖了数据库中的内容,所以要初始化数据库。)所依赖的环境信息。

    3.两个after中,依次对数据和环境进行恢复,在CI情况下,本次执行的结果 有可能会影响到下次执行,所以,负责任的方法是,执行完本次test case后,就相应的进行环境和数据的清理,便于下次接口测试的顺利执行。

    建议:

    1.接口测试脚本的结构很重要,对于业务场景相似的情况,可以设置测试基类,将环境/数据的初始化放置在基类中;将测试执行和测试结果判断适当加以区分,这样逻辑会清晰,便于测试脚本维护。

    2.提高脚本复用程度,如采取参数化驱动,使用csv/txt/excel构建测试数据驱动,编写自己的dataProvider,解析测试数据,提高脚本的利用率,如上述脚本中,针对returnObject方法,可以构建

    a.数据初始化另一个返回结果

    b.数据初始化为空

    c.业务开关关闭

    等情况,并且测试数据和测试结果一一对应,都进行参数化,加上正常场景,相当于进行了4个业务场景的测试,能够极大减少回归测试的人工。

    3.为脚本执行后的副作用负责,主要是指,在脚本执行的过程中,难免会引入一些测试数据和对当前业务流的改动,在执行完成后,需要将这些执行痕迹清理和还原,一是便于手工测试的正常执行,而是为下次持续集成,减轻了错误概率。

  • 相关阅读:
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    xgqfrms™, xgqfrms® : xgqfrms's offical website of GitHub!
    分布式架构在农业银行的应用实践与展望
  • 原文地址:https://www.cnblogs.com/cheese320/p/8483437.html
Copyright © 2011-2022 走看看