
com.magenic.jmaqs.base.BaseTest Maven / Gradle / Ivy
/*
* Copyright 2020 (C) Magenic, All rights Reserved
*/
package com.magenic.jmaqs.base;
import static java.lang.System.out;
import com.magenic.jmaqs.utilities.helper.StringProcessor;
import com.magenic.jmaqs.utilities.logging.ConsoleLogger;
import com.magenic.jmaqs.utilities.logging.FileLogger;
import com.magenic.jmaqs.utilities.logging.Logger;
import com.magenic.jmaqs.utilities.logging.LoggingConfig;
import com.magenic.jmaqs.utilities.logging.LoggingEnabled;
import com.magenic.jmaqs.utilities.logging.MessageType;
import com.magenic.jmaqs.utilities.logging.TestResultType;
import com.magenic.jmaqs.utilities.performance.PerfTimerCollection;
import java.lang.reflect.Method;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Clock;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
import org.testng.ITestContext;
import org.testng.ITestResult;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
/**
* Base test class.
*/
public abstract class BaseTest {
/**
* All logged exceptions caught and saved to be thrown later.
*/
protected ConcurrentHashMap> loggedExceptions;
/**
* Logging Enabled Setting from Config file.
*/
protected LoggingEnabled loggingEnabledSetting;
/**
* The test result object.
*/
private ITestResult testResult;
/**
* The Collection of Base Test Objects to use.
*/
ConcurrentManagerHashMap baseTestObjects;
/**
* The Performance Timer Collection.
*/
private PerfTimerCollection perfTimerCollection;
/**
* The TestNG Test Context.
*/
private ITestContext testContextInstance;
/**
* The Fully Qualified Test Class Name.
*/
ThreadLocal fullyQualifiedTestClassName = new ThreadLocal<>();
/**
* Initializes a new instance of the BaseTest class.
*/
public BaseTest() {
this.loggedExceptions = new ConcurrentHashMap<>();
this.baseTestObjects = new ConcurrentManagerHashMap();
}
/**
* Gets the Performance Timer Collection.
*
* @return Performance Timer Collection
*/
public PerfTimerCollection getPerfTimerCollection() {
return this.perfTimerCollection;
}
/**
* Sets the Performance Timer Collection.
*
* @param perfTimerCollection Performance Timer Collection to use
*/
public void setPerfTimerCollection(PerfTimerCollection perfTimerCollection) {
this.perfTimerCollection = perfTimerCollection;
}
/**
* Gets the Logger for this test.
*
* @return Logger object
*/
public Logger getLogger() {
return this.getTestObject().getLogger();
}
/**
* Set the Logger for this test.
*
* @param log The Logger object
*/
public void setLogger(Logger log) {
this.getTestObject().setLogger(log);
}
/**
* Gets the Logging Enabled setting.
*
* @return Logging Enabled setting
*/
public LoggingEnabled getLoggingEnabledSetting() {
return this.loggingEnabledSetting;
}
/**
* Set the Logging Enabled setting.
*
* @param setting The LoggingEnabled enum
*/
protected void setLoggingEnabled(LoggingEnabled setting) {
this.loggingEnabledSetting = setting;
}
/**
* Get logged exceptions for this test.
*
* @return ArrayList of logged exceptions for this test
*/
public List getLoggedExceptions() {
ArrayList result;
if (!this.loggedExceptions.containsKey(this.fullyQualifiedTestClassName.get())) {
result = new ArrayList<>();
} else {
result = this.loggedExceptions.get(this.fullyQualifiedTestClassName.get());
}
return result;
}
/**
* Set Logged Exception List - Add/Update entry in Hash Map with test class name as key.
*
* @param loggedExceptionList ArrayList of logged exceptions to use.
*/
public void setLoggedExceptions(List loggedExceptionList) {
this.loggedExceptions.put(this.fullyQualifiedTestClassName.get(), (ArrayList) loggedExceptionList);
}
/**
* Gets the Driver Store.
*
* @return The Driver Store
*/
public ManagerDictionary getManagerStore() {
return this.getTestObject().getManagerStore();
}
/**
* Gets the TestNG Test Context.
*
* @return The TestNG Test Context
*/
public ITestContext getTestContext() {
return this.testContextInstance;
}
/**
* Sets the TestNG Test context.
*
* @param testContext The TestNG Test Context to use
*/
public void setTestContext(ITestContext testContext) {
this.testContextInstance = testContext;
}
/**
* Get the BaseTestObject for this test.
*
* @return The BaseTestObject
*/
public BaseTestObject getTestObject() {
if (!this.baseTestObjects.containsKey(this.fullyQualifiedTestClassName.get())) {
this.createNewTestObject();
}
return this.baseTestObjects.get(this.fullyQualifiedTestClassName.get());
}
/**
* Sets the Test Object.
*
* @param baseTestObject The Base Test Object to use
*/
public void setTestObject(BaseTestObject baseTestObject) {
String key = this.fullyQualifiedTestClassName.get();
if (this.baseTestObjects.containsKey(key)) {
this.baseTestObjects.replace(key, baseTestObject);
} else {
this.baseTestObjects.put(key, baseTestObject);
}
}
/**
* Setup before a test.
*
* @param method The initial executing Method object
* @param testContext The initial executing Test Context object
*/
@BeforeMethod(alwaysRun = true)
public void setup(Method method, ITestContext testContext) {
this.testContextInstance = testContext;
// Get the Fully Qualified Test Class Name and set it in the object
String testName = method.getDeclaringClass() + "." + method.getName();
customSetup(testName, testContext);
}
/**
* Setup before a test with custom name.
*
* @param testName User provide name of test
* @param testContext The initial executing Test Context object
*/
public void customSetup(String testName, ITestContext testContext) {
this.testContextInstance = testContext;
testName = testName.replaceFirst("class ", "");
this.fullyQualifiedTestClassName.set(testName);
this.createNewTestObject();
}
/**
* Cleanup after a test.
*/
@AfterMethod(alwaysRun = true)
public void teardown() {
try {
this.beforeLoggingTeardown(testResult);
} catch (Exception e) {
this.tryToLog(MessageType.WARNING, "Failed before logging teardown because: %s", e.getMessage());
}
// Log the test result
if (testResult.getStatus() == ITestResult.SUCCESS) {
this.tryToLog(MessageType.SUCCESS, "Test Passed");
} else if (testResult.getStatus() == ITestResult.FAILURE) {
this.tryToLog(MessageType.ERROR, "Test Failed");
} else if (testResult.getStatus() == ITestResult.SKIP) {
this.tryToLog(MessageType.INFORMATION, "Test was skipped");
} else {
this.tryToLog(MessageType.WARNING, "Test had an unexpected result.");
}
// Cleanup log files we don't want
try {
if ((this.getLogger() instanceof FileLogger) && testResult.getStatus() == ITestResult.SUCCESS
&& this.loggingEnabledSetting == LoggingEnabled.ONFAIL) {
Files.delete(Paths.get(((FileLogger) this.getLogger()).getFilePath()));
}
} catch (Exception e) {
this.tryToLog(MessageType.WARNING, "Failed to cleanup log files because: %s", e.getMessage());
}
// Get the Fully Qualified Test Name
String fullyQualifiedTestName = this.fullyQualifiedTestClassName.get();
try (BaseTestObject baseTestObject = this.getTestObject()) {
// Release logged messages
this.loggedExceptions.remove(fullyQualifiedTestName);
// Release the Base Test Object
this.baseTestObjects.remove(fullyQualifiedTestName, baseTestObject);
}
// Create console logger to log subsequent messages
this.setTestObject(new BaseTestObject(new ConsoleLogger(), fullyQualifiedTestName));
this.fullyQualifiedTestClassName.remove();
}
/**
* Set the test result after each test execution.
*
* @param testResult The result object
*/
@AfterMethod(alwaysRun = true)
public void setTestResult(ITestResult testResult) {
this.testContextInstance = testResult.getTestContext();
this.testResult = testResult;
}
/**
* Steps to do before logging teardown results.
*
* @param resultType The test result
*/
protected abstract void beforeLoggingTeardown(ITestResult resultType);
/**
* Setup logging data.
*
* @return Logger
*/
protected Logger createLogger() {
Logger log;
this.loggingEnabledSetting = LoggingConfig.getLoggingEnabledSetting();
this.setLoggedExceptions(new ArrayList<>());
if (this.loggingEnabledSetting != LoggingEnabled.NO) {
log = LoggingConfig.getLogger(StringProcessor.safeFormatter("%s - %s", this.fullyQualifiedTestClassName.get(),
DateTimeFormatter.ofPattern("uuuu-MM-dd-HH-mm-ss-SSSS", Locale.getDefault())
.format(LocalDateTime.now(Clock.systemUTC()))));
} else {
log = new ConsoleLogger();
}
return log;
}
/**
* Get the type of test result.
*
* @return The type of test result
*/
protected TestResultType getResultType() {
switch (this.testResult.getStatus()) {
case ITestResult.SUCCESS:
return TestResultType.PASS;
case ITestResult.FAILURE:
return TestResultType.FAIL;
case ITestResult.SKIP:
return TestResultType.SKIP;
default:
return TestResultType.OTHER;
}
}
/* */
/**
* Get the test result type as text.
*
* @return The test result type as text
*/
protected String getResultText() {
switch (this.testResult.getStatus()) {
case ITestResult.SUCCESS:
return "SUCCESS";
case ITestResult.FAILURE:
return "FAILURE";
case ITestResult.SKIP:
return "SKIP";
default:
return "OTHER";
}
}
/**
* Get the fully qualified test name.
*
* @return The test name including class
*/
protected String getFullyQualifiedTestClassName() {
return this.fullyQualifiedTestClassName.get();
}
/**
* Try to log a message - Do not fail if the message is not logged.
*
* @param messageType The type of message
* @param message The message text
* @param args String format arguments
*/
protected void tryToLog(MessageType messageType, String message, Object... args) {
// Get the formatted message
String formattedMessage = StringProcessor.safeFormatter(message, args);
try {
// Write to the log
this.getLogger().logMessage(messageType, formattedMessage);
// If this was an error and written to a file, add it to the console
// output as well
if (messageType == MessageType.ERROR && !(this.getLogger() instanceof ConsoleLogger)) {
out.println(formattedMessage);
}
} catch (Exception e) {
out.println(formattedMessage);
out.println("Logging failed because: " + e.getMessage());
}
}
/**
* Log a verbose message and include the automation specific call stack data.
*
* @param message The message text
* @param args String format arguments
*/
protected void logVerbose(String message, Object... args) {
StringBuilder messages = new StringBuilder();
messages.append(StringProcessor.safeFormatter(message, args) + System.lineSeparator());
for (StackTraceElement element : Thread.currentThread().getStackTrace()) {
// If the stack trace element is from the com.magenic package (excluding this method) append the stack trace line
if (element.toString().startsWith("com.magenic") && !element.toString().contains("BaseTest.logVerbose")) {
messages.append(element.toString() + System.lineSeparator());
}
}
this.getLogger().logMessage(MessageType.VERBOSE, messages.toString());
}
/**
* Create a Base test object.
*/
protected void createNewTestObject() {
Logger newLogger = this.createLogger();
this.setTestObject(new BaseTestObject(newLogger, this.fullyQualifiedTestClassName.get()));
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy