手把手教你接口自動化測試 – SoapUI & Groovy

手把手教你接口自動化測試 – SoapUI & Groovyhtml

http://www.cnblogs.com/wade-xu/p/4236295.html java

 

關鍵詞:SoapUI接口測試,接口自動化測試,數據驅動測試,SoapUI進階使用, Groovy in SoapUI, SoapUI中Groovy的使用,數據分離。node

 

閱讀這篇文章須要必定的SoapUI基礎,至少入過門,另外還須要一些Groovy的知識,固然若是你會java 也能夠,這裏用到的Groovy知識和Java很相似。web

另外,本文的思路和我上一篇文章<零成本實現接口自動化測試 – Java+TestNG 測試Restful service>很類似,只不過把Java+TestNG的組合換成了SoapUI+Groovy, 另外測試對象也換成了基於Soap的web service, 依舊用Excel來管理數據,作到數據分離。數組

因爲我用到的SoapUI是免費版本,相比Pro版,少不少的功能,像DataLoop之類的,因此只能經過Groovy寫一些腳原本作數據驅動的測試。app

 

首先打開SoapUI, 新建一個Workspace 名爲Demoide

 

 

而後點擊File->New soapUI Projectoop

 

而後輸入你的Project Name, WSDL 地址 點擊OK測試

 

 

輸入服務的用戶名密碼 點擊OKui

 

項目工程建好了

 

右擊ServicePort 創建TestSuite

 

以其中一個接口爲例 來生成用例

 

輸入TestSuite name 而後確認

工程結構以下

 

 

經過右擊TestCase -> Add Step  增長 Groovy Script 和 Properties

 

增長四個Groovy Script, 而且命名成 Start, Process, Check Response, End

增長5個 Properties, 而且命名成Input, Baseline, Output, Result, fieldResult

調整它們的順序,最後造成下圖的工程目錄結構

 

 

Start腳本主要建立log文件

/*Check the log file, create folder and file if necessary*/
import java.io.*;

def cal = Calendar.instance;
def sysdate = cal.getTime();
def Y = cal.get(Calendar.YEAR); 
def M = cal.get(Calendar.MONTH)+1; 
def D = cal.get(Calendar.DATE);
if (D<10) D = "0"+D; 
if (M<10) M = "0"+M; 
date = Y+"-"+M+"-"+D;
time=sysdate.toString().replaceAll(':','-')

def testSuites=testRunner.testCase.getTestSuite();
def testcase = testRunner.testCase;

def logFolder = new File(context.expand('${#Project#LogFolder}'));
def responseLogName = (context.expand('${#Project#LogFolder}')+date+'\\'+testSuites.name+' - '+ testcase.name +' - ' + time+".log");
def responseDetailLogName = (context.expand('${#Project#LogFolder}')+date+'\\'+testSuites.name+' - ' + testcase.name +' - ' + time + " Response Detail.log");
def responseLogFile = new File(responseLogName);
def responseDetailLogFile = new File(responseDetailLogName);
def subFolder= new File (context.expand('${#Project#LogFolder}')+date+'\\')

/*Set date and Log Name to Project - Testcase Properties*/
testcase.setPropertyValue('date', date);
testcase.setPropertyValue('LogFile - Check Response', responseLogName);
testcase.setPropertyValue('LogFile - Response Detail', responseDetailLogName);

if(!logFolder.exists()){
    logFolder.mkdirs();
    }

if(!subFolder.exists()){
    subFolder.mkdirs();
    }

/*Check the file, create a new one if not found*/
if(!responseLogFile.exists()){
    responseLogFile.createNewFile();
    }
responseLogFile.append("---------------Test Start on "+sysdate+" ------------------------"+'\n');

if(!responseDetailLogFile.exists()){
    responseDetailLogFile.createNewFile();
    }
responseDetailLogFile.append("---------------Test Start on "+sysdate+" ------------------------"+'\n');
View Script - Start

 

Process腳本是整個工程的核心,讀取Excel數據文件的Input, Baseline 放入二維數組,而後循環讀入Input和Baseline這兩個Properties, 調用request, 取到Ouput和Result Properties的值放入Output, Result數組,最後更新Excel的Output, Result, Comparison sheet。

import java.io.*;
import jxl.*;
import java.text.DecimalFormat;

def readInput(workbook,inputSheetName)
{    
    Sheet sheet=workbook.getSheet(inputSheetName);
            
    rows = sheet.getRows();
    columns = sheet.getColumns();
    
/*Get content into array*/
    input = new Object [columns][rows]
    for (a=0;a<columns;a++)
        {
        for (b=0;b<rows;b++)
            {
                input[a][b]= sheet.getCell(a,b).getContents();
            }
        }
}

def readBaseline(workbook,sheetName)
{    
    Sheet sheet=workbook.getSheet(sheetName);
            
    Rows = sheet.getRows(); 
    Columns = sheet.getColumns();
    
/*Get content into array*/
    baseline = new Object [Columns][Rows]
    for (a=0;a<Columns;a++)
        {
        for (b=0;b<Rows;b++)
            {
                baseline[a][b]= sheet.getCell(a,b).getContents();
            }
        }
}

def updateOutput(writableWorkbook,sheetName,start_row,rows,columnNo,result,resultTag){
    
        Sheet[] sheet= writableWorkbook.getSheets();
        ws = writableWorkbook.getSheet(sheetName);
        if(ws==null){
        ws = writableWorkbook.createSheet(sheetName,sheet.length)
        }
        for (a=0;a<columnNo;a++)
        {
            ws.addCell(new jxl.write.Label(a,0,result[a][0]));
            for (b=start_row;b<rows;b++)
            {
                wc = new jxl.write.WritableCellFormat();
                if (resultTag[a][b]=='PASS')            
                {
                    wc.setBackground(jxl.format.Colour.WHITE);
                    ws.addCell(new jxl.write.Label(a,b,result[a][b],wc));
                }
                else if(resultTag[a][b]=='FAIL'){
                    wc.setBackground(jxl.format.Colour.RED);
                    ws.addCell(new jxl.write.Label(a,b,result[a][b],wc));
                }
            }
        }
}

def updateResult(writableWorkbook,sheetName,start_row,rows,columnNo,result){
    
        Sheet[] sheet= writableWorkbook.getSheets();
        ws = writableWorkbook.getSheet(sheetName);
        if(ws==null){
        ws = writableWorkbook.createSheet(sheetName,sheet.length)
        }
        for (a=0;a<columnNo;a++)
        {
            ws.addCell(new jxl.write.Label(a,0,result[a][0]));
            for (b=start_row;b<rows;b++)
            {
               wcf = new jxl.write.WritableCellFormat();
               wcf.setBackground(jxl.format.Colour.RED);
               
                  if(result[a][b] == 'FAIL'){
                       ws.addCell(new jxl.write.Label(a,b,result[a][b],wcf));
                  }    else             
                    ws.addCell(new jxl.write.Label(a,b,result[a][b]));
            }
        }

        wc = new jxl.write.WritableCellFormat();
          wcc = new jxl.write.WritableCellFormat();
          wc.setBackground(jxl.format.Colour.GRAY_25);
          wcc.setBackground(jxl.format.Colour.LIGHT_TURQUOISE);
          ws.addCell(new jxl.write.Label(0,rows-3,result[0][rows-3],wcc));   
          ws.addCell(new jxl.write.Label(0,rows-2,result[0][rows-2],wc));
        ws.addCell(new jxl.write.Label(0,rows-1,result[0][rows-1],wc));
        
}

