I'm integrating html-reports to our test framework using Extent Report library (version 4).
For that purpose I wrote a wrapper, that encapsulates our default TestNG logger (for the console output) and ExtentReport logger (ExtentTest.log, to collect data for html-report).
We use TestNg as our testing framework.
Having an issue capturing log messages from failed assertions (both soft and hard Assertions) to display it in html-report, they go only to the console log.
What would be the possible solution to capture those Assert log messages to show them in html-report?
I can't extend Assert (or SoftAssert) classes and add my own implementation (by adding an instance of ExtentTest.log there) because I'd have to replace all assertions in dozens of tests.
public class Loggers {
private static final Loggers instance = new Loggers();
private static ExtentTest test;
private static ExtentReports extent;
private static Logger LOG;
private static final String REPORT_LOCATION = "test-output/reports.extent.html";
/**
* Returns an instance of {#link ExtentReports} object. If it doesn't exist creates a new instance and returns it
*/
public static ExtentReports getLogger() {
if ( extent == null ) {
createInstance();
}
return extent;
}
/**
* Create ExtentReport and attaches htmlReporter to it
*/
public static void createInstance() {
ExtentHtmlReporter htmlReporter = getHTMLReporter();
extent = new ExtentReports();
extent.attachReporter( htmlReporter );
}
/**
* This method creates, configures and returns an instance of ExtentHtmlReporter
*
*/
public static ExtentHtmlReporter getHTMLReporter() {
ExtentHtmlReporter htmlReporter = new ExtentHtmlReporter( REPORT_LOCATION );
return htmlReporter;
}
/**
* This method logs a message with the INFO level for both instances of TestNG Logger and ExtentTest
*/
public void info( String message ) {
LOG.info( message );
test.log( Status.INFO, message );
}
Found the solution. Will post here if somebody will have similar issue.
If you locate your loggers in a listener class, you can put your logger over there and use ITestResult as an argument, specifically its method getThrowable (It returns the throwable that was thrown while running the method)
/**
* Triggered upon the failure of a test
*/
public void onTestFailure( ITestResult testResult ) {
LOG.fail( testResult.getThrowable() );
}
It will print in the report a failed assertion or thrown exception.
The Below Code Works for me for Extent Report Try it!
1) Initialize Extent report and Logger
public static Logger log = Logger.getLogger("devpinoyLogger");
public ExtentReports rep = ExtentManager.getInstance();
public static ExtentTest test;
2) Use Configuration File ReportsConfig.xml for Extent Report that you can get from extentreports official site.
3) Create class ExtentManager that load config file and set output of Extent report file.
public class ExtentManager {
private static ExtentReports extent;
public static ExtentReports getInstance(){
if(extent==null){
System.out.println("Path of user DIR"+System.getProperty("user.dir"));
extent = new ExtentReports(System.getProperty("user.dir")+"\\target\\surefire-reports\\ExecutionReport.html",true,DisplayOrder.OLDEST_FIRST);
extent.loadConfig(new File(System.getProperty("user.dir")+"\\src\\main\\java\\extentconfig\\ReportsConfig.xml"));
}
return extent;
}
}
4) Use INFO and ERROR log in method you are creating to display logs in Extent report.
public void click(String xpath) {
try {
driver.findElement(By.xpath(Variables.OR.getProperty(xpath))).click();
System.out.println(xpath + "Button clicked");
test.log(LogStatus.INFO, xpath + " Button clicked");
Thread.sleep(1000);
} catch (Exception e) {
System.err.println("Cannot Click " + e.getMessage());
test.log(LogStatus.ERROR,"Unable to click on :: " + xpath + " Button");
throw new AssertionError("Unable to click on :: " + xpath + " Button", e);
}
}
5) Use Custom listener class CustomListeners
public class CustomListeners extends TestBase implements ITestListener, ISuiteListener {
public boolean flag;
..implement all methods of CustomListeners class and use logs in onTestSuccess and onTestFailure Methods.
public void onTestSuccess(ITestResult arg0) {
test.log(LogStatus.PASS, arg0.getName().toUpperCase() + " PASS");
rep.endTest(test);
rep.flush();
}
public void onTestFailure(ITestResult arg0) {
System.out.println(arg0 + " =================Test Case Failed===========================");
flag = true;
System.out.println("Flag is inside onTestFailure " + flag);
System.setProperty("org.uncommons.reportng.escape-output", "false");
try {
test.log(LogStatus.FAIL, arg0.getName().toUpperCase() + " Failed with exception : " + arg0.getThrowable());
rep.endTest(test);
rep.flush();
} catch (IOException e) {
System.err.println("IOException occurs " + e.getMessage());
e.printStackTrace();
}
}
}
ExtentReport view for PASS Test Case
ExtentReport view for FAIL Test Case
Related
I am trying to create extent report version v4.0.9 but unable to do so.
Below code I have written to setUp class which has all before method and aftermethos and the same class is extented to Utilities class where I am performing tests.
Here is code for setUp class
public class AIG_SetUp {
protected static ExtentLoggerReporter logger;
protected static ExtentReports extent;
protected static ExtentTest log;
#BeforeTest(alwaysRun = true)
public void starttest() {
logger = new ExtentLoggerReporter(System.getProperty("user.dir"));
extent = new ExtentReports();
extent.attachReporter(logger);
System.err.close(); // written to remove JAVA 9 incompatibility.. continued below
System.setErr(System.out); // continue.. and remove the warnings
extent.setSystemInfo("User Name" , "Sobhit");
}
#AfterMethod(alwaysRun = true)
public void endReport(ITestResult result) {
try {
if (result.getStatus() == ITestResult.FAILURE) {
log.log(Status.FAIL , "Test cases Failed" + result.getName());
log.log(Status.FAIL , "Test cases Failed" + result.getThrowable());
} else if (result.getStatus() == ITestResult.SKIP) {
log.log(Status.SKIP , "Test case skipped is" + result.getName());
}
} catch (Exception e) {
e.printStackTrace();
}
}
#AfterTest(alwaysRun = true)
public void endReport() {
extent.flush();
}
}
And here is the utilities class which is extented to above class.
public class UtilitiesOps extends AIG_SetUp {
#Test(groups = {"Core-Smoke"}, description = "List all media types")
public void Verify_List_all_media_types() {
extent.attachReporter(logger);
extent = new ExtentReports();
log = extent.createTest("List all media types");
log.assignCategory("Utilities Operations");
}
Couple of important points to mention
Now I am not getting error, before I was getting null pointer exception but now no error.
Also Code runs fine but not generating the extent report.
If I put everything in one class with no before test and stuff, able to create the report. Not sure why is going wrong.
I really appreciate your help.
I got answer for this after reading about it.
basically I was doing the beforetest without static variables where as it has to be statically intiated because of other global variables.
The below code fixed my issues.
#BeforeTest(alwaysRun = true)
public static void starttest() {
logger = new ExtentLoggerReporter(System.getProperty("user.dir"));
extent = new ExtentReports();
extent.attachReporter(logger);
System.err.close(); // written to remove JAVA 9 incompatibility.. continued below
System.setErr(System.out); // continue.. and remove the warnings
extent.setSystemInfo("User Name" , "Sobhit");
}
I"m trying to build selenium with extent report but i could not get the save screenshot function working because i cannot reference the WebDriver object in the ITestListener class. Below is my sample code:
Test Runner.java:
#Listeners({com.peterwkc.Listener.TestListener.class})
public class ChromeTestManager {
private WebDriverManager webDriverManager = new WebDriverManager();
private WebDriver driver;
private LoginPages loginPages;
private AdminPages adminPages;
#BeforeClass
//#Parameters({"browser"})
public void setupTest(/*String browser*/) throws MalformedURLException {
System.out.println("BeforeMethod is started. " + Thread.currentThread().getId());
// Set & Get ThreadLocal Driver with Browser
webDriverManager.createDriver("chrome");
driver = webDriverManager.getDriver();
// Pages Object Initialization
loginPages = PageFactory.initElements(driver, LoginPages.class);
logoutPages = PageFactory.initElements(driver, LogoutPages.class);
adminPages = PageFactory.initElements(driver, AdminPages.class);
}
#DataProvider(name = "loginCredentials")
public static Object[][] getLoginCredentials() {
return new Object [][] {{ "Admin123", "admin123" }, {"testUser", "test"}, {"test", "test"}};
}
#Test(groups= {"Login"}, description="Invalid Login", priority = 0, dataProvider = "loginCredentials", invocationCount = 3)
public void login_invalid(String username, String password) {
loginPages.login_invalid(driver, username, password);
}
}
TestListener.java
public class TestListener implements ITestListener {
//Extent Report Declarations
private static ExtentReports extent = ExtentManager.createInstance();
private static ThreadLocal<ExtentTest> test = new ThreadLocal<>();
public TestListener() {
}
#Override
public synchronized void onTestFailure(ITestResult result) {
System.out.println((result.getMethod().getMethodName() + " failed!"));
test.get().fail("Exception Error : \n" + result.getThrowable());
/*String feature = getClass().getName();
String screenShot;
try {
screenShot = CaptureScreenshot.captureScreen(driver, CaptureScreenshot.generateFileName(feature));
test.get().addScreenCaptureFromPath(screenShot);
test.get().log(Status.FAIL, screenShot);
} catch (IOException ex) {
LogManager.logger.log(Level.INFO, "Exception: " + ex.getMessage());
}*/
}
}
Questions:
How to pass the WebDriver object from TestRunner.java to TestListener
class?
How to save screenshot in extent report 3?
Anything wrong with my code?
please help, thanks in advance!
Below are the steps to do this :
1 : Passing WebDriver object to Listener class
First create below method in ChromeTestManager class or at any another location from where you can call it, here suppose that it is present in ChromeTestManager class:
public static ITestContext setContext(ITestContext iTestContext, WebDriver driver) {
iTestContext.setAttribute("driver", driver);
return iTestContext;
}
It will set the driver object to the TestContext.
Now change your #BeforeClass setUp method to accept parameter ITestContext, below is the code :
public class ChromeTestManager {
private WebDriverManager webDriverManager = new WebDriverManager();
private WebDriver driver;
private LoginPages loginPages;
private AdminPages adminPages;
private static ITestContext context; // creating a ITestContext variable
#BeforeClass
//#Parameters({"browser"})
public void setupTest(ITestContext iTestContext) throws MalformedURLException {
System.out.println("BeforeMethod is started. " + Thread.currentThread().getId());
// Set & Get ThreadLocal Driver with Browser
webDriverManager.createDriver("chrome");
driver = webDriverManager.getDriver();
this.context = setContext(iTestContext, driver); // setting the driver into context
// Pages Object Initialization
loginPages = PageFactory.initElements(driver, LoginPages.class);
logoutPages = PageFactory.initElements(driver, LogoutPages.class);
adminPages = PageFactory.initElements(driver, AdminPages.class);
}
When you run this, it will run smoothly and will not produce an error (If you are thinking that how I will pass ITestcontext context, It is handled internally)
Now the driver has been added as an object to the ITestcontext ;
Now Accessing the driver in Listener :
#Override
public synchronized void onTestFailure(ITestResult result) {
WebDriver driver = (WebDriver) result.getTestContext().getAttribute("driver"); // here we are accessing the driver object that we added in Test class
}
2. Saving ScreenShot in extent report 3 (I am using dependency 3.1.5 in maven)
#Override
public synchronized void onTestFailure(ITestResult result) {
System.out.println("!!!!!!!!!!!!!!!!!!!! Test Failed !!!!!!!!!!!!!!!!!!!!");
WebDriver driver = (WebDriver) result.getTestContext().getAttribute("driver"); // accessing driver here
String feature = getClass().getName();
String screenShot;
try {
screenShot = CaptureScreenshot.captureScreen(driver, CaptureScreenshot.generateFileName(feature));
test.addScreenCaptureFromPath(screenShotPath); // I am assuming that the "screenShot" is fully qualified path with extension e.g "C:\Users\12345\Desktop\sfgfdh.PNG"
} catch (IOException ex) {
LogManager.logger.log(Level.INFO, "Exception: " + ex.getMessage());
}
}
3. Is there anything wrong with your code ?
No
You just need driver in Listener class and while adding screenshot in extent report ,
make sure that the path to screenshot is correct and is fully qualified path with extension.
Please let me know if you face an issue in this.
First of all don't instantiate Your webDriver in #BeforeClass, because this is called only once as annotation say before class, try using interface ITestListener and using beforeInvocation implementation for initialisation of WebDriver.
Second, You can't call PageFactory for all PageObjects at once, how do You think all 3 pages are initialised at once, this should be achieved in constructor for each page object, and when You init you page object (new Login) the elements are initialised as well, so this is not ok:
// Pages Object Initialization
loginPages = PageFactory.initElements(driver, LoginPages.class);
logoutPages = PageFactory.initElements(driver, LogoutPages.class);
adminPages = PageFactory.initElements(driver, AdminPages.class);
Third I don't see initialisation of ExtentReport test. It should looks something like this:
ExtentTest extentTest = ExtentTestManager.startTest(method.getName(), "");
Here is an example part of code from my implementation of calling screenshot, I'am calling it from afterInvocation, because I'm using concurrent driver initialisation, and so it had to be from here, but also can be achived via onTestFailure implementation:
public synchronized void afterInvocation(IInvokedMethod method, ITestResult testResult){
if (method.isTestMethod() && testResult.getStatus()==2) {
File scrFile = (dataMethod.getAndroidDriver()).getScreenshotAs(OutputType.FILE);
String dest = System.getProperty("user.dir") + "/resources/screenshots/" + dataMethod.getDriver().getSessionId() + ".png";
File destination = new File(dest);
try {
FileUtils.copyFile(scrFile, destination);
dataMethod.setScreenshotPath(destination.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
System.err.println("Path:" + dataMethod.getScreenshotPath());
}
You have to think more about structure,
Hope this helps...
I implemented two customized handler to log information on DB and an additional flat file (DBHandler and MyFileHandler). This new log handlers will be used by a single class on a specific package.
I attached the two new loggers to a specific package only.
The idea is to switch between this two handlers (file and database)for the classes contaiend on a specific package, but currently with the current configuration I could not do that, so either I am logging with both handler either there is no log at all.
I tried to set the log level for DB handler to off but it is still logging normally on DB.
below the configuration file is use logging.properties
############################################################
##### Global properties
############################################################
handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler, com.test.logging.DBHandler, com.test.logging.MyFileHandler
.level = INFO
############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################
java.util.logging.FileHandler.level = ALL
java.util.logging.FileHandler.pattern = %t/CLog%g.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.SimpleFormatter
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
com.test.logging.MyFileHandler.level = ALL
com.test.logging.MyFileHandler.pattern = %t/custLog%g.log
com.test.logging.MyFileHandler.limit = 50000
com.test.logging.MyFileHandler.count = 1
com.test.logging.MyFileHandler.formatter = java.util.logging.SimpleFormatter
com.test.logging.DBHandler.level=OFF
com.test.ccb.mon.handlers=com.test.logging.DBHandler, com.test.logging.MyFileHandler
The class using the logger to track he inforamtion is below
package com.test.ccb.mon;
public class Utils {
public static final Logger logger = Logger.getLogger(Utils.class.getCanonicalName());
public void logging()
{
//processing
logger.info("message);
}
}
DBHandler class:
public class DBHandler extends Handler {
#Override
public void close() throws SecurityException {
}
#Override
public void flush() {
}
#Override
public void publish(LogRecord logRecord) {
if (isLoggable(logRecord))
{
try {
//SQL call to insert onDB
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
MyFileHandler class:
public class MyFileHandler extends FileHandler{
public MyileHandler() throws IOException, SecurityException {
super();
}
#Override
public void close() throws SecurityException {
super.close();
}
#Override
public void flush() {
super.flush();
}
#Override
public void publish(LogRecord record) {
super.publish(record);
}
}
The Handler class doesn't read any properties from the LogManager by default. You have to code that logic in all of your subclasses.
public class DBHandler extends Handler {
public DBHandler() {
LogManager m = LogManager.getLogManager();
String p = getClass().getName();
String v = m.getProperty(p + ".level");
try {
if (v != null) {
super.setLevel(Level.parse(v));
}
} catch (RuntimeException re) {
reportError(v, re, ErrorManager.OPEN_FAILURE);
}
//#todo create code to parse filter, formatter, encoding, etc.
}
#Override
public void close() throws SecurityException {
}
#Override
public void flush() {
}
#Override
public void publish(LogRecord logRecord) {
if (isLoggable(logRecord)) {
try {
//SQL call to insert onDB
} catch (Exception e) {
reportError("", e, ErrorManager.WRITE_FAILURE);
}
}
}
}
Reproducing your problem is not so easy for me. With handler classes similar to yours, changes to the configuration file have the expected effect. With the DBHandler.level=OFF setting, the database handler output is missing for me:
Aug 11, 2015 1:47:26 PM com.test.ccb.mon.Utils logging
DBHandler.publish - handler level: OFF; log record level: INFO
INFO: message
MyFileHandler - message
Logging handlers:
###java.util.logging.FileHandler-ALL
###java.util.logging.ConsoleHandler-ALL
###com.test.logging.DBHandler-OFF
###com.test.logging.MyFileHandler-ALL
Your debug code to print the logging handlers is now also included in the following main method to your Utils class. You could run this method yourself, to see whether this way of reading the configuration file works better for you:
public static void main(final String[] arguments) throws IOException
{
final String fileName = "logging.properties";
final InputStream propertiesStream = Utils.class.getResourceAsStream(fileName);
//final InputStream propertiesStream = new FileInputStream("path to file");
LogManager.getLogManager().readConfiguration(propertiesStream);
new Utils().logging();
System.out.println();
// No handlers for this logger directly, but four for its parent.
System.out.println("Logging handlers:");
for (final Handler handler : logger.getParent().getHandlers())
System.out.println("###" + handler.getClass().getName()
+ "-" + handler.getLevel());
}
A very simple version of your DBHandler class could look like this (please note the if (isLoggable(record)) check in the publish method):
package com.test.logging;
import java.util.logging.*;
/**
* Logging handler that stores logging in the database.
*/
public class DBHandler extends Handler {
#Override
public void publish(final LogRecord record) {
System.out.println("DBHandler.publish - handler level: " + getLevel()
+ "; log record level: " + record.getLevel());
if (isLoggable(record))
System.out.println(getClass().getSimpleName() + " - " + record.getMessage());
}
#Override
public void flush() {
// Empty.
}
#Override
public void close() throws SecurityException {
// Empty.
}
}
Someone could tell me how to write a functional application tests which combine Selenium Page Object Pattern and ExtentsReports (http://extentreports.relevantcodes.com/) to generate reports from these test cases. How to design test class? because I know that validation should be separated from page objects. What is the best approach to do this?
A sample piece of code would be very helpful
It is a good approach, of course, to separate your model (Page Objects) from you tests. For this to happen, you may use a layer of services, i.e. helper classes, which can interact both with business objects and page objects.
Note: I'm going to answer the second part of your question, not that on yet-another lib for reporting.
So, you have a business object:
public class Something {
boolean toHappen;
public Something(boolean toHappen) {
this.toHappen = toHappen;
}
public boolean isToHappen() {
return toHappen;
}
}
You also have your page:
public class ApplicationPage {
// how driver object is put here is your own business.
private static WebDriver driver;
#FindBy(id = "id")
private Button triggerButton;
public ApplicationPage() {
PageFactory.initElements(driver, this);
}
public static ApplicationPage open(){
driver.get("http://page.net");
return new ApplicationPage();
}
public void trigger() {
triggerButton.click();
}
}
So in order not to mix business objects and pages in tests, you create a service:
public class InevitableService {
public static void makeHappen() {
// just a very stupid code here to show interaction
Something smth = new Something(true);
ApplicationPage page = ApplicationPage.open();
if(smth.toHappen()){
page.trigger();
}
}
}
And finally your test
public class TestClass extends Assert {
#Test
public void test() {
InevitableService.makeHappen();
assertTrue(true);
}
}
As a result:
you have no driver in tests
you have no page objects in tests
you operate only high-level logic
Pros:
very flexible
Cons:
gets complicated over time
Considering your reporting tool - I believe it just listens the result of you tests and sends them to server. Or it just takes the xml/html results of you tests and makes pretty and useless pie-charts. Again, has nothing to do with POP.
Steps:
1. Declare variables under Test Suite class
public ExtentReports extent ;
public ExtentTest test;
2. Create object for Extent Managers User defined class
extent = ExtentManager.instance();
3. Pass extent parameter to the Page Object Class
inbound = new DemoPageObject(driver,extent);
4. Goto page object class method and Start with "Start log"
test = extent.startTest("View details", "Unable to view details");
5. For Success steps and we need end test
test.log(LogStatus.PASS, "The list of details are successfully displaying");
test.log(LogStatus.INFO, test.addScreenCapture(ExtentManager.CaptureScreen(driver, "./Send")));
log.info("The list of details are successfully displaying ");
extent.endTest(test);
6. For Failure and no need to end test
test.log(LogStatus.FAIL, "A Technical error is displaying under ");
7. Use #AfterMethod to handle error test cases
#AfterMethod
public void tearDown(ITestResult result) {
if (result.getStatus() == ITestResult.FAILURE) {
test.log(LogStatus.FAIL, "<pre>" + result.getThrowable().getMessage() + "</pre>");
extent.endTest(test);
}
}
8. Finally Adding results to the report
#AfterTest
public void when_I_Close_Browser() {
extent.flush();
}
public class ExtentManager {
public static ExtentReports instance() {
ExtentReports extent;
String Path = "./ExtentReport.html";
System.out.println(Path);
extent = new ExtentReports(Path, true);
//extent.config() .documentTitle("Automation Report").reportName("Regression");
extent
.addSystemInfo("Host Name", "Anshoo")
.addSystemInfo("Environment", "QA");
return extent;
}
public static String CaptureScreen(WebDriver driver, String ImagesPath) {
TakesScreenshot oScn = (TakesScreenshot) driver;
File oScnShot = oScn.getScreenshotAs(OutputType.FILE);
File oDest = new File(ImagesPath + ".jpg");
try {
FileUtils.copyFile(oScnShot, oDest);
} catch (IOException e) {
System.out.println(e.getMessage());
}
return ImagesPath + ".jpg";
}
}
I have this program as shown below , right now its only printng the stacktrace .
my question is that , is it possible to get the stack trace and also a custom field , here in my case i need 1090099
Please tell me if its possible ??
package com;
import org.apache.log4j.Logger;
public class Test {
private static final Logger logger = Logger.getLogger(Test.class);
public static void main(String args[]) {
try {
String accountid = "1090099";
String desc = null;
System.out.println(desc.toUpperCase());
}
catch (Exception t)
{
logger.fatal("Exception inside the Test program ", t);
}
}
}
2013-06-26 21:44:29,723[main] FATAL(Test.java:<main>:16)- Exception inside the Test program
java.lang.NullPointerException
at com.Test.main(Test.java:12)
You have to include it manually in the message you're logging. But it looks to me like what you're really looking for is the MDC (mapped diagnostic context), a way to store values in a thread-local "context" that can then be used to distinguish between log messages relating to different application-level entities.
package com;
import org.apache.log4j.*;
public class Test {
private static final Logger logger = Logger.getLogger(Test.class);
public static void main(String args[]) {
MDC.put("accountid", "1090099");
try {
String desc = null;
System.out.println(desc.toUpperCase());
}
catch (Exception t)
{
logger.fatal("Exception inside the Test program ", t);
} finally {
MDC.remove("accountid");
}
}
}
You would then include %X{accountid} somewhere in your appender's layout pattern and it would include the appropriate MDC entry in every log message, including those logged by third-party code that you call.
I would create my own Exception class, with members to hold the additional information, and a suitable toString() method that displays them. Wrap the original Exception in your custom Exception and add the information you want preserved.
Yes, you can print the value as long as it's in scope.
String accountid = null;
try {
accountid = "1090099";
String desc = null;
System.out.println(desc.toUpperCase());
} catch (Exception t) {
logger.fatal("Exception inside the Test program " + accountid, t);
}
Also, I would suggest using logger.debug instead of system.out.println for your other logging calls...
You are close to achieving that.
In your case you will have to declare the accountid outside the try block and then you can append the accountid along with your Exception inside the Test program message`
String accountid = "";
try {
accountid = "1090099";
String desc = null;
System.out.println(desc.toUpperCase());
}
catch (Exception t)
{
logger.fatal("Exception inside the Test program.\nAccount ID: " + accountid, t);
}