/******************************************************************************* * Copyright (c) 2017 BREDEX GmbH. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * BREDEX GmbH - initial API and implementation and/or initial documentation *******************************************************************************/ package org.eclipse.jubula.client.core.exporter.junit; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.util.ArrayList; import java.util.List; import javax.xml.bind.JAXBException; import org.apache.commons.lang.CharEncoding; import org.eclipse.jubula.client.core.exporter.junitmodel.ObjectFactory; import org.eclipse.jubula.client.core.exporter.junitmodel.Testcase; import org.eclipse.jubula.client.core.exporter.junitmodel.Testsuite; import org.eclipse.jubula.client.core.exporter.junitmodel.Testsuites; import org.eclipse.jubula.client.core.model.ICapPO; import org.eclipse.jubula.client.core.model.IControllerPO; import org.eclipse.jubula.client.core.model.ITestCasePO; import org.eclipse.jubula.client.core.model.ITestResult; import org.eclipse.jubula.client.core.model.TestResultNode; import org.eclipse.jubula.client.core.testresult.export.ITestResultExporter; import org.eclipse.jubula.client.core.utils.ITreeNodeOperation; import org.eclipse.jubula.client.core.utils.TestResultNodeTraverser; import org.eclipse.jubula.tools.internal.constants.StringConstants; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * @author marcelk * 2017 */ public class JunitXMLWriter implements ITestResultExporter { /** the logger */ private static Logger log = LoggerFactory.getLogger(JunitXMLWriter.class); /** * Objectfactory for generating JAXB objects like Testsuites, Testsuite and * Testcase aswell as Error or Failure. */ private ObjectFactory m_objF; /** * The project which contains the testsuites */ private Testsuites m_project; /** * The result of the Jubula test */ private ITestResult m_testResult; /** * The testResultNode to be used as rootnode */ private TestResultNode m_resultNode; /** * list of TestSuites */ private List<TestResultNode> m_testSuiteList; /** * Generating the Head of the XMLfile (TestSuites object) * */ private void generateHead() { //Creating TestSuites object setTestSuites(); setSuitesData(m_resultNode, m_project, m_testSuiteList); } /** * Creates Testsuites node via Objectfactory */ private void setTestSuites() { m_project = m_objF.createTestsuites(); m_project.setTime((m_testResult.getStartTime()).toString()); m_project.setName(m_testResult.getProjectName()); } /** * Sets the TestResult element * * @param testResult * the test result */ private void setTestResult(ITestResult testResult) { m_testResult = testResult; } /** * Creates a file to write in and returns it * * @param path the path of the target location * @param filename the name of the created file * * @throws IOException * @throws FileNotFoundException * @throws UnsupportedEncodingException * @return fileToWrite the file created */ public File generateFileForExport(String path, String filename) throws UnsupportedEncodingException, FileNotFoundException, IOException { File fileToWrite = new File(path, filename + "-junit" + ".xml"); //$NON-NLS-1$ //$NON-NLS-2$ return fileToWrite; } /** * Converts Time from long into a string with the format: "1234.567" * * @param l the time that is to be converted * @return a string representing the converted time */ private String convertTime(long l) { String convertedtime; convertedtime = (Double.toString(l / 1000.0)); return convertedtime; } /** * Searches in the childs of the testsuite for Testcases and saves them in a * list object */ private void findTestcasesForTestsuite() { //counter for handling the filling of the different Testsuite-JAXB objects in relation to their TestResultNode equivalent int count = 0; List<Testsuite> tempSuiteList = m_project.getTestsuite(); // for (TestResultNode testResultNode : m_testSuiteList) { List<TestResultNode>testcaseList = testResultNode.getResultNodeList(); for (TestResultNode testRes : testcaseList) { if (testRes.getNode() instanceof ITestCasePO) { createJAXBTestCase(testRes, tempSuiteList, count); } else if (testRes.getNode() instanceof ICapPO) { //Handling of the sitaution that a suite has no CAPs/Steps createJAXBTestCase(testRes, tempSuiteList, count); } else if (testRes.getNode() instanceof IControllerPO) { //Handling of the occurence of conditional statements as //direct children of the JUnitTestSutie createJAXBTestCase(testRes, tempSuiteList, count); } } //For filling the next suite once the current one has been worked through count++; } } /**Creates a JAXB TestCase object based on the state of the TestResultNode * it belongs to * * @param testRes the TestResultNode that is being processed * @param tempSuiteList list of TestSuites * @param count a counter for filling the next suite once the current one has been worked through */ private void createJAXBTestCase(TestResultNode testRes, List<Testsuite> tempSuiteList, int count) { Testcase testCase = m_objF.createTestcase(); if (testRes.getNode() instanceof IControllerPO) { testCase.setName("(Condition)" + StringConstants.SPACE //$NON-NLS-1$ + testRes.getName()); } else { testCase.setName(testRes.getName()); } testCase.setTime(convertTime (testRes.getDuration(m_testResult.getEndTime()))); testCase.setStatus(testRes.getStatusString()); if (testRes.getStatus() == TestResultNode.ERROR_IN_CHILD) { testCaseHandling(testRes, testCase, false); } else if (testRes.getStatus() == TestResultNode.SKIPPED || testRes.getStatus() == TestResultNode.NOT_YET_TESTED) { //Handling of skipped TestCases testCaseHandling(testRes, testCase, true); testCase.setTime("0"); //$NON-NLS-1$ } else if (testRes.getStatus() != TestResultNode.SUCCESS) { //Handling of all other possible situations testCaseHandling(testRes, testCase, false); } //Gets the TestSuite that is currently being filled and adds the newly //created element to its list which can contain elements of the type: //TestSuite, TestCase or Properties. //It will however only get filled with TestCase elements tempSuiteList.get(count). getTestsuiteOrPropertiesOrTestcase().add(testCase); } /** * Finds the elements that are defined as TestSuite elements via an Attribute in Jubula * and adds them to the list of TestSuite objects of the TestSuites object * * @param project contains data about the project and its testsuites * @param testRes the rootNode of the traversion * @param list list of testsuites */ private void setSuitesData(TestResultNode testRes, Testsuites project, List<TestResultNode> list) { SuiteFinderOperation suiteFinder = new SuiteFinderOperation(testRes, project, list, m_testResult); TestResultNodeTraverser testResTraverser = new TestResultNodeTraverser(testRes, suiteFinder); testResTraverser.traverse(); } /** * Used for creating and adding information about errors and failures * to a testcase * * @param node the rootnode for the resultNodetraverser * @param testCase the testcase that is to receive information * @param skipped boolean value wether the TestCase was skipped */ private void testCaseHandling(TestResultNode node, Testcase testCase, boolean skipped) { ITreeNodeOperation<TestResultNode> jxgOperat = null; if (skipped) { jxgOperat = new JUnitXMLSkippedGenerator(node, testCase); } else { jxgOperat = new JUnitXMLGeneratorOperations(node, testCase); } TestResultNodeTraverser testResTraverser = new TestResultNodeTraverser(node, jxgOperat); testResTraverser.traverse(); } /* * Initiliazing of the JUnitReportWriter (previously done in Constructor) * * * @param result the result of the test, which is to be exported */ @Override public void initiliaze(ITestResult result) { m_objF = new ObjectFactory(); setTestResult(result); m_resultNode = result.getRootResultNode(); m_testSuiteList = new ArrayList<TestResultNode>(); generateHead(); } /** * Writes the generated content tree into a file provided by the * generateFileForExport() function * * @param path targetpath for the file * * @throws JAXBException * @throws IOException {@link JunitXMLWriter#generateFileForExport(String, String)} * @throws UnsupportedEncodingException */ @Override public void writeTestResult(String path, String filename) { //Finds and adds the TestCases of the TestSuite elements, that were defined in findTestcasesForTestsuite(); //Init of of JACBContext object javax.xml.bind.JAXBContext jaxbCtx = null; try { //Setup jaxbCtx = javax.xml.bind.JAXBContext .newInstance(m_project.getClass().getPackage().getName()); javax.xml.bind.Marshaller marshaller = null; marshaller = jaxbCtx.createMarshaller(); marshaller.setProperty(javax.xml.bind.Marshaller. JAXB_ENCODING, CharEncoding.UTF_8); marshaller.setProperty(javax.xml.bind.Marshaller. JAXB_FORMATTED_OUTPUT, Boolean.TRUE); //Execution of filling a file with information marshaller.marshal(m_project, generateFileForExport(path, filename). getAbsoluteFile()); } catch (IOException | JAXBException e) { log.error("Exception while writing TestResults to file", e); //$NON-NLS-1$ } } }