def updateComparison(writableWorkbook,sheetName,start_row,rows,columnNo,output,outputTag,result,baseline){
    
        Sheet[] sheet= writableWorkbook.getSheets();
        ws = writableWorkbook.getSheet(sheetName);
        if(ws==null){
        ws = writableWorkbook.createSheet(sheetName,sheet.length)
        }
        for (a=0;a<columnNo;a++)
        {
            ws.addCell(new jxl.write.Label(a,0,output[a][0]));
            
            x= 1;
            for (b=start_row;b<rows;b++)
            {
                if(result[1][b] == 'FAIL'){
                  wc = new jxl.write.WritableCellFormat();
                  if (outputTag[a][b]=='PASS')            
                  {
                        wc.setBackground(jxl.format.Colour.WHITE);
                     ws.addCell(new jxl.write.Label(a,x,output[a][b],wc));                     
                  }
                  else {
                     wc.setBackground(jxl.format.Colour.RED);
                     ws.addCell(new jxl.write.Label(a,x,output[a][b],wc));
                  }
                wbc = new jxl.write.WritableCellFormat();
                 wbc.setBackground(jxl.format.Colour.ICE_BLUE);
                ws.addCell(new jxl.write.Label(a,x+1,baseline[a][b],wbc));
                x+=2; 
              }
            }
        }
}

def removeSheetByName(writableWorkbook, name){
    
        Sheet[] sheet= writableWorkbook.getSheets();    
        ws = writableWorkbook.getSheet(name);
        if(ws != null){
            for (i = 0; i < sheet.length; i++) {
                sheetName = writableWorkbook.getSheet(i).getName();            
                if (sheetName.equalsIgnoreCase(name)) {
                    writableWorkbook.removeSheet(i);
                }
            }
        }
}

def setProperties(Name,Value,Place)
{    
    name = Name;
    target = testRunner.testCase.getTestStepByName(Place);
    target.setPropertyValue(name,Value);
    }

def cleanProperty(PropertyListName)
{
         PropertyList = testRunner.testCase.getTestStepByName(PropertyListName);
         size=PropertyList.getPropertyCount();
         if (size!=0)
         {
                   for (i=0;i<size;i++)
                   {
                            PropertyList.removeProperty(PropertyList.getPropertyAt(0).name);
                   }
         }
}

def logFile = new File(context.expand('${#TestCase#LogFile - Check Response}'));
def xlsName = context.expand('${#TestCase#Workbook}');

def project = testRunner.testCase.getTestSuite().getProject();
def testSuite = testRunner.testCase.getTestSuite();
def testcase = testRunner.testCase
def requests = testcase.getTestStepsOfType( com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep.class )
def request = requests[0];

inputSheetName = "Input";
baselineSheet = "Baseline";
outputSheet = "Output";
resultSheet = "Result";
fieldResult = testcase.getTestStepByName('fieldResult');
ComparisonSheet = "Comparison";

Baseline = testcase.getTestStepByName(baselineSheet);
baselineSize = Baseline.getPropertyCount();
Output = testcase.getTestStepByName(outputSheet);

def cal = Calendar.instance;
def sysdate = cal.getTime();
sleepTime=context.expand('${#Project#sleepTime}').toInteger()

try{    
       Workbook workbook=Workbook.getWorkbook(new File(xlsName));
       cleanProperty(inputSheetName);
       readInput(workbook,inputSheetName);
      
    for (i=0;i<columns;i++)
    {
      setProperties(input[i][0],'',inputSheetName)
    }

      cleanProperty(baselineSheet);
      readBaseline(workbook,baselineSheet);
    for (i=0;i<Columns;i++)
    {
      setProperties(baseline[i][0],'',baselineSheet)
    }
       workbook.close();
       
}catch(Exception e){
      e.printStackTrace();
}
        
/*-----------Set runSelect as 'true' in Project property to run selected test cases from startTag till endTag-------*/
def runSelected = context.expand('${#Project#runSelected}')
start_Test=1;
end_Test=rows-1;

def passNumbers = 0;
def decFormat = new DecimalFormat("##.00%"); 


if ('true'.equalsIgnoreCase(runSelected))
{
    startTag=context.expand('${#Project#startTag}').toInteger();
     endTag=context.expand('${#Project#endTag}').toInteger();
     
    if((0<startTag)&&(startTag<rows)&&(endTag>=startTag)&&(rows>endTag)){
    start_Test=startTag;
    end_Test=endTag;
    }
}
    
    result = new Object [2][rows+3]
    result[0][0]='Case Description';
    result[1][0]='Result'
    result[0][rows+1]='Start Time:';
    result[1][rows+1]=sysdate.toString();
    
