Skip to content

Commit

Permalink
JENKINS-22060 Implemented test suite parsing from whole suite executi…
Browse files Browse the repository at this point in the history
…on time instead of just adding test case execution times together
  • Loading branch information
japiiron committed Mar 14, 2014
1 parent 1c5bb8b commit 33c6607
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 9 deletions.
3 changes: 3 additions & 0 deletions src/main/java/hudson/plugins/robot/RobotParser.java
Expand Up @@ -140,6 +140,9 @@ private RobotSuiteResult processSuite(XMLStreamReader reader, RobotTestObject pa
if ("FAIL".equals(reader.getAttributeValue(null, "status"))) {
suite.failTeardown();
}
} else if("status".equals(tagName)){
suite.setStartTime(reader.getAttributeValue(null, "starttime"));
suite.setEndTime(reader.getAttributeValue(null, "endtime"));
}
} else if (reader.isEndElement() && "suite".equals(reader.getLocalName())) {
return suite;
Expand Down
28 changes: 28 additions & 0 deletions src/main/java/hudson/plugins/robot/model/RobotSuiteResult.java
Expand Up @@ -20,24 +20,31 @@
import hudson.util.Graph;

import java.io.IOException;
import java.text.ParseException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;

public class RobotSuiteResult extends RobotTestObject {

private static final long serialVersionUID = 1L;

private static final Logger LOGGER = Logger.getLogger(RobotSuiteResult.class.getName());

private Map<String, RobotSuiteResult> children;
private RobotTestObject parent;
private String name;
private Map<String, RobotCaseResult> caseResults;
private String startTime;
private String endTime;
private transient int failed;
private transient int passed;
private transient int criticalPassed;
Expand Down Expand Up @@ -166,6 +173,27 @@ public void addCaseResult(RobotCaseResult caseResult) {
caseResults.put(caseResult.getDuplicateSafeName(), caseResult);
}

public void setStartTime(String startTime){
this.startTime = startTime;
}

public void setEndTime(String endTime){
this.endTime = endTime;
}

@Override
public long getDuration() {
if (StringUtils.isEmpty(this.startTime) || StringUtils.isEmpty(this.endTime))
return duration;

try{
return RobotCaseResult.timeDifference(this.startTime, this.endTime);
} catch (ParseException e){
LOGGER.warn("Couldn't parse duration for suite " + name);
return 0;
}
}

public String getDisplayName() {
return getName();
}
Expand Down
Expand Up @@ -31,7 +31,7 @@ limitations under the License.
<h1><j:if test="${it.critical}">Critical</j:if> test case: "${it.name}"</h1>
<j:set var="prevcase" value="${it.previousResult}" />
<div style="float:right;">
Test took ${it.humanReadableDuration} (${it.getDurationDiff(prevcase)})
Test execution took ${it.humanReadableDuration} (${it.getDurationDiff(prevcase)})
</div>
<h2 style="color:${headingColor};">${status}</h2>
<j:if test="${!it.isPassed()}">
Expand Down
Expand Up @@ -27,7 +27,7 @@ limitations under the License.
<div style="float:right;">
<img src="${rootURL}/images/16x16/notepad.gif"/><a href="report" title="Original report files">Original report files</a><br/>
Executed at ${it.timeStamp}<br/>
Tests took ${it.humanReadableDuration} (${it.getDurationDiff(prevresult)})
Suite execution took ${it.humanReadableDuration} (${it.getDurationDiff(prevresult)})
</div>
<j:if test="${it.overallFailed > 0}">
<h2 style="color:#c00;">${it.overallFailed} failed tests, ${it.criticalFailed} critical</h2>
Expand Down
Expand Up @@ -25,7 +25,7 @@ limitations under the License.
<h1>Testsuite: "${it.name}"</h1>
<j:set var="prevresult" value="${it.previousResult}" />
<div style="float:right;">
Tests took ${it.humanReadableDuration} (${it.getDurationDiff(prevresult)})
Suite execution took ${it.humanReadableDuration} (${it.getDurationDiff(prevresult)})
</div>
<j:if test="${it.failed > 0}">
<h2 style="color:#c00;">${it.failed} failed tests, ${it.criticalFailed} critical</h2>
Expand Down
Expand Up @@ -290,7 +290,7 @@ public void testReportPage() throws Exception {
HtmlPage page = wc.goTo("job/robot/robot/");
WebAssert.assertTextPresent(page, "Robot Framework test results");
WebAssert.assertTextPresent(page, "4 failed tests, 4 critical");
WebAssert.assertTextPresent(page, "Tests took 0:00:00.009 (+0:00:00.009)");
WebAssert.assertTextPresent(page, "Suite execution took 0:00:00.041 (+0:00:00.041)");
WebAssert.assertElementPresentByXPath(page, "//td[@id='main-panel']//a[@href='Testcases%20&%20Othercases/Testcases/Not%20equal' and contains(.,'Testcases & Othercases.Testcases.Not equal')]");
WebAssert.assertElementPresentByXPath(page, "//td[@id='main-panel']//a[@href='Testcases%20&%20Othercases/Othercases' and contains(.,'Testcases & Othercases.Othercases')]");

Expand All @@ -299,14 +299,14 @@ public void testReportPage() throws Exception {

page = wc.goTo("job/robot/1/robot/Testcases%20&%20Othercases");
WebAssert.assertTextPresent(page, "4 failed tests, 4 critical");
WebAssert.assertTextPresent(page, "Tests took 0:00:00.009 (+0:00:00.009)");
WebAssert.assertTextPresent(page, "Suite execution took 0:00:00.041 (+0:00:00.041)");
WebAssert.assertTextNotPresent(page, "All Testcases");
WebAssert.assertElementPresentByXPath(page, "//td[@id='main-panel']//a[@href='Testcases/Not%20equal' and contains(.,'Testcases.Not equal')]");
WebAssert.assertElementPresentByXPath(page, "//td[@id='main-panel']//a[@href='Othercases' and contains(.,'Othercases')]");

page = wc.goTo("job/robot/1/robot/Testcases%20&%20Othercases/Othercases");
WebAssert.assertTextPresent(page, "2 failed tests, 2 critical");
WebAssert.assertTextPresent(page, "Tests took 0:00:00.005 (+0:00:00.005)");
WebAssert.assertTextPresent(page, "Suite execution took 0:00:00.008 (+0:00:00.008)");
WebAssert.assertTextPresent(page, "All Testcases");
WebAssert.assertElementPresentByXPath(page, "//td[@id='main-panel']//a[@href='Not%20equal' and contains(.,'Not equal')]");
WebAssert.assertElementPresentByXPath(page, "//td[@id='main-panel']//a[@href='Contains%20string' and contains(.,'Contains string')]");
Expand All @@ -316,7 +316,7 @@ public void testReportPage() throws Exception {
WebAssert.assertTextPresent(page, "Failed!");
WebAssert.assertTextPresent(page, "Error message:");
WebAssert.assertTextPresent(page, "Hello, world! != Good bye, world!");
WebAssert.assertTextPresent(page, "Test took 0:00:00.001 (+0:00:00.001)");
WebAssert.assertTextPresent(page, "Test execution took 0:00:00.001 (+0:00:00.001)");
WebAssert.assertElementPresentByXPath(page, "//td[@id='main-panel']//img[@src='durationGraph']");

page = wc.goTo("job/robot/1/robot/Testcases%20&%20Othercases/Othercases/Contains%20string");
Expand Down
9 changes: 7 additions & 2 deletions src/test/java/hudson/plugins/robot/model/RobotResultTest.java
Expand Up @@ -18,7 +18,6 @@
import hudson.plugins.robot.RobotParser;

import java.io.File;
import java.net.URISyntaxException;
import java.util.List;

import junit.framework.TestCase;
Expand Down Expand Up @@ -151,7 +150,6 @@ public void testShouldReturnCaseById(){
assertEquals("Hello3rd", caseResult.getName());
}


public void testShouldParseSplittedOutput() throws Exception {
RobotParser.RobotParserCallable remoteOperation = new RobotParser.RobotParserCallable("testfile.xml");
result = remoteOperation.invoke(new File(new RobotSuiteResultTest().getClass().getResource("testfile.xml").toURI()).getParentFile(), null);
Expand All @@ -176,4 +174,11 @@ public void testShouldHandleNameCollisions() throws Exception {
assertEquals(3, failers.size());
}

public void testShouldParseWholeSuiteDuration() throws Exception {
RobotParser.RobotParserCallable remoteOperation = new RobotParser.RobotParserCallable("suite-setup-and-teardown.xml");
RobotResult res = remoteOperation.invoke(new File(new RobotSuiteResultTest().getClass().getResource("suite-setup-and-teardown.xml").toURI()).getParentFile(), null);
res.tally(null);
assertEquals(10141, res.getDuration());
}

}
@@ -0,0 +1,52 @@
<?xml version="1.0" encoding="UTF-8"?>
<robot generated="20140314 10:53:30.832" generator="Robot 2.8.3 (Python 2.7.5 on darwin)">
<suite source="robot-with-long-setuptimes/setuptimes.txt" id="s1" name="Setuptimes">
<kw type="setup" name="BuiltIn.Sleep">
<doc>Pauses the test executed for the given time.</doc>
<arguments>
<arg>5s</arg>
</arguments>
<msg timestamp="20140314 10:53:35.937" level="INFO">Slept 5 seconds</msg>
<status status="PASS" endtime="20140314 10:53:35.938" starttime="20140314 10:53:30.936"></status>
</kw>
<test id="s1-t1" name="Sleepy Test">
<kw type="kw" name="BuiltIn.Log">
<doc>Logs the given message with the given level.</doc>
<arguments>
<arg>Test with slow setup and teardown!</arg>
</arguments>
<msg timestamp="20140314 10:53:35.970" level="INFO">Test with slow setup and teardown!</msg>
<status status="PASS" endtime="20140314 10:53:35.970" starttime="20140314 10:53:35.969"></status>
</kw>
<doc></doc>
<tags>
</tags>
<status status="PASS" endtime="20140314 10:53:35.970" critical="yes" starttime="20140314 10:53:35.968"></status>
</test>
<kw type="teardown" name="BuiltIn.Sleep">
<doc>Pauses the test executed for the given time.</doc>
<arguments>
<arg>5s</arg>
</arguments>
<msg timestamp="20140314 10:53:40.973" level="INFO">Slept 5 seconds</msg>
<status status="PASS" endtime="20140314 10:53:40.973" starttime="20140314 10:53:35.971"></status>
</kw>
<doc></doc>
<metadata>
</metadata>
<status status="PASS" endtime="20140314 10:53:40.973" starttime="20140314 10:53:30.832"></status>
</suite>
<statistics>
<total>
<stat fail="0" pass="1">Critical Tests</stat>
<stat fail="0" pass="1">All Tests</stat>
</total>
<tag>
</tag>
<suite>
<stat fail="0" pass="1" id="s1" name="Setuptimes">Setuptimes</stat>
</suite>
</statistics>
<errors>
</errors>
</robot>

0 comments on commit 33c6607

Please sign in to comment.