All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.netbeans.modules.testng.api.XmlOutputParser Maven / Gradle / Ivy

There is a newer version: RELEASE230
Show newest version
/*
 * 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.netbeans.modules.testng.api;

import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Logger;
import org.netbeans.modules.gsf.testrunner.api.Status;
import org.netbeans.modules.gsf.testrunner.api.TestSession;
import org.netbeans.modules.gsf.testrunner.api.Trouble;
import org.netbeans.modules.gsf.testrunner.api.Trouble.ComparisonFailure;
import org.openide.util.NbBundle;
import org.openide.xml.XMLUtil;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

/**
 *
 * @author lukas
 */
public final class XmlOutputParser extends DefaultHandler {

    private static final Logger LOG = Logger.getLogger(XmlOutputParser.class.getName());
    private int allTestsCount;
    private int failedTestsCount;
    private int passedTestsCount;
    private int skippedTestsCount;
    private int failedConfCount;
    private int skippedConfCount;
    private String status;
    private int suiteTime;
    /** */
    private static final int STATE_OUT_OF_SCOPE = 0;
    private static final int STATE_SUITE = 3;
    private static final int STATE_GROUPS = 4;
    private static final int STATE_GROUP = 5;
    private static final int STATE_METHOD = 6;
    private static final int STATE_TEST = 7;
    private static final int STATE_CLASS = 8;
    private static final int STATE_TEST_METHOD = 9;
    private static final int STATE_TEST_PARAMS = 10;
    private static final int STATE_TEST_PARAM = 11;
    private static final int STATE_TEST_VALUE = 12;
    private static final int STATE_EXCEPTION = 13;
    private static final int STATE_MESSAGE = 14;
    private static final int STATE_FULL_STACKTRACE = 15;
    private int state = STATE_OUT_OF_SCOPE;
    /** */
    private XmlResult reports;
    private TestNGTest test;
    private TestNGTestSuite testsuite;
    private TestNGTestcase testcase;
    private Trouble trouble;
    private String tcClassName;
    private StringBuffer text;
    private final XMLReader xmlReader;
    private TestSession testSession;

    /** Creates a new instance of XMLOutputParser */
    private XmlOutputParser(TestSession session) throws SAXException {
        this.testSession = session;
        xmlReader = XMLUtil.createXMLReader();
        xmlReader.setContentHandler(this);
    }

    public static XmlResult parseXmlOutput(Reader reader, TestSession session) throws SAXException, IOException {
        assert reader != null;
        XmlOutputParser parser = new XmlOutputParser(session);
        try {
            parser.xmlReader.parse(new InputSource(reader));
        } catch (SAXException ex) {
            LOG.info("Exception while parsing XML output from TestNG: " + ex.getMessage()); //NOI18N
            throw ex;
        } catch (IOException ex) {
            assert false;            /* should never happen */
        } finally {
            reader.close();          //throws IOException
        }
        return parser.reports;
    }

