Java tutorial
/** * This file is part of PaxmlTestNG. * * PaxmlTestNG is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * PaxmlTestNG is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with PaxmlTestNG. If not, see <http://www.gnu.org/licenses/>. */ package org.paxml.testng; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.IOException; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Map; import javax.xml.bind.JAXBContext; import javax.xml.bind.Marshaller; import org.apache.commons.io.FileUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.paxml.core.Context; import org.paxml.core.Context.Stack.IStackTraverser; import org.paxml.core.IEntity; import org.paxml.selenium.rc.SeleniumTag; import org.paxml.selenium.rc.SeleniumHelper; import org.paxml.selenium.rc.SeleniumHelper.SnapshotInfo; import org.paxml.tag.ITag; import org.paxml.testng.PaxmlTestCaseFactory.ILockedOperation; import org.paxml.util.XmlUtils; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.Test; /** * paxml test case impl for testNG. * * @author Xuetao Niu * */ public abstract class AbstractPaxmlTestResult { public static enum ResultType { JSON("js"), XML("xml"); private final String ext; private ResultType(String ext) { this.ext = ext; } public String getExt() { return ext; } } private static final Log log = LogFactory.getLog(AbstractPaxmlTestResult.class); private final long processId; private final File outputDir; private final ResultType resultType; private final String entityName; private final String group; private boolean success = false; private final Map<?, ?> initialProps; /** * Construct from factors. * * @param point * the launch point * */ public AbstractPaxmlTestResult(String group, String entityName, long processId, File outputDir, ResultType resultType, Map<?, ?> initialProps) { if (resultType == null) { resultType = ResultType.JSON; } this.group = group; this.initialProps = initialProps; this.entityName = entityName; this.resultType = resultType; this.outputDir = outputDir; this.processId = processId; } @Override public String toString() { return getClass().getName() + ":" + getProcessId(); } protected void addMap(Map<?, ?> map, List<Const> consts) { for (Map.Entry<?, ?> entry : map.entrySet()) { Const c = new Const(); c.setName(String.valueOf(entry.getKey())); Object value = entry.getValue(); c.setValue(String.valueOf(value)); if (value != null) { c.setType(value.getClass().getName()); } consts.add(c); } Collections.sort(consts, new Comparator<Const>() { @Override public int compare(Const o1, Const o2) { return o1.getName().compareTo(o2.getName()); } }); } protected abstract Context getContext(); protected abstract void onSummary(TestResultSummary s); protected abstract void doTest() throws Throwable; protected abstract String getThreadName(); protected abstract long getStartMs(); protected abstract long getStopMs(); @Test public void executeTest() throws Throwable { doTest(); success = true; } @AfterMethod public void populateReport(final ITestResult result) throws Exception { try { PaxmlTestCaseFactory.performLocked(new ILockedOperation<Object>() { @Override public Object perform() { try { doPopulateReport(result); } catch (Exception e) { throw new RuntimeException(e); } return null; } }); } catch (Throwable t) { log.error("Cannot generate test result", t); } } private void doPopulateReport(ITestResult result) throws Exception { final Context context = getContext(); final Context exceptionContext = context == null ? null : context.getExceptionContext(); final TestResultSummary s = new TestResultSummary(); try { final TestResult r = new TestResult(); r.setProcessId(processId); r.setEntityName(entityName); r.setGroup(group); r.setThreadName(getThreadName()); r.setSuccessful(success); r.setStart(getStartMs()); r.setStop(getStopMs()); s.setProcessId(r.getProcessId()); s.setGroup(r.getGroup()); s.setEntityName(r.getEntityName()); s.setThreadName(r.getThreadName()); s.setSuccessful(r.isSuccessful()); s.setStart(r.getStart()); s.setStop(r.getStop()); ContextDump dump = new ContextDump(); r.setContextDump(dump); for (SnapshotInfo si : SeleniumHelper.getSnapshots(context)) { ScreenshotInfo info = new ScreenshotInfo(); r.getScreenshots().add(info); info.setFileName(si.getFile().getName()); for (SeleniumHelper.CallStack cs : si.getCallStack()) { CallStack _cs = new CallStack(); _cs.setEntityName(cs.getEntity().getResource().getName()); _cs.setTagName(cs.getTag().getTagName()); _cs.setLine(cs.getTag().getLineNumber()); info.getCallStack().add(_cs); } } addMap(System.getProperties(), r.getSystemProperties()); if (initialProps != null) { addMap(initialProps, r.getInitialProperties()); s.getInitialProperties().addAll(r.getInitialProperties()); } if (success) { if (context != null) { addMap(context.getIdMap(true, false), dump.getContextValue()); } } else { r.setErrorMessage(result.getThrowable().getMessage()); s.setErrorMessage(r.getErrorMessage()); if (exceptionContext != null) { addMap(exceptionContext.getIdMap(true, false), dump.getContextValue()); final File file = SeleniumTag.getErrorSnapshot(exceptionContext); if (file != null) { r.setErrorScreenshotName(file.getName()); } else { if (log.isWarnEnabled()) { log.warn(getTitle() + " failed but has no selenium snapshots attached. It may have failed before opening the browser."); } } // compose error stack exceptionContext.getStack().traverse(new IStackTraverser() { @Override public boolean onItem(IEntity entity, ITag tag) { CallStack c = new CallStack(); r.getErrorStack().add(c); c.setLine(tag.getLineNumber()); c.setEntityName(entity.getResource().getName()); c.setTagName(tag.getTagName()); return true; } }); } } // write the log detached to from the current test case. Context.cleanCurrentThreadContext(); writeReportFile(r, false); } finally { onSummary(s); } } public long getProcessId() { return processId; } public File getOutputDir() { return outputDir; } public ResultType getResultType() { return resultType; } public String getEntityName() { return entityName; } public String getTitle() { return processId + ":" + entityName + "@" + getThreadName(); } public File writeReportFile(Object tr, boolean index) { String str = null; if (resultType == ResultType.JSON) { str = XmlUtils.toJson(tr); } else if (resultType == ResultType.XML) { str = serializeXml(tr); } else { throw new RuntimeException("Unknown result type: " + resultType); } if (null != outputDir) { final String fn = index ? "index" : new Long(processId).toString(); final File file = new File(outputDir, fn + "." + resultType.getExt()); if (log.isInfoEnabled()) { if (index) { log.info("Outputting test result index to: " + file.getAbsolutePath()); } else { log.info("Outputting test result to: " + file.getAbsolutePath()); } } outputDir.mkdirs(); try { FileUtils.writeStringToFile(file, str, "UTF-8"); } catch (IOException e) { throw new RuntimeException(e); } return file; } else { if (log.isWarnEnabled()) { if (index) { log.warn("No output dir specified, therefore no test result index file will be saved."); } else { log.warn( "No output dir specified, therefore no test result file will be saved after each test case."); } } return null; } } public static String serializeXml(Object obj) { final String encoding = "UTF-8"; try { JAXBContext c = JAXBContext.newInstance(obj.getClass()); Marshaller m = c.createMarshaller(); m.setProperty(Marshaller.JAXB_ENCODING, encoding); m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true); ByteArrayOutputStream out = new ByteArrayOutputStream(); m.marshal(obj, out); return out.toString(encoding); } catch (Exception e) { throw new RuntimeException("Cannot serialize jaxb object of class: " + obj.getClass(), e); } } }