/*--New object and put the output name and value into this list--*/
    output = new Object [baselineSize][rows]
    outputTag = new Object [baselineSize][rows]
    for (i=0;i<baselineSize;i++)
    {
        output[i][0]= Baseline.getPropertyAt(i).name;
        outputTag[i][0]= 'PASS';
        }
        
    for (m=start_Test;m<=end_Test;m++)
    {
         logFile.append('\n'+ testcase.name + ": "+m+" "+ ". "+sysdate+'\n');
        for (i=0;i<columns;i++)
        {
            setProperties(input[i][0],input[i][m],inputSheetName)
        }
        for (j=0;j<Columns;j++)
        {    
             setProperties(baseline[j][0],baseline[j][m],baselineSheet)
        }
            
        testRunner.runTestStepByName(request.name);
        Thread.sleep(sleepTime);
        testRunner.runTestStepByName("Check Response");
                
        result[0][m]=context.expand('${'+inputSheetName+'#Case Description}')
        result[1][m]=context.expand('${'+resultSheet+'#result}')

        if(result[1][m] == 'PASS'){
                 passNumbers++;
        }
        
        for (i=0;i<baselineSize;i++)
        {
            output[i][m]= Output.getPropertyAt(i).value;
            outputTag[i][m]= fieldResult.getPropertyAt(i).value;
        }
}
          result[0][rows+2]='End Time:';
          result[1][rows+2]=sysdate.toString();
          result[0][rows]='Pass Percentage:';
          
          passPercentage = decFormat.format(passNumbers/(end_Test-start_Test+1));
          result[1][rows] = passPercentage

/*--------------Update Output, Result, Comparison sheet---------*/
    try{
        workbook = Workbook.getWorkbook(new File(xlsName));
        writableWorkbook =  Workbook.createWorkbook(new File(xlsName), workbook);

        updateOutput(writableWorkbook,outputSheet,start_Test,end_Test+1,baselineSize,output,outputTag);
        updateResult(writableWorkbook,resultSheet,start_Test,rows+3,2,result);

        removeSheetByName(writableWorkbook,ComparisonSheet);
                  
        if(passPercentage != '100.00%'){
               updateComparison(writableWorkbook,ComparisonSheet,start_Test,end_Test+1,baselineSize,output,outputTag,result,baseline);
          }

          writableWorkbook.write();
        writableWorkbook.close();   
        workbook.close();
        
        }catch(Exception e){
            e.printStackTrace();
        }
           
          setProperties('passPercentage', passPercentage ,'Result');
          
        testRunner.gotoStepByName('End');
        
View Script - Process

 

Check Response 顧名思義,用來檢查返回結果, 經過XmlHolder getNodeValue 來取response各節點的值,而且填入Output Properties已做對比之用。

import java.lang.*;
import java.util.*;
import groovy.lang.*;
import groovy.util.*;
import com.eviware.soapui.support.XmlHolder

baselineSheet = "Baseline";
outputSheet = "Output";
resultSheet = "Result";

def testcase = testRunner.testCase;
Baseline = testcase.getTestStepByName(baselineSheet)
baselineSize = Baseline.getPropertyCount();
Output = testcase.getTestStepByName(outputSheet);

def requests = testcase.getTestStepsOfType( com.eviware.soapui.impl.wsdl.teststeps.WsdlTestRequestStep.class )
def request = requests[0];
def response = request.testRequest.response;

respXmlHolder = new XmlHolder(response.contentAsXml)

//declare namespace in xml response
respXmlHolder.declareNamespace("ns1", "http://schemas.xxx.com/v201203/yourservice")

def statusCode = request.testRequest.response.responseHeaders["#status#"].toString();

def setProperties(Name,Value,Place){              
       name = Name;
       target = testRunner.testCase.getTestStepByName(Place);
       target.setPropertyValue(name,Value);
}

def getspecifiedValue(field){
      prefix = "//ns1:";
       nodePath = "${prefix}${field}"
       specifiedValue = respXmlHolder.getNodeValue("${nodePath}")
}

