org.apache.batik.test.xml.XMLTestSuiteRunner Maven / Gradle / Ivy
/* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ package org.apache.batik.test.xml; import java.io.File; import java.io.StringWriter; import java.io.PrintWriter; import java.net.URL; import java.net.MalformedURLException; import java.util.HashSet; import java.util.Set; import java.util.List; import java.util.ArrayList; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.DocumentBuilder; import org.apache.batik.test.DefaultTestSuite; import org.apache.batik.test.DefaultTestReport; import org.apache.batik.test.TestReport; import org.apache.batik.test.TestSuite; import org.apache.batik.test.Test; import org.apache.batik.test.TestFilter; import org.apache.batik.test.TestException; import org.apache.batik.test.TestReportProcessor; import org.w3c.dom.Element; import org.w3c.dom.Document; import org.w3c.dom.Node; import org.w3c.dom.NodeList; /** * This class can be used to build and run a
instances from theTestSuite
from * an XML description following the "XML Test Run" and "XML Test Suite" * formats, whose constants are defined in theXTRunConstants
* andXTSConstants
interfaces. * * This class takes a "Test Run" XML description as an input. That * description contains:
* + pointers to a number of "Test Suite" XML descriptions, * which contain the definition of the set ofTests
to be * run and their configuration.
* + a description of the set ofTestReportProcessor
and * their configuration that should be used to process the reports * generated by the variousTestSuites
.
* * @author Vincent Hardy * @version $Id: XMLTestSuiteRunner.java 1806580 2017-08-29 12:06:44Z ssteiner $ */ public class XMLTestSuiteRunner implements XTRunConstants, XTSConstants{ /** * Displayed when no test or testSuite matching the input id was * found. * {0} : unmatched id set */ public static final String MESSAGE_UNMATCHED_TEST_IDS = "XMLTestSuiteRunner.messages.unmatched.test.ids"; /** * An error happened while processing aTestreportProcessor
* description. * {0} : the <testReportProcessor> "className" attribute value * {1} : exception's class name * {2} : exception's message * {3} : exception's stack trace */ public static final String CANNOT_CREATE_TEST_REPORT_PROCESSOR = "xml.XMLTestSuiteRunner.error.cannot.create.test.report.processor"; /** * An error happened while running theTestSuite
* {0} :TestSuite
name * {1} :TestSuite
class name. * {1} : exception's class name. * {2} : exception's message * {3} : exception's stack trace. */ public static final String TEST_SUITE_EXCEPTION = "xml.XMLTestSuiteRunner.test.suite.exception"; /** * An error happened while processing theTestReport
* generated by theTestSuite
* {0} :TestReportProcessor
class name. * {1} : exception's class name. * {2} : exception's message * {3} : exception's stack trace. */ public static final String TEST_REPORT_PROCESSING_EXCEPTION = "xml.XMLTestSuiteRunner.error.test.report.processing.exception"; /** * Test filter which accepts all tests */ public static class AcceptAllTestsFilter implements TestFilter{ public Test filter(Test t){ return t; } } /** * Test filter which only accepts tests with ids matching * the ones passed to its constructor. */ public static class IdBasedTestFilter implements TestFilter { protected String[] ids; protected Set unmatchedIds = new HashSet(); public IdBasedTestFilter(String[] ids){ this.ids = ids; for (String id : ids) { unmatchedIds.add(id); } } public String traceUnusedIds(){ Object[] ui = unmatchedIds.toArray(); StringBuffer sb = null; if(ui != null && ui.length > 0){ sb = new StringBuffer(); sb.append(ui[0].toString()); for(int i=1; iTest TestSuite
* if they are filtered out. */ public void filterTestSuite(TestSuite ts){ Test[] t = ts.getChildrenTests(); int nTests = t != null ? t.length : 0; for(int i=0; iTest's * qualified id. * TestSuite
s are accepted if they have children and * rejected if they have none. */ public Test filter(Test t){ String id = t.getQualifiedId(); boolean isRequested = isRequestedId(id); // // First, handle TestSuite children // if(t instanceof TestSuite){ TestSuite ts = (TestSuite)t; filterTestSuite(ts); if(ts.getChildrenCount() > 0){ return t; } return null; } // // Now, handle leaf Tests // if(isRequested){ return t; } return null; } protected boolean isRequestedId(String id){ for (String id1 : ids) { // // id substring of ids[i] // ====================== // if the test identifier (id) is a substring of one of the requested // then the test is one of the requested test parents and should be accepted. // Example: id = "all.B" with requested ids = "all.A all.B.B3" // "all.B" (id) is a substring of "all.B.B3" (ids[1]) // Conclusion: id is accepted because it is a parent test of ids[1] // // ids[i] substring of id // ====================== // if one of the requested test identifiers (id[i]) is a substring of the // test id, then one of the test children is requested, so the test should // be accepted. // Example: id = "all.B.B3" with requested ids = "all.B" // "all.B" (ids[0]) is a substring of "all.B.B3" (id) // Conclusion: id is accepted because it is a child test of ids[0] // if (id1.lastIndexOf(id) == 0) { // System.out.println("accepting " + id + ". It is (or is the a parent of) " + ids[i]); unmatchedIds.remove(id1); return true; } if (id.lastIndexOf(id1) != -1) { // System.out.println("accepting " + id + " it is (or is a child of) the requested " + ids[i]); unmatchedIds.remove(id1); return true; } } return false; } } /** * Builds an array ofTestReportProcessor
from the input * element, assuming the input element is a <testSuite> instance, */ protected TestReportProcessor[] extractTestReportProcessor(Element element) throws TestException { List processors = new ArrayList(); NodeList children = element.getChildNodes(); if(children != null && children.getLength() > 0){ int n = children.getLength(); for(int i=0; i0){ p = new TestReportProcessor[processors.size()]; processors.toArray(p); } return p; } /** * Builds a TestResultProcessor
from an element. */ protected TestReportProcessor buildProcessor(Element element) throws TestException { try{ return (TestReportProcessor)XMLReflect.buildObject(element); }catch(Exception e){ StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); throw new TestException(CANNOT_CREATE_TEST_REPORT_PROCESSOR, new Object[] { element.getAttribute(XR_CLASS_ATTRIBUTE), e.getClass().getName(), e.getMessage(), sw.toString() }, e); } } /** * Builds aTestSuite
from an input element. * This method assumes that element is a <testRun> * instance. The element is scanned for children * <testSuite> elements which is loaded into * aTest
and composited into aTestSuite
*/ protected DefaultTestSuite buildTestRunTestSuite(Element element) throws TestException { DefaultTestSuite testSuite = new DefaultTestSuite(); // // Set the testRun name and id on the top level testSuite // String name = element.getAttribute(XTRun_NAME_ATTRIBUTE); testSuite.setName(name); String id = element.getAttribute(XTRun_ID_ATTRIBUTE); testSuite.setId(id); Element[] testSuites = getChildrenByTagName(element, XTRun_TEST_SUITE_TAG); int n = testSuites != null ? testSuites.length : 0; for(int i=0; i0){ int n = children.getLength(); for(int i=0; i 0){ a = new Element[childrenWithTagName.size()]; childrenWithTagName.toArray(a); } return a; } /** * Runs the test suite described by the input * Document object. If the input ids array * is null or of zero length, then all the tests will be run. * Otherwise, only the tests identified by * the array will be run. */ public TestReport run(Document doc, String[] ids) throws TestException { Element root = doc.getDocumentElement(); return run(root, ids); } protected TestReport runTest(Test test) throws TestException { try{ return test.run(); }catch(Exception e){ StringWriter sw = new StringWriter(); PrintWriter pw = new PrintWriter(sw); e.printStackTrace(pw); throw new TestException(TEST_SUITE_EXCEPTION, new Object[] { test.getName(), test.getClass().getName(), e.getClass().getName(), e.getMessage(), sw.toString() }, e); } } protected void processReport(TestReport report, TestReportProcessor[] processors) throws TestException { int n = processors.length; int i=0; try{ for(; i 0){ IdBasedTestFilter filter = new IdBasedTestFilter(ids); filteredTestRun = filter.filter(testRun); String unusedIds = filter.traceUnusedIds(); if(unusedIds != null){ System.err.println(Messages.formatMessage(MESSAGE_UNMATCHED_TEST_IDS, new Object[]{unusedIds})); } } if(filteredTestRun == null){ DefaultTestReport report = new DefaultTestReport(testRun); report.setPassed(true); return report; } // // Now, get the set of TestReportProcessors // that can use the data // TestReportProcessor[] processors = extractTestReportProcessor(testRunElement); // // Run the test // TestReport report = runTest(testRun); // // Process the report // if(processors != null){ processReport(report, processors); } return report; } /** * Displayed when the user passes no arguments to the command line. */ public static final String USAGE = "XMLTestSuiteRunner.messages.error.usage"; /** * Displayed when the input argument does not represent an existing * file to notify the user that the argument is going to be * interpreted as a URI. */ public static final String NOT_A_FILE_TRY_URI = "XMLTestSuiteRunner.messages.error.not.a.file.try.uri"; /** * Displayed when the input file name cannot be turned into a URL */ public static final String COULD_NOT_CONVERT_FILE_NAME_TO_URI = "XMLTestSuiteRunner.messages.error.could.not.convert.file.name.to.uri"; /** * Displayed when the input argument does not represent a valid * URI */ public static final String INVALID_URI = "XMLTestSuiteRunner.messages.error.invalid.uri"; /** * Displayed when the input document cannot be parsed. * {0} : uri of the invalid document. * {1} : exception generated while parsing * {2} : exception message */ public static final String INVALID_DOCUMENT = "XMLTestSuiteRunner.messages.error.invalid.document"; /** * Error displayed when an error occurs while running the * test suite */ public static final String ERROR_RUNNING_TEST_SUITE = "XMLTestSuiteRunner.messages.error.running.test.suite"; public static void main(String[] args) { if(args.length < 1){ System.err.println(Messages.formatMessage(USAGE, null)); System.exit(0); } String uriStr = args[0]; String[] ids = new String[args.length - 1]; System.arraycopy(args, 1, ids, 0, args.length-1); File file = new File(uriStr); URL url = null; if(file.exists()){ try { url = file.toURI().toURL(); }catch(MalformedURLException e){ System.err.println(Messages.formatMessage(COULD_NOT_CONVERT_FILE_NAME_TO_URI, new Object[]{uriStr})); System.exit(0); } } else { System.err.println(Messages.formatMessage(NOT_A_FILE_TRY_URI, new Object[]{uriStr})); try{ url = new URL(uriStr); }catch(MalformedURLException e){ System.err.println(Messages.formatMessage(INVALID_URI, new Object[]{uriStr})); System.exit(0); } } Document doc = null; try{ System.err.println("Loading document ..."); DocumentBuilder docBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); doc = docBuilder.parse(url.toString()); }catch(Exception e){ e.printStackTrace(); System.err.println(Messages.formatMessage(INVALID_DOCUMENT, new Object[] { uriStr, e.getClass().getName(), e.getMessage() })); System.exit(0); } try{ System.err.println("Running test run..."); XMLTestSuiteRunner r = new XMLTestSuiteRunner(); r.run(doc, ids); }catch(TestException e){ System.err.println(Messages.formatMessage(ERROR_RUNNING_TEST_SUITE, new Object[] { e.getMessage() })); System.exit(0); } System.exit(1); } }
© 2015 - 2024 Weber Informatics LLC | Privacy Policy