我正在使用此脚本编辑XML文件。 TestNG使用此XML文件来运行测试。它包含有关我想要运行的测试的信息。运行测试后,我想更新XML文件,例如,测试结果的位置。
我写了这个脚本来做我想做的事情;
public void editXMLFile(String nameOfTest, String resultLoc){
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setNamespaceAware(true);
DocumentBuilder builder;
Document doc = null;
try {
builder = factory.newDocumentBuilder();
doc = builder.parse("testng.xml");
NodeList tests = doc.getElementsByTagName("test");
Element test = null;
for (int i = 0; i < tests.getLength(); i++) {
test = (Element) tests.item(i);
String testNames = test.getAttribute("name");
if (testNames.equals(nameOfTest)) {
//System.out.println("Found element!");
NodeList params = test.getElementsByTagName("parameter");
Element runType = null, baselineLocation = null;
for (int i1 = 0; i1 < params.getLength(); i1++) {
runType = (Element) params.item(i1);
String paramNames = runType.getAttribute("name");
if (paramNames.equalsIgnoreCase("runType")) {
//System.out.println("Found the runType");
if (runType.getAttribute("value").equalsIgnoreCase(
"baseline")) {
for (int j = 0; j < params.getLength(); j++) {
baselineLocation = (Element) params.item(j);
if (baselineLocation.getAttribute("name")
.equalsIgnoreCase("baselineLocation")) {
//System.out.println("Found baselineLocation!");
runType.setAttribute("value", "actual");
baselineLocation.setAttribute("value", resultLoc);
System.out.println("resultLoc = " + resultLoc);
System.out.println("Test name = " + _testName);
// Prepare the DOM document for writing
Source source = new DOMSource(doc);
// Prepare the output file
File file = new File("C:/Users/sfd/Desktop/testng.xml");
StreamResult sr = new StreamResult(file);
Result result = sr;
// Write the DOM document to the file
Transformer xformer = TransformerFactory
.newInstance().newTransformer();
xformer.transform(source, result);
}
}
}
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
这是XML文件;
<?xml version="1.0" encoding="UTF-8"?>
<suite name="Test Suite Name" parallel="none">
<listeners>
<listener class-name="testng.MyListener"></listener>
</listeners>
<test name="Test NOT on localhost">
<parameter name="Browser" value="chrome"/> <!-- chrome or firefox or IE or Android Native-->
<parameter name="url" value='' /> <!-- URL of the webpage you want to test -->
<parameter name="CSV" value="testdata.csv"/> <!-- Location of the CSV file that you want to run tests with -->
<parameter name="resultLocation" value="C:\Users\sfd\Desktop"/> <!-- TestNG will create two folder in this location, screenshots and test-output-datestamp -->
<parameter name="baselineLocation" value=""/> <!-- Location of the baseline location -->
<parameter name="runType" value="baseline" /> <!-- actual or baseline . baseline = first run. actual is second run, to do a compare for example -->
<classes>
<class name="testng.runTest"></class>
</classes>
</test> <!-- Test CAN YOU SEE THIS?-->
<test name="Test localhost">
<parameter name="Browser" value="chrome"/> <!-- chrome or firefox or IE or Android Native-->
<parameter name="url" value='' />
<parameter name="CSV" value="testdata.csv"/>
<parameter name="resultLocation" value="C:\Users\sfd\Desktop\testmap"/> <!-- TestNG will create two folder in this location, screenshots and test-output-datestamp -->
<parameter name="baselineLocation" value=""/> <!-- Location of the baseline run. leave value empty. This will be filled in by TestNG itself. -->
<parameter name="runType" value="baseline" /> <!-- actual or baseline . baseline = first run. actual is second run, to do a compare for example -->
<classes>
<class name="testng.runTest"></class>
</classes>
</test>
</suite> <!-- Suite end of suite -->
我面临的问题是以下问题;当我在xml文件中只有一个测试时,它工作正常。但是当我在XML文件中有多个测试时,只会更新最后一个测试。应更新两个测试的baselineLocation,而只更新最后一个测试。我认为这种方法的逻辑存在缺陷,但我不确定究竟是什么。
答案 0 :(得分:1)
如果您多次调用editXMLFile()来更新多个测试名称,则会出现问题。您正在该方法中编写更新的XML文件。由一个测试名称匹配创建的XML将被后续测试名称匹配条件覆盖。
您需要推迟编写XML文件,直到您使用所有测试名称更新doc对象。
重构的一种可能解决方案
private Document createXMLDocument() // move the XML document for test.xml logic into this method
public Document editXMLFile(Document doc, String nameOfTest, String resultLoc) // assuming you don't have any constraint on method signature. Return back updated Document object.
private Document getUpdatedXMLDocument(Document doc) // move your filtering condition logic into this. Call this from editXMLFile()
private void writeUpdatedXMLFile(Document doc) // move out the logic of writing the new XML file here. Call this after final call to editXMLFile()
希望这给出了一个公平的想法。