Introduction to TestNG

   


What is TDD?

Test-Driven Development (TDD) is a software development process that relies on the repetition of a very short development cycle: Red, Green, Refactor. It is more a design technique than a testing technique.


What is TestNG?

TestNG stands for Test Next Generation. It is an open-source testing framework inspired by JUnit and NUnit, designed specifically for the Java programming language. It overcomes the limitations of older frameworks by introducing powerful features for unit testing, functional testing, integration testing, and end-to-end testing.

TestNG's centers on providing a powerful, flexible, and structured environment for running tests. It addresses the limitations of older frameworks by offering features that make writing and managing complex test scenarios easier.


1. Annotation-Driven Structure

Core Concept: Tests are structured using annotations (special markers) that tell the framework what a method is, when it should be run, and how it relates to other methods.

Example: Annotations can mark a method as the setup code to run before an entire test class, the cleanup code to run after a test method, or the test method itself. This provides a clear, logical structure for setting up and tearing down testing environments.


2. Parallel Execution and Grouping

Core Concept: TestNG can run tests in parallel (concurrently), which significantly reduces the total execution time of a large test suite.

Grouping: It allows tests to be assigned to groups (example: "sanity," "regression," "database"). A developer can then choose to run only a specific group of tests, providing granular control over the testing scope.


3. Data-Driven Testing (DDT)

Core Concept: TestNG supports running the same test method multiple times with different sets of input data.

Mechanism: It uses Data Providers to supply various parameters to the test method, efficiently testing a function across many possible inputs without duplicating the test logic.


4. Dependency Management

Core Concept: Tests can be declared as dependent on the successful completion of other test methods.

Benefit: If a setup test (like a login process) fails, TestNG can be configured to skip dependent tests, saving time and clearly indicating the root cause of the failure.


TestNG's Impact:

  • Flexibility: It moves beyond simple unit testing to handle complex integration and system tests.
  • Reporting: It generates detailed, customizable HTML reports, making it easier to analyze test results and identify failures.
  • Scalability: Its features like parallel execution and grouping make it suitable for managing very large and complex test automation projects.












Below are some key features of Testng

  • Annotations:
    TestNG uses a wide variety of annotations (@Test, @BeforeClass, @AfterMethod, etc.) to control test behavior and execution flow.
  • Flexible Test Configuration:
    Allows grouping, prioritization, dependencies, and conditional test execution.
  • Parallel Test Execution:
    You can run multiple tests simultaneously, which reduces total execution time and is useful for large projects.
  • Parameterization:
    TestNG supports both static and dynamic test data through parameters and data providers.
  • Test Suite Execution:
    Tests can be organized into suites using an XML configuration file (testng.xml), allowing you to control test runs from a central place.
  • Powerful Reporting:
    It automatically generates HTML and XML reports after execution, providing insights into test pass/fail status.
  • Integration Support:
    Works well with tools like Maven, Jenkins, Selenium WebDriver, Eclipse, IntelliJ, and various CI/CD tools.
  • Exception Handling:
    It allows defining what exceptions to expect, which helps in testing negative or error-prone scenarios.

Structure of TestNG Testing

  • Test Suite:
    A collection of tests defined in the testng.xml file.
  • Test:
    A test block within a suite. It can include multiple test classes.
  • Test Class:
    Java class containing test methods and configurations.
  • Test Methods:
    Individual test cases.

Test Execution Flow in TestNG

TestNG follows a specific sequence in running methods:

  • BeforeSuite
  • BeforeTest
  • BeforeClass
  • BeforeMethod
  • Test Method
  • AfterMethod
  • AfterClass
  • AfterTest
  • AfterSuite

Types of Testing Supported by TestNG

  • Unit Testing: Test individual components.

  • Functional Testing: Validate business logic.

  • Integration Testing: Test combined modules.

  • Regression Testing: Re-run test cases to ensure no new bugs.

  • Data-Driven Testing: Run same tests with different inputs.


We can use Testng for below scenarios

  • Automating browser testing with Selenium

  • Running API tests

  • Validating database operations

  • Managing large test suites

  • Executing tests in a distributed environment


Tools and Environment Compatibility

  • IDEs: Eclipse, IntelliJ IDEA

  • Build Tools: Maven, Gradle

  • CI/CD Tools: Jenkins, Bamboo

  • Reporting Tools: Allure, ExtentReports

  • Testing Tools: Selenium WebDriver, REST Assured



Suggested Posts:

1. TestNG Suite
2. TestNG Dependent Tests
3. TestNG Reports
4. Parameterization in TestNG
5. Priority in TestNG

How to validate Response by Matchers API in Rest Assured

  



How to Use Hamcrest Matchers in GET API via Rest Assured

Hamcrest is a framework for writing matcher objects, which allow 'match' rules to be defined declaratively. In Rest Assured, we use Hamcrest matchers to write expressive assertions for validating the API response.


We can use the Hamcrest Matchers API in a GET API test by employing the assertThat assertion within your testing framework (like JUnit or TestNG), where the actual value is an element extracted from the API's response body or headers, and the matcher defines the specific expectation.

The entire process follows three theoretical steps: Execute, Extract, and Assert.

You use the Hamcrest Matchers API in a GET API test by employing the assertThat assertion within your testing framework (like JUnit or TestNG), where the actual value is an element extracted from the API's response body or headers, and the matcher defines the specific expectation.

The entire process follows three theoretical steps: Execute, Extract, and Assert.


1. Execute the GET Request

First, your testing tool performs the GET request to the target API endpoint. The result of this execution is the API Response, which contains:
  • Status Line: The HTTP Status Code (example: 200 OK).
  • Headers: Metadata about the response (e.g., Content-Type, Date).
  • Body: The payload, usually in JSON or XML format.

2. Extract the Actual Value

This step involves parsing the response and pulling out the specific piece of data you want to validate.
  • Extraction from the Body: If the response body is JSON (which is common), you use a JSONPath or XPath expression (depending on the testing library, like REST Assured) to navigate the structure and isolate the required value.
Example: Extracting a product name from a nested JSON object.
  • Extraction from Headers: You extract a specific header value directly.
Example: Extracting the value of the Content-Type header.
  • Extraction of Status Code: You get the numeric HTTP status code.
This extracted data becomes the actual value (actual_value) for your Hamcrest assertion.


3. Assert with Hamcrest Matchers

The final step is the assertion, where the extracted value is verified against the expected condition using the Hamcrest syntax: assertThat(actual_value,matcher).











Maven Dependencies:

<dependencies>
    <!-- Rest Assured -->
    <dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>5.3.0</version>
        <scope>test</scope>
    </dependency>

    <!-- Hamcrest -->
    <dependency>
        <groupId>org.hamcrest</groupId>
        <artifactId>hamcrest</artifactId>
        <version>2.2</version>
        <scope>test</scope>
    </dependency>
</dependencies>


Commonly Used Hamcrest Matchers

MatcherDescription
equalTo(value)Check equality
hasItem(value)Check if a list contains item
hasItems(val1, val2)Check if list contains multiple items
not(value)Asserts the opposite
containsString(str)Check substring match
startsWith(str)Check if string starts with



API to be tested:

https://reqres.in/api/users?page=2



API Response of above API











Java Code:

import io.restassured.RestAssured;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;

public class GetApiHamcrestExample {
    public static void main(String[] args) {

        // Set base URI
        RestAssured.baseURI = "https://reqres.in";

        // GET Request with Hamcrest matchers for assertions
        given()
            .log().all()
        .when()
            .get("/api/users?page=2")
        .then()
            .log().all()
            .statusCode(200)
            .body("page", equalTo(2))  // validate page number
            .body("data.id", hasItems(7, 8, 9))  // check if certain user IDs are present
            .body("data.first_name", hasItem("Michael"))  // check first_name list contains value
            .body("support.url", containsString("reqres.in"))  // substring match
            .body("data.email[0]", startsWith("michael"));  // starts with
    }
}



Code Explanation:

(a) Set the base URI
(b) Send the API request
(c) Get the API response nd log on console
(d) Validate API response by Matchers API methods like equalTo(), hasItems(), hasItem(), etc.



Output:

Got 200 server code response as shown below in the response. The validated data from Matcher's API is also mentioned below.

Request:
GET https://reqres.in/api/users?page=2

Response:
200 OK
...
Assertions:
page == 2
data.id contains 7, 8, 9
data.first_name contains "Michael"
support.url contains "reqres.in"
data.email[0] startsWith "michael"


Suggested Posts:

1. Test Basic Authentication in RestAssured
2. Test Preemptive Authentication in RestAssured
3. Test Form Authentication in RestAssured
4. Validate Keys in API in RestAssured
5. Validate XML Schema in RestAssured