How to use Log4j in Selenium | Automate the application logging process

Selenium Log4j

What is log4j?

Apache Log4j is an open source project, which helps developers to log the application activities during run time. Log4j in selenium can be used to track the execution flow, identify problematic area effectively and easy debugging.

Many times you might have noticed the yellow lines hovering below the code written in Eclipse IDE. If you mouse hover on these lines or look into the console (Markers tab), you will find that Eclipse show these as Warnings, which usually may not cause your code not to run, but it simply warns the user of trivial issues, for eg. any class which we have imported but not used.

This warning is one of the logging levels provided by Log4j API. We may configure Log4j to capture these warnings and present it to the user after execution is finished. Similarly, we have following different logging levels:
Selenium Log4j

All above scenarios can be logged into a human-readable format using log4j API in selenium. These logs can be printed on the console or on a file, as per our requirement.

How to implement Log4j in our project

Step 1: Create a Maven Project

Before implementing log4j API, let’s create a sample maven project and add Selenium, TestNG and Log4J API to it. Create a maven project with the following details:

Selenium Log4j

Once the project is created, delete the default package from src/test/java source folder and create a new package com.logging.logs

 

Step 2: Update pom.xml

Head over to pom.xml, remove everything inside <dependencies> </dependencies> tags and replace it with following code.

<dependencies> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>3.14.0</version> </dependency> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>6.14.3</version> <scope>compile</scope> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> </dependencies>

Use Ctrl+Shift+F after pasting above code (if you are using eclipse) to format the pom.xml correctly

In the above code, we have added dependencies for Selenium, TestNG and Apache Log4j. Save the pom.xml file to download all the dependencies automatically. To get the latest dependencies, visit https://mvnrepository.com/ and search for the desired dependency.

Step 3: Create the test class

To implement log4j API and enable logging, first, we will create a test class under com.logging.logs. This class will contain the following 2 tests:

  • Verify if Contact Us link is displayed.
  • Verify that default value in Cart is (empty).

We will use http://automationpractice.com as our demo web application.

Selenium Log4j

Below is the code for these 2 test cases. The code is very simple and self-explanatory so we will no go into much detail.

package com.logging.logs;
import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class Log4jTest {
    
    WebDriver driver;
    
    @BeforeMethod
    public void setup() {
    System.setProperty("webdriver.chrome.driver", "E:chromedriverchromedriver.exe");
    driver = new ChromeDriver();
    driver.manage().window().maximize(); //maximize the browser
    driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS); //define default page time out. Till this time selenium will wait for the element
    driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
    driver.get("http://automationpractice.com");
    }
    
    @Test
    public void testContactUsLink() {
        boolean isLinkPresent = driver.findElement(By.xpath("//a[@title='Contact Us']")).isDisplayed();
        Assert.assertTrue(isLinkPresent);
    }
    
    @Test
    public void testCartValue() {
        String cartValue = driver.findElement(By.xpath("//span[@class='ajax_cart_no_product']")).getText();
        Assert.assertEquals(cartValue, "(empty)");
    }
    
    
    @AfterMethod
    public void tearDown() {
        driver.close();
    }
}

Log4jTest.java

Execute above code as TestNG Test and validate if everything gets passed.

Configure log4j API in our project

What we have done till now is a regular selenium scripting chorus. To use log4j API in our project we have to configure it, which simply means we have to create a .properties file inside some source folder and write down some pre-defined code. This code is already available over the internet and Log4j manual page, we generally make few changes as per our need and rest of the code is used as it is.

Right click on your root folder, select New -> Source Folder and name it as src/main/syslogs. Inside this folder create a file log4j.properties“. Your project structure should be like below:

Selenium Log4j

Open log4j.properties file and paste the following code to it:

#Set the level
log4j.rootCategory=debug, console, file  
  
# Appender for writing to console  
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{MM-dd-yyyy HH:mm:ss} %F %-5p [%t] %c{2} %L - %m%n
  
# Appender for writing to a file  
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=logFile.log
  
# Define maximum size of the log file
log4j.appender.file.MaxFileSize=8mb 
log4j.appender.file.MaxBackupIndex=10
log4j.appender.file.layout=org.apache.log4j.PatternLayout  
log4j.appender.file.layout.ConversionPattern=%d{ISO8601} %5p [%t] %c{1}:%L - %m%n
log4j.appender.file.Append=false

We have already discussed that logs can either be printed on console, file or on a debugger.

  • rootCategory defines the different ways in which we want logs to be generated.
  • ConsoleAppender is used to display logs on Console
  • RollingFileAppender is used to create and store logs in a file.
  • Append=false will overwrite previous logs. To append your current logs to previously generated logs change this value to true.

All the above features are provided by Log4j API and rest of the code we can use as it is. logFile.log is the name of the log file which will be generated upon the execution of our application.

Now run your test as TestNG Test, you will see logs populating in the console area. Once the execution is finished, select your project and click Refresh. There will be a file with name logFile.log containing all the logs which are also displayed on the terminal.

Selenium Log4j

Note: If you are unable to see the logs, change your selenium version to 3.5.3 in pom.xml and then try running the test.

Generating your own customized logs

Follow below steps to create your own logs in Selenium using log4j:

  • Create a Logger object inside the main class.
  • Invoke getLogger() method of Logger class and pass the className.class as an argument to it.
  • Use this object with any of the log levels with our own text.

Update the Log4jTest.java class as following:

package com.logging.logs;
import java.util.concurrent.TimeUnit;
import org.apache.log4j.Logger;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

public class Log4jTest {

    WebDriver driver;
    // Define the Logger object to create own logs
    Logger log = Logger.getLogger(Log4jTest.class);

    @BeforeMethod
    public void setup() {
        System.setProperty("webdriver.chrome.driver", "E:chromedriverchromedriver.exe");
        driver = new ChromeDriver();
        log.info("Chrome Opened");
        driver.manage().window().maximize(); // maximize the browser
        driver.manage().timeouts().pageLoadTimeout(20, TimeUnit.SECONDS); // define default page time out. Till this time selenium will wait for the element            
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
        driver.get("http://automationpractice.com");
        log.info("Application launched");
    }

    @Test
    public void testContactUsLink() throws Exception {
        boolean isLinkPresent = driver.findElement(By.xpath("//a[@title='Contact Us']")).isSelected();
        try {
            if (!isLinkPresent) {
                log.error("Not Found");
            } else {
                Assert.assertTrue(isLinkPresent);
            }
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    @Test
    public void testCartValue() {
        String cartValue = driver.findElement(By.xpath("//span[@class='ajax_cart_no_product']")).getText();
        Assert.assertEquals(cartValue, "(empty)");
    }

    @AfterMethod
    public void tearDown() {
        driver.close();
    }
}

We have updated the class with text in bold. We have created a Logger object log and used it in @BeforeMethod to log the info when our browser is opened and when the application is opened.

In our first @Test, we have modified the code to throw an error, and this error should be logged if condition returns false. Similarly, you can use other log levels and use them in your script.

Author: Dhawal Joshi

A post-graduate in MCA, ISTQB & ITIL certified QA with more than 8 years of experience in QA working with a CMMI Level 5 organization as System Analyst. I started my automation journey with HP UFT(formerly known as QTP) and for the past few years, I am using Selenium for automation. I also have experience in Android Application Development, Java, HTML, and VBScript. When I am not working, I like to spend time with my family, cooking and learning new developments in IT.

2 thoughts on “How to use Log4j in Selenium | Automate the application logging process

Leave a Reply

Your e-mail address will not be published. Required fields are marked *