[SoapUI] 比较两个不同环境下的XML Response, 从外部文件读取允许的偏差值,输出结果到文本文件

1. 获取TP和Live的xml response

2. 以其中一个数据点 ticker 为基准进行比较,ticker相同才进行比对

3. 从外部文件读取各个数据点允许的偏差值,偏差范围以内的不同认为是正常

4. API中的数据点提供的是Data ID, 而用户希望错误日志以UI上的Data Name进行打印,因此需要从外部文件读取Data ID和Data Name的映射关系

5. 计算Data point失败的比例

6. 将错误日志输出到本地的文本文件

import static  java.lang.Math.* 
import com.eviware.soapui.support.GroovyUtils
import com.eviware.soapui.support.XmlHolder
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

// The parameter allowableDeviation means the allowable deviation can be ? percent, e.g. allowableDeviation = 0.03 , the allowable deviation is 3%
def allowableDeviation

// Fail message
ArrayList failMessageList = new ArrayList()
String failMessage

//  Get test steps
def currentStepIndex = context.currentStepIndex
String currentStepName = testRunner.testCase.getTestStepAt(currentStepIndex).name
String previousStepName = testRunner.testCase.getTestStepAt(currentStepIndex-1).name
String prePreStepName = testRunner.testCase.getTestStepAt(currentStepIndex-2).name

//  File path
String testDataPath = testRunner.testCase.testSuite.project.getPropertyValue( "testDataPath" )
String dataIdMappingFile = testDataPath+"\DataIdMappingPA.xml"
String dataDeviationFile = testDataPath+"\RTQDataAllowableDeviation.xlsx"
String testResultPath = testRunner.testCase.testSuite.project.getPropertyValue( "testResultPath" )

//  Get allowable deviation
HashMap dataDeviationMap = getAllowableDeviation(dataDeviationFile)

// Get response
def groovyUtils = new GroovyUtils( context )
def xmlHolderLive = groovyUtils.getXmlHolder( prePreStepName+"#ResponseAsXml" )
def xmlHolderTP = groovyUtils.getXmlHolder( previousStepName+"#ResponseAsXml" )

// Get records
def nodesArrayLive = xmlHolderLive.getDomNodes("//B/I" )
def nodesArrayTP =xmlHolderTP.getDomNodes("//B/I")
List nodesListLive = nodesArrayLive.toList()
List nodesListTP = nodesArrayTP.toList()
int recordsNumberLive = nodesListLive.size()
int recordsNumberTP = nodesListTP.size()
log.info "Total Records Number on Live = "+recordsNumberLive
log.info "Total Records Number on TP = "+recordsNumberTP

// Failed records
int failedRecordsNumber=0

// Get Map of Data ID and Data Name
getMapOfDataIdAndNameFromExternelFile(dataIdMappingFile)
HashMap dataIDAndNameMap = new HashMap()
dataIDAndNameMap = getMapOfDataIdAndNameFromExternelFile(dataIdMappingFile)
def attributesNumber = nodesListLive.get(0).attributes.getLength()

// Get Map of Data Name and Data Value
HashMap  recordMapLive = new HashMap()
HashMap  recordMapTP = new HashMap()
def dataName
def dataValue
recordMapLive = getRecordMap(nodesListLive,recordsNumberLive,attributesNumber,dataIDAndNameMap,recordMapLive)
recordMapTP = getRecordMap(nodesListTP,recordsNumberTP,attributesNumber,dataIDAndNameMap,recordMapTP)

// Compare data value on TP and Live based on ticker
Iterator iter = recordMapLive.entrySet().iterator()
while (iter.hasNext()) {
	Map.Entry entry = (Map.Entry) iter.next()
	def ticker = entry.getKey()
	HashMap dataMapLive = entry.getValue()
	HashMap dataMapTP =recordMapTP.get(ticker)
	Iterator iter2 = dataMapLive.entrySet().iterator()
	while (iter2.hasNext()) {
		Map.Entry entry2 = (Map.Entry) iter2.next()
		def dataNameLive = entry2.getKey()
		def dataValueLive = entry2.getValue()
		def dataValueTP = dataMapTP.get(dataNameLive)

		if(dataValueTP==null){
			failMessage = "Ticker = "+ticker+" , Data Point = "+dataNameLive+" , TP = "+"Not Exist"+" , Live = "+dataValueLive
  			failMessageList.add(failMessage)
		}
		
		if(dataValueLive != dataValueTP){
			 if(((dataValueTP=="")&&(dataValueTP!=""))||((dataValueTP!="")&&(dataValueTP==""))){
	        		failMessage = "Ticker = "+ticker+" , Data Point = "+dataNameLive+" , TP = "+dataValueTP+" , Live = "+dataValueLive
       			failMessageList.add(failMessage)
	    		}
	    		
			if(dataValueLive.isFloat()&&dataValueTP.isFloat()){
				allowableDeviation = dataDeviationMap.get(dataNameLive)
				if(allowableDeviation==null){
					allowableDeviation=0
				}
				addFailMessageAboutFloatDiff(failMessageList,ticker,dataNameLive,dataValueTP,dataValueLive, allowableDeviation)
			}

			else{
				failMessage = "Ticker = "+ticker+" , Data Point = "+dataNameLive+" , TP = "+dataValueTP+" , Live = "+dataValueLive
       			failMessageList.add(failMessage)
			}
		}
	}
}	