testRunner.testCase.getTestStepByName(outputSheet).clearPropertyValues();

//normal output, status = '200 OK'
if(statusCode.contains('200 OK')){
       for (i=1;i<baselineSize;i++)
       {
               specifiedName = Baseline.getPropertyAt(i).name;
               specifiedValue = getspecifiedValue(specifiedName);
               if(specifiedValue != null){
               setProperties(specifiedName,specifiedValue,outputSheet)
               } else  {
                   setProperties(specifiedName,'',outputSheet)
               }            
       }
    
} else
       { 
           setProperties(Baseline.getPropertyAt(0).name,Baseline.getPropertyAt(0).value,outputSheet);
         setProperties(Baseline.getPropertyAt(1).name,statusCode,outputSheet);
         
          for(t=2; t<baselineSize; t++){
            setProperties(Baseline.getPropertyAt(t).name, '' ,outputSheet);   
       }
}

setProperties(Baseline.getPropertyAt(0).name,Baseline.getPropertyAt(0).value,outputSheet);
setProperties('result','PASS', resultSheet);


logFile = new File(context.expand('${#TestCase#LogFile - Check Response}'));
responseDetailLogFile= new File(context.expand('${#TestCase#LogFile - Response Detail}'));

logFile.append(" ------                   Start Response Check "+ " @ "+Calendar.instance.getTime()+"\n");
responseDetailLogFile.append("\n"+ testcase.name + " -- " + Baseline.getPropertyAt(0).value+ "\n" + response+"\n");


/*--------Compare the result with Baseline and update the result accordingly---------*/

for (i=0;i<baselineSize;i++)
{
         if (Baseline.getPropertyAt(i).value==Output.getPropertyAt(i).value)
                {
                      setProperties(Baseline.getPropertyAt(i).name,'PASS','fieldResult');
       }
               else
                {
                       setProperties(Baseline.getPropertyAt(i).name,'FAIL','fieldResult');
                       setProperties('result','FAIL','Result');
         }
 }
View Script - Check Response

 

End腳本 在log上打時間戳

def cal = Calendar.instance;
def sysdate = cal.getTime();

responseLogFile = new File(context.expand('${#TestCase#LogFile - Check Response}'));
responseDetailLogFile= new File(context.expand('${#TestCase#LogFile - Response Detail}'));

responseLogFile.append('\n'+ "---------------Test End on " + sysdate.toString() + " ------------------------"+'\n');
responseDetailLogFile.append('\n'+ "---------------Test End on " + sysdate.toString() + " ------------------------"+'\n');
View Script - End

 

配置

雙擊DemoProject, 點擊下方的Properties tab

而後 Add property

Add 以下圖所示的5個Property

 

雙擊項目工程列表裏的'Demo TestCase'

點擊Properties tab

Add Property 如圖

 

Value 填Excel 的路徑

 

Excel數據工做簿裏的Input sheet 如圖

 

接下來須要把Input裏的column name 與 Soap request裏的input 字段映射起來

雙擊Test Steps 裏的request

將xml文件裏的?用參數來代替

左下角的TestRequest Properties  要填上用戶名 密碼

 

Baseline sheet裏要把輸出結果的字段名都定義好, 由於是根據字段名去response裏取結果的

每條用例指望結果都寫好,用做和實際結果對比

 

另外Check Response裏的腳本須要設置一下

假設你的response xml文件結構以下

若是你須要檢查Soap body標籤下的內容, 則你須要配置一下Check Response的腳本

將xml namespace的路徑配置一下

 

右擊Project  Save一下Project 

最後能夠運行了 雙擊Demo TestSuite  點擊Run

注意:Groovy腳本也是用第三方的jxl.jar操做excel文件的,因此這個jar須要放到SoapUI安裝目錄的\lib下面,才能運行成功。

 

打開Workbook 數據工做簿查看結果

Output

Result

Comparison

 

是否是跟我上一篇文章殊途同歸?

 

 

注:轉載需註明出處及做者名,嚴禁惡意轉載,尊重原做者的勞動成果。

相關文章
相關標籤/搜索