    @Override
    public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
        switch (state) {
            case STATE_SUITE:
                if ("groups".equals(qName)) { //NOI18N
                    //XXX - not handled yet, shoould perhaps create ie. "group" view
                    state = STATE_GROUPS;
                } else if ("test".equals(qName)) { //NOI18N
                    String name = attributes.getValue("name"); //NOI18N
                    test = name != null ? new TestNGTest(name) : new TestNGTest(""); //NOI18N
                    state = STATE_TEST;
                }
                break;
            case STATE_GROUPS:
                if ("group".equals(qName)) { //NOI18N
                    state = STATE_GROUP;
                }
                break;
            case STATE_GROUP:
                if ("method".equals(qName)) { //NOI18N
                    state = STATE_METHOD;
                }
                break;
            case STATE_METHOD:
                //empty for now
                break;
            case STATE_TEST:
                if ("class".equals(qName)) { //NOI18N
                    tcClassName = attributes.getValue("name"); //NOI18N
                    testsuite = new TestNGTestSuite(tcClassName, testSession);

                    state = STATE_CLASS;
                }
                break;
            case STATE_CLASS:
                if ("test-method".equals(qName)) { //NOI18N
                    int duration = Integer.valueOf(attributes.getValue("duration-ms")); //NOI18N
                    testcase = createTestcaseReport(tcClassName, attributes.getValue("name"), duration); //NOI18N
                    suiteTime += duration;
                    testcase.setConfigMethod(Boolean.valueOf(attributes.getValue("is-config"))); //NOI18N
                    status = attributes.getValue("status"); //NOI18N
                    if (!testcase.isConfigMethod()) {
                        allTestsCount++;
                    }
                    if ("FAIL".equals(status)) { //NOI18N
                        testcase.setStatus(Status.FAILED);
                        if (testcase.isConfigMethod()) {
                            failedConfCount++;
                        } else {
                            failedTestsCount++;
                        }
                        trouble = new Trouble(true);
                    } else if ("PASS".equals(status)) { //NOI18N
                        testcase.setStatus(Status.PASSED);
                        passedTestsCount++;
                    } else if ("SKIP".equals(status)) { //NOI18N
                        testcase.setStatus(Status.SKIPPED);
                        trouble = new Trouble(false);
                        if (testcase.isConfigMethod()) {
                            skippedConfCount++;
                        } else {
                            skippedTestsCount++;
                        }
                    }
                    state = STATE_TEST_METHOD;
                }
                break;
            case STATE_TEST_METHOD:
                if ("params".equals(qName)) { //NOI18N
                    state = STATE_TEST_PARAMS;
                } else if ("exception".equals(qName)) { //NOI18N
                    assert testcase != null && status != null;
                    if (!"PASS".equals(status)) {

//TODO:                        trouble.exceptionClsName = attributes.getValue("class"); //NOI18N
                    }
                    //if test passes, skip possible exception element
                    state = (trouble != null) ? STATE_EXCEPTION : STATE_TEST_METHOD;
                }
                break;
            case STATE_EXCEPTION:
                //how to get text msgs here?
                //exMessage =
                if ("message".equals(qName)) { //NOI18N
                    state = STATE_MESSAGE;
                } else if ("full-stacktrace".equals(qName)) { //NOI18N
                    state = STATE_FULL_STACKTRACE;
                }
                break;
            default:
                if (qName.equals("suite")) { //NOI18N
                    String name = attributes.getValue("name");
                    if (name == null || "".equals(name.trim())) {
                        name = NbBundle.getMessage(XmlOutputParser.class, "UNKNOWN_NAME");
                    }
                    reports = new XmlResult(name);
                    state = STATE_SUITE;
                }
        }
    }

    @Override
    public void endElement(String uri, String localName, String qName) throws SAXException {
        switch (state) {
            case STATE_GROUPS:
                assert "groups".equals(qName); //NOI18N
                state = STATE_SUITE;
                break;
            case STATE_GROUP:
                assert "group".equals(qName); //NOI18N
                state = STATE_GROUPS;
                break;
            case STATE_METHOD:
                assert "method".equals(qName) : "was " + qName; //NOI18N
                state = STATE_GROUP;
                break;
            case STATE_SUITE:
                assert "suite".equals(qName) : "was " + qName; //NOI18N
                state = STATE_OUT_OF_SCOPE;
                break;
            case STATE_TEST:
                assert "test".equals(qName); //NOI18N
                reports.addTestNGTest(test);
                test = null;
                state = STATE_SUITE;
                break;
            case STATE_CLASS:
                assert "class".equals(qName); //NOI18N
                testsuite.setElapsedTime(suiteTime);
                test.addTestsuite(testsuite);
                testsuite = null;
                suiteTime = 0;
                skippedTestsCount = 0;
                failedTestsCount = 0;
                allTestsCount = 0;
                passedTestsCount = 0;
                failedConfCount = skippedConfCount = 0;
                tcClassName = null;
                testcase = null;
                state = STATE_TEST;
                break;
            case STATE_TEST_METHOD:
                //if test passes, wait for our element
                if (!"test-method".equals(qName)) {
                    break;
                }
                assert "test-method".equals(qName) : "was " + qName; //NOI18N
                assert testcase != null;
                testcase.setTrouble(trouble);
                //assing all methods including config ones
                testsuite.getTestcases().add(testcase);
                trouble = null;
                testcase = null;
                state = STATE_CLASS;
                break;
            case STATE_TEST_PARAMS:
                //XXX - param and value elements are not handled yet
                if ("param".equals(qName) || "value".equals(qName)) { //NOI18N
                    break;
                }
                assert "params".equals(qName) : "was " + qName; //NOI18N
                state = STATE_TEST_METHOD;
                break;
            case STATE_EXCEPTION:
                assert "exception".equals(qName); //NOI18N
                state = STATE_TEST_METHOD;
                break;
            case STATE_MESSAGE:
                assert "message".equals(qName); //NOI18N
                assert testcase != null;
                assert trouble != null;
                if (text != null) {
                    //there should be better way to do this
                    String s = text.toString().trim();
                    if (s.startsWith("expected:")) {  //NOI18N
                        int index = s.indexOf("<"); //NOI18N
                        if (index > -1) {
                            int ie = s.indexOf(">", index + 1); //NOI18N
                            String expected = s.substring(index + 1, ie);
                            String actual = s.substring(s.indexOf("<", ie + 1) + 1, s.indexOf(">", ie + 1)); //NOI18N
                            trouble.setComparisonFailure(new ComparisonFailure(expected, actual));
                        }
                    }
                    text = null;
                }
                state = STATE_EXCEPTION;
                break;
            case STATE_FULL_STACKTRACE:
                assert "full-stacktrace".equals(qName); //NOI18N
                if (text != null) {
                    String[] lines = text.toString().trim().split("[\\r\\n]+"); //NOI18N
                    trouble.setStackTrace(lines);
                    text = null;
                }
                state = STATE_EXCEPTION;
                break;
        }
    }

    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        switch (state) {
            case STATE_MESSAGE:
            case STATE_FULL_STACKTRACE:
                if (text == null) {
                    text = new StringBuffer(512);
                }
                text.append(ch, start, length);
                break;
        }
    }

    private TestNGTestcase createTestcaseReport(String className, String name, int time) {
//        TestNGTestcase tc = new TestNGTestcase(name, "TestNG Test", testSession);
        TestNGTestcase tc = new TestNGTestcase(className + "." + name, "params", null, testSession);
        tc.setTimeMillis(time);
        return tc;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy