TestNG Reporter Log

  



What is Reporter.log in TestNG?

Reporter.log() is a method provided by TestNG to log messages during test execution. These logs are then displayed in the TestNG report, particularly in emailable-report.html and index.html. This is useful for debugging and tracking what happens during a test.


Key purpose of Reporter Logs

1. Persistent Logging for Reports

The primary purpose of the Reporter Log is to provide persisting, method-specific log statements that can be viewed later in the test execution reports. Unlike temporary console output, these logs become a permanent part of the test result documentation.


2. Traceability and Debugging

Reporter logs significantly enhance traceability and debugging. By strategically placing Reporter.log() calls throughout a test method, a tester can record key actions, variable values, or intermediate statuses. If a test fails, these logs provide the necessary context and detailed step-by-step information to diagnose the failure without needing to rerun the test or step through the code manually.


3. Separation from Console Output

The Reporter Log offers a distinct advantage over using standard System.out.println():

  • System.out.println() messages go to the console (standard output), which is often cleared or lost in large test suites and is not included in the default TestNG HTML reports.
  • Reporter.log() messages are captured by the TestNG framework and stored, ensuring they appear specifically in the "Reporter Output" section of the index.html and emailable-report.html.


4. Dual Output Capability

While its main role is reporting, the Reporter class is flexible. It allows an optional boolean parameter in its log() method to direct the message to both the report and the standard console output simultaneously. This gives the user control over where the log message is visible.


5. Log Association

TestNG is designed to associate each log entry with the specific test method or configuration method that generated it. This organization makes the reports structured and easy to read, ensuring logs from one test don't clutter the output of another.













Key Features of Reporter.log():


FeatureDescription
Output locationLogs are printed in TestNG's HTML reports (emailable-report.htmlindex.html) and console if configured.
SyntaxReporter.log(String message)
Overloaded methodReporter.log(String messageboolean logToStandardOutput) where second param lets you print to the console.
Use casesDebugging, logging checkpoints, recording data inputs/outputs, etc.



Basic Syntax:

Reporter.log("Your log message here");




Example Java Code Using Reporter.log()

import org.testng.Assert;
import org.testng.Reporter;
import org.testng.annotations.Test;

public class ReporterLogExample {

    @Test
    public void testLogin() {
        Reporter.log("Opening browser", true);
        Reporter.log("Navigating to login page", true);
        
        String actualTitle = "Login - MyApp";
        String expectedTitle = "Login - MyApp";
        
        Reporter.log("Verifying page title", true);
        Assert.assertEquals(actualTitle, expectedTitle, "Page title doesn't match");

        Reporter.log("Login test passed", true);
    }

    @Test
    public void testSearch() {
        Reporter.log("Starting search test", true);

        String keyword = "TestNG";
        Reporter.log("Searching for keyword: " + keyword, true);
        
        // Dummy output
        boolean searchSuccess = true;

        Reporter.log("Search operation completed", true);
        Assert.assertTrue(searchSuccess, "Search failed");

        Reporter.log("Search test passed", true);
    }
}


Code Explanation:


In the class, two test methods are there, in each method: Reporter.log("message", true) logs message to:

  • TestNG report

  • Console output

  • true as the second argument ensures it prints to the console during execution.
    If omitted or set to false, the message will only appear in the report.


Output Location:

After running the test, you’ll find logs in:

Console output when true is passed that TestNG Report Files:

  • test-output/emailable-report.html
  • test-output/index.html


At a glance:

  • Reporter.log() is a handy tool for tracking and debugging in TestNG tests.
  • It helps you monitor steps, values, and flow in reports.
  • Use the second parameter as true to see logs on the console during execution.



Suggested Posts:

1. Read Excel Data by Data provider
2. Annotations in TestNG
3. TestNG Asserts
4. Priority in TestNG
5. Parameterization in TestNG

Priority in TestNG

 



What is priority in TestNG?


The TestNG Priority is a mechanism used to force a specific execution order among test methods that belong to the same TestNG class. By default, TestNG does not guarantee any particular order for running test methods within a class; they might run in alphabetical order or another unpredictable sequence. Priority allows the developer to override this default behavior.


In TestNG, the priority attribute is used to define the order of execution of test methods in a class.


By default, TestNG executes test methods in alphabetical order of method names (not the order they appear in the code). If you want to control the execution order explicitly, you can assign a priority to each @Test method.














