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+"\n" ) } 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() } }