2014-10-09 36 views
0

我的API調用響應返回2,000個患者。是否可以在SoapUI Pro XML DataSource中選擇隨機樣本百分比的XML節點?

我創建了一個XML DataSource來創建返回患者的屬性列表。如果我把在行的Xpath場下,所有2000名患者被添加爲屬性:

//PatientInfo[1]/Patient 

如果我用這個,只有第一個病人加入一個屬性:

//PatientInfo[1]/Patient[1] 

我想要什麼要做的只是將1%的患者轉換爲屬性。例如:

//PatientInfo[1]/Patient[Random 1 Percent] 

這是XPath中可能的東西嗎?

回答

2

可以使用subsequence XPath函數,指定subsequence(items, start, length)從由length參數指定的項目數start參數位置返回的items的序列。

你的情況,例如,以獲得10個第一<patient>節點上,您可以使用:

subsequence(//PatientInfo[1]/Patient,1,10)

如果你想獲得總<Patient>節點的百分比,可以同時使用subsequence功能與count爲了計算總的子節點,並且還需要div*round爲了得到一個非浮動的百分比數,這一切都在一起可能是:

subsequence(//PatientInfo[1]/Patient, 1, round(count(//PatientInfo[1]/Patient) div 100 * 1))

如果這round(count(//PatientInfo[1]/Patient) div 100 * 1)1%個圓,先算所有患者的節點,這個劃分爲100繁衍爲您的百分比。

請注意,我沒有SOAPUI PRO,所以我不能使用數據源來檢查它是否工作,但是我在SOAPUI的其他部分使用subsequence XPath函數來實現類似於您的目標。我用的是後續常規例子來檢查這個XPath該工程按預期:

import javax.xml.transform.TransformerFactory 
import javax.xml.transform.Transformer 
import javax.xml.transform.dom.DOMSource 
import javax.xml.transform.stream.StreamResult 

// xml sample to get Patient nodes 
def xml = '<PatientInfo><Patient>1</Patient><Patient>2</Patient><Patient>3</Patient><Patient>4</Patient></PatientInfo>' 

// xmlHolder to perform an XPath 
def xmlHolder = new com.eviware.soapui.support.XmlHolder(xml) 

// get the 50% of patients (in the sample 2 nodes) 
// with XPath 
def nodes = xmlHolder.getDomNodes("subsequence(//PatientInfo[1]/Patient, 1, round(count(//PatientInfo[1]/Patient) div 100 * 50))") 

// print the nodes to check that only 2 first 
// patient nodes where selected by the xpath 
nodes.each{ n -> log.info printDocument(n)} 

// this function is to print xml as string 
// it's purpose it's only to log the info 
def printDocument(node) { 
    TransformerFactory tf = TransformerFactory.newInstance() 
    Transformer transformer = tf.newTransformer() 
    StringWriter writer = new StringWriter() 
    transformer.transform(new DOMSource(node), new StreamResult(writer)) 
    return writer.getBuffer().toString() 
} 

編輯基於OP評論:

關於你的新的要求,我認爲是存在的XPath沒有隨機函數,但是你可以與unordered(items)函數試圖讓<patient>無序的,但是這個功能的隨機性取決於實現,我不知道這是否正常工作在SOAPUI,表達可以是:

subsequence(unordered(//PatientInfo[1]/Patient), 1, round(count(//PatientInfo[1]/Patient) div 100 * 50)) 

另一種可能是使用groovy來填充您的數據源,將groovy組合成一個隨機數作爲subsequence函數的起始點,並使用XPath來獲取<patient>節點。如果你有你的XML響應的測試步驟,你可以修改我前面的例子可以直接在XPath適用於它,代碼可能是:

import javax.xml.transform.TransformerFactory 
import javax.xml.transform.Transformer 
import javax.xml.transform.dom.DOMSource 
import javax.xml.transform.stream.StreamResult 
import java.util.Random 

// random number 
def random = new Random(); 
// random as start point for subsequence 
// use a number which doesn't exceed the number of patient nodes... 
// you can use count(//PatientInfo[1]/Patient) to know the max number however 
// you have to use a less number to start... 
def start = random.nextInt(500) 

// define the xpath to get 50% of patients starting 
// to get patients from a random point in array 
def xpath = 'subsequence(//PatientInfo[1]/Patient,' + start +', round(count(//PatientInfo[1]/Patient) div 100 * 50))' 

// access test request response 
def response = context.expand('${YourRequestTestName#response}') 

// xmlHolder to perform an XPath 
def xmlHolder = new com.eviware.soapui.support.XmlHolder(response) 

// get nodes 
def nodes = xmlHolder.getDomNodes(xpath) 

// print the nodes to check that only 2 first 
// patient nodes where selected by the xpath 
nodes.each{ n -> log.info printDocument(n)} 

// this function is to print xml as string 
// it's purpose it's only to log the info 
def printDocument(node) { 
    TransformerFactory tf = TransformerFactory.newInstance() 
    Transformer transformer = tf.newTransformer() 
    StringWriter writer = new StringWriter() 
    transformer.transform(new DOMSource(node), new StreamResult(writer)) 
    return writer.getBuffer().toString() 
} 

希望這有助於

+0

哇,完美的作品!非常感謝! – MattJ 2014-10-09 15:36:28

+0

這對於能夠選擇第一個1%是完美的。謝謝!我希望隨機抽取1%的樣本,以便每次進行測試時都有可能對不同的患者進行評估。你會知道如何增加隨機性嗎? – MattJ 2014-10-09 15:54:08

+0

@MattJoe關於你的新問題我認爲在XPath中沒有隨機函數,然而你可以試着用'無序(items)'函數來獲得無序的 ...但是這個函數的隨機性取決於實現, m不知道它是否在soapui中正常工作,表達式可能是:'subsequence(unordered(// PatientInfo [1]/Patient),1,round(count(// PatientInfo [1]/Patient)div 100 * 50) )'。 – albciff 2014-10-09 21:42:21