org.tap4j.ext.junit.util.TapJUnitUtil Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of tap4j-ext Show documentation
Show all versions of tap4j-ext Show documentation
TAP extensions to support JUnit and TestNG
/*
* The MIT License
*
* Copyright (c) 2010 tap4j team (see AUTHORS)
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package org.tap4j.ext.junit.util;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.StringTokenizer;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.runner.Description;
import org.tap4j.ext.junit.model.JUnitTestData;
import org.tap4j.model.Directive;
import org.tap4j.model.TestResult;
import org.tap4j.util.DirectiveValues;
import org.tap4j.util.StatusValues;
import org.yaml.snakeyaml.DumperOptions.LineBreak;
/**
* JUnit TAP extension utility class.
*
* @since 1.4.3
*/
public final class TapJUnitUtil {
public static final String LINE_SEPARATOR = LineBreak.UNIX.getString();
/**
* Default constructor.
*/
private TapJUnitUtil() {
super();
}
/**
* Generate TAP test result
*
* @param testMethod
* @param number
* @return TestResult
*/
public static TestResult generateTAPTestResult(JUnitTestData testMethod,
Integer number, boolean yaml) {
final TestResult tapTestResult = new TestResult();
final String testResultDescription = generateTAPTestResultDescription(testMethod);
tapTestResult.setDescription(testResultDescription);
setTapTestStatus(tapTestResult, testMethod);
if (yaml) {
String message = getMessage(testMethod);
String severity = getSeverity(testMethod);
String source = getSource(
extractMethodName(testMethod.getDescription()),
extractClassName(testMethod.getDescription()));
String datetime = getDatetime();
String file = getFile(testMethod);
String line = getLine(testMethod);
String name = getName(testMethod);
String error = getError(testMethod);
String backtrace = getBacktrace(testMethod);
TapJUnitYamlUtil.createJUnitYAMLishData(tapTestResult, message,
severity, source, datetime, file, line, name, error, backtrace);
}
return tapTestResult;
}
/**
* Get the tap test description
*
* @param testMethod
* @return the tap test description
*/
public static String generateTAPTestResultDescription(JUnitTestData testMethod) {
final StringBuilder description = new StringBuilder();
// An extra space is added before the description by the TAP Representer
description.append("- ");
description.append(extractClassName(testMethod
.getDescription()));
description.append(':');
description.append(extractMethodName(testMethod
.getDescription()));
return description.toString();
}
/**
* Set the tap status
*
* @param tapTestResult
* @param testMethod
*/
public static void setTapTestStatus(TestResult tapTestResult,
JUnitTestData testMethod) {
if (testMethod.isIgnored()) {
tapTestResult.setStatus(StatusValues.NOT_OK);
Directive skip = new Directive(DirectiveValues.SKIP,
"JUnit test was skipped");
tapTestResult.setDirective(skip);
} else if (testMethod.isFailed()) {
tapTestResult.setStatus(StatusValues.NOT_OK);
} else {
tapTestResult.setStatus(StatusValues.OK);
}
}
/**
* Extract the class name from a given junit test description
*
* @param description
* @return a class name
*/
public static String extractClassName(Description description) {
final String displayName = description.getDisplayName();
final String regex = "^" + "[^\\(\\)]+" // non-parens
+ "\\((" // then an open-paren (start matching a group)
+ "[^\\\\(\\\\)]+" // non-parens
+ ")\\)" + "$";
// System.out.println(regex);
final Pattern parens = Pattern.compile(regex); // then a close-paren
// (end group match)
final Matcher m = parens.matcher(displayName);
if (!m.find()) {
return displayName;
}
return m.group(1);
}
/**
* Extract the simple class name from a given junit test description
*
* @param description
* @return a simple class name
*/
public static String extractSimpleClassName(Description description) {
String simpleClassName = null;
final String className = extractClassName(description);
final String[] splitClassName = className.split("\\.");
if (splitClassName.length > 0) {
simpleClassName = splitClassName[splitClassName.length - 1];
}
return simpleClassName;
}
/**
* Get the tested method name
*
* @param description
* @return tested methode name
*/
public static String extractMethodName(Description description) {
String methodName = null;
final String[] splitDisplayName = description.getDisplayName().split("\\(");
if (splitDisplayName.length > 0) {
methodName = splitDisplayName[0];
}
return methodName;
}
/**
* Get the file name of the tested method
*
* @param testMethod
* @return the file name
*/
public static String getFile(JUnitTestData testMethod) {
return extractClassName(testMethod.getDescription());
}
/**
* Get tested method name
*
* @param testMethod
* @return tested method name
*/
public static String getName(JUnitTestData testMethod) {
return extractMethodName(testMethod.getDescription());
}
/**
* Get the line of the error in the exception info
*
* @param testMethod
* @return line of the error in the exception info
*/
public static String getLine(JUnitTestData testMethod) {
String line = "~";
Throwable testException = testMethod.getFailException();
if (testException != null) {
StringBuilder lookFor = new StringBuilder();
lookFor.append(extractClassName(testMethod.getDescription()));
lookFor.append('.');
lookFor.append(extractMethodName(testMethod.getDescription()));
lookFor.append('(');
lookFor.append(extractSimpleClassName(testMethod.getDescription()));
lookFor.append(".java:");
StackTraceElement[] els = testException.getStackTrace();
for (int i = 0; i < els.length; i++) {
StackTraceElement el = els[i];
line = getLineNumberFromExceptionTraceLine(el.toString(),
lookFor.toString());
if (line.equals("") == Boolean.FALSE) {
break;
}
}
}
return line;
}
/**
* Get the error line number from the exception stack trace
*
* @param exceptionTraceLine
* @param substrToSearch
* @return error line number
*/
public static String getLineNumberFromExceptionTraceLine(String exceptionTraceLine,
String substrToSearch) {
String lineNumber = "";
int index = exceptionTraceLine.indexOf(substrToSearch);
if (index >= 0) {
int length = substrToSearch.length() + index;
if (exceptionTraceLine.lastIndexOf(')') > length) {
lineNumber = exceptionTraceLine
.substring(length, exceptionTraceLine.lastIndexOf(')'));
}
}
return lineNumber;
}
/**
* Get the error message from a given failed JUnit test result
*
* @param testMethod
* @return error message from a given failed JUnit test result
*/
public static String getError(JUnitTestData testMethod) {
String error = "~";
Throwable t = testMethod.getFailException();
if (t != null) {
error = t.getMessage();
}
return error;
}
/**
* Generate a message with the name of the tested method
*
* @param testMethod
* @return test message
*/
public static String getMessage(JUnitTestData testMethod) {
return "JUnit 4.0 Test " + testMethod.getDescription().getDisplayName();
}
/**
* Get the severity of the test
*
* @param testMethod
* @return severity
*/
public static String getSeverity(JUnitTestData testMethod) {
String severity = "~";
if (testMethod.getFailException() != null) {
severity = "High";
}
return severity;
}
/**
* @param testMethod
* @param testClass
* @return test source
*/
public static String getSource(String testMethod, String testClass) {
return testClass + ":" + testMethod;
}
/**
* Get a date time string
*
* @return date time string
*/
public static String getDatetime() {
long currentTimeMillis = System.currentTimeMillis();
final Date date = new Date(currentTimeMillis);
// ISO-8061 for YAMLish diagnostic
return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss").format(date);
}
/**
* Get the backtrace from a given failed JUnit test result
*
* @param testMethod
* @return Backtrace from a given failed JUnit test result
*/
public static String getBacktrace(JUnitTestData testMethod) {
StringBuilder stackTrace = new StringBuilder();
Throwable throwable = testMethod.getFailException();
if (throwable != null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
throwable.printStackTrace(pw);
String stackTraceString = sw.toString();
stackTraceString = stackTraceString.trim().replaceAll("\\r\\n",
"\n");
StringTokenizer st = new StringTokenizer(stackTraceString,
LINE_SEPARATOR);
while (st.hasMoreTokens()) {
String stackTraceLine = st.nextToken();
stackTrace.append(stackTraceLine);
stackTrace.append(LINE_SEPARATOR);
}
} else {
stackTrace.append('~');
}
return stackTrace.toString();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy