During the running of test case, user wants some information to be logged in the console. Information could be any detail depends upon the purpose. Keeping this in mind that we are using Selenium for testing, we need the information which helps the user to understand the test steps or any failure during the test case execution. With the help of Log4j it is possible to enable loggings during the Selenium test case execution for e.g. let's say you have encountered a failure in the automation test script and it has to be reported in the system. The set of information that you have required to report a bug is :
- A complete test steps to replicate the scenario
- Issue, Description of the failure or reason for the failed test case
- Time stamp for the developers to investigate the issue in detail
Log4j helps us to acheive the above objectives in Selenium Webdriver. When logging is wisely used, it can prove to be an essential tool.
Logging inside the Methods
Logging inside the test case is very tedious task and sooner or later you will find it boring and annoying. Plus everybody has their own way of writing log messages and messages can be less informative and confusing. So why not make it universal. Writing logs message inside the methods is much helpful way, with that we can avoid lots of confusion, save a lot of time and maintain consistency.
How to do it...
1) Download JAR files of Log4j and Add Jars to your project library. You can download it from here. That’s all about the configuration of Apache POI with eclipse. Now you are ready to write your test.
- Create a new XML file – log4j.xml and place it under the Project root folder.
3) Paste the following code in the log4j.xml file.
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="https://jakarta.apache.org/log4j/" debug="false">
<appender name="fileAppender" class="org.apache.log4j.FileAppender">
<param name="Threshold" value="INFO" />
<param name="File" value="logfile.log"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%c{1}] %m %n" />
</layout>
</appender>
<root>
<level value="INFO"/>
<appender-ref ref="fileAppender"/>
</root>
</log4j:configuration>
Note: After pasting the code make sure that the code is exactly same, as copying from HTML may change some symbols (") to (?).
Let's take an example of our previous Apache_POI_TC test case and put log messages in every method and module it interacts with.
- To achieve that we need to create a static Log class, so that we can access its log method in any of our project class. Log class will look like this:
package utility;
import org.apache.log4j.Logger;
public class Log {
// Initialize Log4j logs
private static Logger Log = Logger.getLogger(Log.class.getName());//
// This is to print log for the beginning of the test case, as we usually run so many test cases as a test suite
public static void startTestCase(String sTestCaseName){
Log.info("****************************************************************************************");
Log.info("****************************************************************************************");
Log.info("$$$$$$$$$$$$$$$$$$$$$ "+sTestCaseName+ " $$$$$$$$$$$$$$$$$$$$$$$$$");
Log.info("****************************************************************************************");
Log.info("****************************************************************************************");
}
//This is to print log for the ending of the test case
public static void endTestCase(String sTestCaseName){
Log.info("XXXXXXXXXXXXXXXXXXXXXXX "+"-E---N---D-"+" XXXXXXXXXXXXXXXXXXXXXX");
Log.info("X");
Log.info("X");
Log.info("X");
Log.info("X");
}
// Need to create these methods, so that they can be called
public static void info(String message) {
Log.info(message);
}
public static void warn(String message) {
Log.warn(message);
}
public static void error(String message) {
Log.error(message);
}
public static void fatal(String message) {
Log.fatal(message);
}
public static void debug(String message) {
Log.debug(message);
}
}
- Insert log messages in Home_Page class of pageObject package.
package pageObjects;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import framework.utility.Log;
public class Home_Page {
private static WebElement element = null;
public static WebElement lnk_MyAccount(WebDriver driver){
element = driver.findElement(By.id("account"));
Log.info("My Account link element found");
return element;
}
public static WebElement lnk_LogOut(WebDriver driver){
element = driver.findElement(By.id("account_logout"));
Log.info("Log Out link element found");
return element;
}
}
- Insert log messages in LogIn_Page class of pageObject package.
package pageObjects;
import org.openqa.selenium.*;
import utility.Log;
public class LogIn_Page {
static WebElement element = null;
public static WebElement txtbx_UserName(WebDriver driver){
element = driver.findElement(By.id("log"));
Log.info("Username text box found");
return element;
}
public static WebElement txtbx_Password(WebDriver driver){
element = driver.findElement(By.id("pwd"));
Log.info("Password text box found");
return element;
}
public static WebElement btn_LogIn(WebDriver driver){
element = driver.findElement(By.id("login"));
Log.info("Submit button found");
return element;
}
}
7) Insert log messages in SignIn_Action class of appModule package.
package appModules;
import org.openqa.selenium.WebDriver;
import pageObjects.Home_Page;
import pageObjects.LogIn_Page;
import utility.ExcelUtils;
import utility.Log;
public class SignIn_Action {
public static void Execute(WebDriver driver) throws Exception{
String sUserName = ExcelUtils.getCellData(1, 1);
Log.info("Username picked from Excel is "+ sUserName );
String sPassword = ExcelUtils.getCellData(1, 2);
Log.info("Password picked from Excel is "+ sPassword );
Home_Page.lnk_MyAccount(driver).click();
Log.info("Click action performed on My Account link");
LogIn_Page.txtbx_UserName(driver).sendKeys(sUserName);
Log.info("Username entered in the Username text box");
LogIn_Page.txtbx_Password(driver).sendKeys(sPassword);
Log.info("Password entered in the Password text box");
LogIn_Page.btn_LogIn(driver).click();
Log.info("Click action performed on Submit button");
}
}
- Now it is the time to insert log message into your test script but before that create a ‘New Class‘ and name it as Log4j_Logging_TC by right click on the ‘automationFramework‘ Package and select New > Class.
package automationFramework;
// Import Package Log4j.*
import org.apache.log4j.xml.DOMConfigurator;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.*;
import pageObjects.*;
import utility.*;
import appModules.*;
public class Log4j_Logging_TC {
private static WebDriver driver = null;
public static void main(String[] args) throws Exception {
// Provide Log4j configuration settings
DOMConfigurator.configure("log4j.xml");
Log.startTestCase("Selenium_Test_001");
ExcelUtils.setExcelFile(Constant.Path_TestData + Constant.File_TestData,"Sheet1");
Log.info(" Excel sheet opened");
driver = new FirefoxDriver();
Log.info("New driver instantiated");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Log.info("Implicit wait applied on the driver for 10 seconds");
driver.get(Constant.URL);
Log.info("Web application launched");
SignIn_Action.Execute(driver);
System.out.println("Login Successfully, now it is the time to Log Off buddy.");
Home_Page.lnk_LogOut(driver).click();
Log.info("Click action is perfomred on Log Out link");
driver.quit();
Log.info("Browser closed");
ExcelUtils.setCellData("Pass", 1, 3);
Log.endTestCase("Selenium_Test_001");
}
}
Once your test is complete, go to your project root folder and open the log file. Your log file will look like this:
Your Project explorer window will look like this now.
Note: Still you see some logging in the main test script which ideally has to be avoided or minimized. I have done this so that it can make sense to you. In coming chapters you will see how to avoid logging in main test script.
Next chapter is all about TestNG framework which is the most important chapter of the Selenium Automation Frameworks. Before that I request you to visit first Test Case with TestNG.