// Get total data points number
int totalDataPointsNumber = recordsNumberLive*attributesNumber
log.info "Total Data Points Number = "+totalDataPointsNumber

// Get failed data points number
int failedDataPointsNumber = failMessageList.size()
log.info "Failed Data Points Number = "+failedDataPointsNumber
def failedPercentage = failedDataPointsNumber/totalDataPointsNumber
log.error "Failed Data Points Percentage = "+((int)(failedPercentage*10000))/100+"%"

// Print out all failed data points
if(failedDataPointsNumber>0){
	def testResultFile = new File(testResultPath+ currentStepName+".txt")  
     if (testResultFile.exists()) {
		 testResultFile.delete()
     }
	for(j=0; j<failedDataPointsNumber; j++){
		String currentFailMessage = failMessageList.get(j)
		log.error currentFailMessage
	     testResultFile.append(currentFailMessage+"
" )
	}
	assert false,failMessageList.get(0)
}

// Get map of ticker and other data points list
def getRecordMap(List nodesList,int recordsNumber,int attributesNumber,HashMap dataIDAndNameMap,HashMap recordMap){
	HashMap map = new HashMap()
	for(int i=0;i<recordsNumber;i++){
		attributes = nodesList.get(i).getAttributes()
		ticker = attributes.item(3).value
		if(ticker!=""){
			HashMap dataMap = new HashMap()
			for(int j=4;j<attributesNumber;j++){
				dataID = attributes.item(j).name
				dataName = dataIDAndNameMap.get(dataID)
				dataValue = attributes.item(j).value
				dataMap.put(dataName,dataValue)
			}
			map.put(ticker,dataMap)
		}
	}
	return map
}

// Get map of Data ID and Data Name from externel file
def getMapOfDataIdAndNameFromExternelFile(String dataIdMappingFile){
	HashMap map = new HashMap()
    def xmlDataIdMapping= new XmlParser().parse(dataIdMappingFile)
    for(it in xmlDataIdMapping.f){
        	String mapDataID =  "${it.attribute("i")}"
         	String mapDataName =  "${it.attribute("udlbl")}"
         	map.put(mapDataID, mapDataName)	
     }
     return map
}

// Add fail message when two float data is different
def addFailMessageAboutFloatDiff(ArrayList failMessageList,String ticker,String dataName,String dataValueStringTP,String dataValueStringLive,def allowableDeviation){
	Float dataValueTP = dataValueStringTP.toFloat()
     Float dataValueLive = dataValueStringLive.toFloat()

     if ((dataValueLive ==0)&&(dataValueTP == 0)){
		return
	}

	Float benchmark = dataValueLive
	if (dataValueLive ==0){
		benchmark = dataValueTP
	}
	   
	if(Math.abs((dataValueLive-dataValueTP )/benchmark)>allowableDeviation){  
		failMessage ="Ticker = "+ticker+" , Data Point = "+dataName+" , TP = "+dataValueTP+" , Live = "+dataValueLive+" , Allowable Deviation = "+allowableDeviation
		failMessageList.add(failMessage)
	 }
}

// Get allowable deviation from externel file
def getAllowableDeviation(String dataDeviationFile){
	HashMap map = new HashMap()
	File file = new File(dataDeviationFile)
	try{
 		XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(dataDeviationFile))
        	XSSFSheet sheet = wb.getSheetAt(0)
        	Row row
        	Cell cellDataName
        	Cell cellDataDeviation
        	int rows = sheet.physicalNumberOfRows
        	def dataName
        	def dataDeviation
        	(1..<rows).each{ r ->
        		row = sheet.getRow(r)
        		if (row != null){  
        			cellDataName = row.getCell(1)
        			cellDataDeviation = row.getCell(2)
        			if (cellDataName != null){
        				dataName = cellDataName.getStringCellValue()
        			}
        			if (cellDataDeviation != null){
        				switch (cellDataDeviation.getCellType()){
			                case cellDataDeviation.CELL_TYPE_NUMERIC:
		                        dataDeviation = cellDataDeviation.getNumericCellValue()
		                        break
			 
			                case cellDataDeviation.CELL_TYPE_STRING:
		                        dataDeviation = cellDataDeviation.getStringCellValue()
		                        break
			 
			                case cellDataDeviation.CELL_TYPE_BLANK:
		                        break
			 
			                default:
		                        break
	      			}
        			}
        		}
   			map.put(dataName,dataDeviation)
        	}
        	return map
	 }
	 catch (Exception e){
	 	 log.info "Exception :" + e.getMessage()
	 }
}

  

原文地址:https://www.cnblogs.com/MasterMonkInTemple/p/4635721.html