Key Points about priority:

  • The lower the priority number, the earlier the method will run.

  • priority = 0 will run before priority = 1, and so on.

  • If no priority is specified, TestNG assigns it a default priority of 0.

  • You can assign negative values as well.

  • If two or more tests have the same priority, they run in alphabetical order.



Example Java Code for Priority in TestNG

Below is the test class having multiple test methods having attribute priority in @Test annotation.
Output is shown below of the execution of test methods depends on priority values.

import org.testng.annotations.Test;

public class PriorityExample {

    @Test(priority = 1)
    public void testC() {
        System.out.println("Test C - Priority 1");
    }

    @Test(priority = 0)
    public void testA() {
        System.out.println("Test A - Priority 0");
    }

    @Test(priority = 2)
    public void testB() {
        System.out.println("Test B - Priority 2");
    }

    @Test  // No priority mentioned, default is 0
    public void testD() {
        System.out.println("Test D - Default Priority (0)");
    }
}



Output:

Test A - Priority 0
Test D - Default Priority (0)
Test C - Priority 1
Test B - Priority 2



Important points:
  • testA() and testD() both have priority 0. Since testA() comes alphabetically before testD(), it runs first.
  • Priorities help in defining explicit flow of tests, especially in dependent or staged testing scenarios.
  • In TestNG, when multiple test methods have the same priority, TestNG does not guarantee any specific execution order among them. It means that the methods with the same priority may be executed in any order, and this order can change across different runs.
  • Lower priority value = executed earlier
  • Same priority value = no guaranteed order among those methods



Example Code: Same Priority Test Methods

Below in test class, first three test methods have same priority that 1, last method has priority as 0.
Below is the output shown the execution flow of all test methods. Please have a look.

import org.testng.annotations.Test;

public class SamePriorityExample {

    @Test(priority = 1)
    public void testA() {
        System.out.println("Test A - Priority 1");
    }

    @Test(priority = 1)
    public void testB() {
        System.out.println("Test B - Priority 1");
    }

    @Test(priority = 1)
    public void testC() {
        System.out.println("Test C - Priority 1");
    }

    @Test(priority = 0)
    public void testD() {
        System.out.println("Test D - Priority 0");
    }
}



Output:

Test D - Priority 0
Test A - Priority 1
Test B - Priority 1
Test C - Priority 1



Another Run Might Give:

Test D - Priority 0
Test C - Priority 1
Test A - Priority 1
Test B - Priority 1


If multiple test methods share the same priorityTestNG may run them in any order. So, do not rely on order of execution if you assign the same priority to multiple test methods.


Suggested Posts:

1. Introduction to TestNG
2. Annotations in TestNG
3. TestNG Asserts
4. First Script in TestNG
5. Parameterization in TestNG

Read Excel Data by Apache Poi using Data Provider in TestNG

  



Reading data from Excel using Apache POI and supplying it to TestNG                      using @DataProvider is a popular data-driven testing approach in automation frameworks like Selenium.










Below are steps to be executed while reading data from excel sheet using dataprovider.


1. Include Maven Dependency

TestNG itself does not possess the inherent capability to open, navigate, or interpret a Microsoft Excel file (e.g., .xlsx).

To read data from Excel, a project must incorporate an external library (like Apache POI) as a dependency. This library acts as a data bridge that can interact with the Excel file system, understand its sheet and cell structure, and extract the content.


2. @DataProvider

The TestNG method annotated with @DataProvider is where the theoretical work of data retrieval takes place.

(a) Initialization: The Data Provider first uses the external library to locate and open the Excel file and identify the specific sheet containing the test data.

(b) Dimensionality Mapping: It then reads the sheet's dimensions to determine the number of rows (which correspond to the number of test iterations) and the number of columns (which correspond to the number of parameters/data fields required by the test method).

(c) Data Structure Creation: The Data Provider must then create a specific data structure—theoretically a two-dimensional array of objects—to hold all the extracted data. This is the format TestNG expects.

(d) Cell-by-Cell Extraction: It loops through every relevant cell in the Excel sheet:
  • Reads the content of each cell.
  • Handles different data types (e.g., converting a numeric cell value into a string if required by the test).
  • Populates the two-dimensional array with the processed data.

3. Include dataprovider method in @Test annotation

The final step is the consumption of the structured data by the test method.
  • The Contract: The test method, marked with @Test, declares that it accepts the required number of parameters and specifies the name of the Data Provider (the one that performed the Excel reading).
  • Injection: TestNG takes the two-dimensional array generated by the Data Provider and, for each row in the array, it runs the @Test method once, injecting the data fields from that row as input parameters.


You need the following dependencies in pom.xml

  • testng

  • apache poi

  • poi-ooxml (for .xlsx files)

<dependencies>
    <!-- TestNG -->
    <dependency>
        <groupId>org.testng</groupId>
        <artifactId>testng</artifactId>
        <version>7.8.0</version>
        <scope>test</scope>
    </dependency>

    <!-- Apache POI -->
    <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>5.2.3</version>
    </dependency>
</dependencies>




Full Java Code to Read Excel using Apache POI + TestNG DataProvider

In below java class, getData() is annotated with @DataProvider which has code to read data from excel sheet having name 'excelData'.

In test class, in @Test annotation dataprovider method is included by its name with attribute 'dataProvider'

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;

public class ExcelDataProvider {

    @Test(dataProvider = "excelData")
    public void loginTest(String username, String password) {
        System.out.println("Login with Username: " + username + ", Password: " + password);
    }

    @DataProvider(name = "excelData")
    public Object[][] getData() throws IOException {
        String excelPath = "data.xlsx";  // Change path if needed

        FileInputStream fis = new FileInputStream(new File(excelPath));
        Workbook workbook = new XSSFWorkbook(fis);
        Sheet sheet = workbook.getSheetAt(0); // First sheet

        int rowCount = sheet.getPhysicalNumberOfRows();
        int colCount = sheet.getRow(0).getPhysicalNumberOfCells();

        Object[][] data = new Object[rowCount - 1][colCount]; // excluding header

        for (int i = 1; i < rowCount; i++) {
            Row row = sheet.getRow(i);
            for (int j = 0; j < colCount; j++) {
                data[i - 1][j] = row.getCell(j).toString();
            }
        }

        workbook.close();
        fis.close();

        return data;
    }
}




Important points:
 
Row 0 is usually treated as a header, so it's skipped in the loop.
Make sure data.xlsx is in the project root or update the path accordingly.


If we are using CSV files instead of xlsx to read data then instead of Apache POI, we can use BufferedReader class as well. Below is the example showing the same.


@DataProvider(name = "csvData")
public Object[][] readCsv() throws Exception {
    List<Object[]> data = new ArrayList<>();
    BufferedReader reader = new BufferedReader(new FileReader("data.csv"));
    String line;
    while ((line = reader.readLine()) != null) {
        String[] parts = line.split(",");
        data.add(parts);
    }
    reader.close();
    return data.toArray(new Object[0][0]);
}



Java code for read, test, and write result

Below is the java class having code to read and write in excel files. We are reading parameters: username and password from excel sheet using data provider, and giving values of parameters to loginTest()

import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.testng.annotations.*;

import java.io.*;

public class ExcelReadWrite {

    Workbook workbook;
    Sheet sheet;
    String excelPath = "testdata.xlsx";

    @BeforeClass
    public void setupExcel() throws IOException {
        FileInputStream fis = new FileInputStream(new File(excelPath));
        workbook = new XSSFWorkbook(fis);
        sheet = workbook.getSheetAt(0);
    }

    @Test(dataProvider = "excelData")
    public void loginTest(String username, String password, int rowNum) {
        // Example: Assume login successful if password equals "admin123"
        String result = password.equals("admin123") ? "PASS" : "FAIL";
        writeResult(rowNum, 2, result); // Write to 3rd column
    }

    @DataProvider(name = "excelData")
    public Object[][] getData() {
        int rowCount = sheet.getPhysicalNumberOfRows();
        Object[][] data = new Object[rowCount - 1][3]; // 2 inputs + row index

        for (int i = 1; i < rowCount; i++) {
            Row row = sheet.getRow(i);
            data[i - 1][0] = row.getCell(0).toString(); // Username
            data[i - 1][1] = row.getCell(1).toString(); // Password
            data[i - 1][2] = i; // Row number (used for writing result)
        }
        return data;
    }

    public void writeResult(int rowNum, int colNum, String result) {
        Row row = sheet.getRow(rowNum);
        Cell cell = row.createCell(colNum);
        cell.setCellValue(result);
    }

    @AfterClass
    public void saveExcel() throws IOException {
        FileOutputStream fos = new FileOutputStream(new File(excelPath));
        workbook.write(fos);
        fos.close();
        workbook.close();
    }
}



Suggested Posts:

1. Groups in TestNG
2. Annotations in TestNG
3. TestNG Asserts
4. First Script in TestNG
5. Parameterization in TestNG