# Assertion  & hamcrest

Perfect 👍 — this is an important **Java + Selenium + TestNG/JUnit** interview and practical topic.  
Let’s go **step-by-step in detail** on:

> 🔍 `Assert` (from TestNG/JUnit) and  
> 🧩 `Hamcrest Matchers` (from `org.hamcrest`) — what they are, how they differ, and how to use them **in Selenium automation**.

---

# 🧠 1️⃣ What is an Assertion?

### 🔹 Definition:

An **assertion** is a **checkpoint** that verifies whether the **actual result** matches the **expected result** in your test case.

If the condition **passes** → test continues.  
If it **fails** → test stops and marks as **Failed**.

---

# 🧩 2️⃣ Types of Assertions (in Selenium + TestNG)

| Type | Package | Purpose |
| --- | --- | --- |
| **Hard Assert** | `org.testng.Assert` | Stops execution when it fails |
| **Soft Assert** | `org.testng.asserts.SoftAssert` | Collects all failures, reports at the end |
| **Hamcrest Matchers** | `org.hamcrest.*` | Provides advanced, readable, flexible comparison logic |

---

# 🧩 3️⃣ HARD ASSERT (TestNG)

### 🧠 Meaning:

Used for **strict verification**.  
If a Hard Assert fails, test execution **immediately stops** at that line.

### ✅ Common Methods:

| Method | Description |
| --- | --- |
| `Assert.assertEquals(actual, expected)` | Checks equality |
| `Assert.assertNotEquals(actual, expected)` | Checks non-equality |
| `Assert.assertTrue(condition)` | Pass if condition = true |
| `Assert.assertFalse(condition)` | Pass if condition = false |
| `Assert.assertNull(object)` | Pass if object = null |
| `Assert.assertNotNull(object)` | Pass if object ≠ null |
| `Assert.fail("Message")` | Forcefully fail the test |

---

### 🧩 Example (Selenium + TestNG)

```java
import org.testng.Assert;
import org.testng.annotations.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class PaymentAssertionTest {
    @Test
    public void verifyPaymentSuccess() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://example.com/payment");

        driver.findElement(By.id("payNow")).click();
        String actualMessage = driver.findElement(By.id("paymentSuccessMsg")).getText();

        // Hard Assert
        Assert.assertEquals(actualMessage, "Payment Successful", "❌ Payment message mismatch");
        System.out.println("✅ Payment verified successfully");

        driver.quit();
    }
}
```

👉 If message mismatches → test stops immediately and fails.

---

# 🧩 4️⃣ SOFT ASSERT (TestNG)

### 🔹 Meaning:

Soft asserts **don’t stop** the test when they fail.  
They **collect** all failures and report at the end using `.assertAll()`.

### ✅ Syntax:

```java
SoftAssert softAssert = new SoftAssert();
softAssert.assertEquals(actual, expected);
softAssert.assertTrue(condition);
softAssert.assertAll();  // mandatory
```

---

### 🧩 Example (Selenium)

```java
import org.testng.asserts.SoftAssert;

SoftAssert softAssert = new SoftAssert();

softAssert.assertEquals(driver.getTitle(), "Payments");
softAssert.assertTrue(driver.findElement(By.id("payNow")).isDisplayed());
softAssert.assertEquals(actualMessage, "Payment Successful");

System.out.println("✅ Test continued despite assertion failures.");
softAssert.assertAll();  // Collects and reports all failures
```

---

# 🧠 5️⃣ Why Use Hamcrest Matchers?

### 🔹 Problem with Assert:

`Assert` syntax can be **rigid** and **less readable** when you need complex validation:

```java
Assert.assertTrue(actualText.contains("Success"));
```

### 🔹 Solution:

**Hamcrest Matchers** (from `org.hamcrest`) allow **fluent, readable**, and **flexible** conditions like:

```java
assertThat(actualText, containsString("Success"));
```

---

# 🧩 6️⃣ Hamcrest Core Concept

✅ Import:

```java
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
```

✅ Syntax:

```java
assertThat(actualValue, matcherCondition);
```

---

# 🧱 7️⃣ Common Hamcrest Matchers

| Matcher | Description | Example |
| --- | --- | --- |
| `equalTo()` | Checks equality | `assertThat(title, equalTo("Dashboard"));` |
| `is()` | Same as equalTo (adds readability) | `assertThat(amount, is(100));` |
| `not()` | Negation | `assertThat(status, not("Failed"));` |
| `containsString()` | Checks substring | `assertThat(msg, containsString("Success"));` |
| `startsWith()` / `endsWith()` | String prefix/suffix | `assertThat(url, startsWith("https"));` |
| `greaterThan()` / `lessThan()` | Numeric comparison | `assertThat(price, greaterThan(0));` |
| `hasItem()` | Checks if collection has element | `assertThat(list, hasItem("Product1"));` |
| `hasItems()` | Multiple elements | `assertThat(list, hasItems("Item1", "Item2"));` |
| `instanceOf()` | Checks type | `assertThat(driver, instanceOf(WebDriver.class));` |
| `anyOf()` | Logical OR | `assertThat(status, anyOf(is("OK"), is("Done")));` |
| `allOf()` | Logical AND | `assertThat(msg, allOf(containsString("Payment"), containsString("Success")));` |

---

# 🧩 8️⃣ Example — Hamcrest in Selenium

```java
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.Test;

public class HamcrestPaymentTest {

    @Test
    public void verifyPaymentConfirmation() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://example.com/checkout");
        driver.findElement(By.id("payNow")).click();

        String confirmationMsg = driver.findElement(By.id("paymentSuccessMsg")).getText();

        // Hamcrest Assertions
        assertThat("✅ Payment confirmation validation",
                   confirmationMsg,
                   allOf(startsWith("Payment"), containsString("Success")));

        String url = driver.getCurrentUrl();
        assertThat(url, containsString("confirmation"));

        driver.quit();
    }
}
```

🟢 **Output:** Test passes only if message starts with “Payment” and includes “Success”.

---

# ⚙️ 9️⃣ Combining Hamcrest + TestNG SoftAssert (Advanced)

Sometimes you can use both to get readable, non-blocking checks:

```java
SoftAssert softAssert = new SoftAssert();

try {
    assertThat(price, greaterThan(0.0));
} catch (AssertionError e) {
    softAssert.fail(e.getMessage());
}

try {
    assertThat(message, containsString("Success"));
} catch (AssertionError e) {
    softAssert.fail(e.getMessage());
}

softAssert.assertAll();
```

✅ Gives best of both worlds — flexible matching + multiple validation collection.

---

# 🧠 1️⃣0️⃣ Hamcrest Logical Matchers (Advanced)

| Matcher | Description | Example |
| --- | --- | --- |
| `allOf(m1, m2, m3)` | All must match (AND) | `assertThat(value, allOf(greaterThan(10), lessThan(20)));` |
| `anyOf(m1, m2)` | Any one can match (OR) | `assertThat(color, anyOf(is("Red"), is("Blue")));` |
| `not(anyOf(...))` | None should match | `assertThat(status, not(anyOf(is("Fail"), is("Error"))));` |

---

# 🧾 1️⃣1️⃣ Real E-commerce Payment Example (Combined)

```java
@Test
public void verifyPaymentFlow() {
    WebDriver driver = new ChromeDriver();
    driver.get("https://shopdemo.example.com");

    driver.findElement(By.id("addToCart")).click();
    driver.findElement(By.id("checkout")).click();
    driver.findElement(By.id("payNow")).click();

    String message = driver.findElement(By.id("paymentSuccessMsg")).getText();
    double totalAmount = Double.parseDouble(driver.findElement(By.id("totalAmount")).getText().replace("$", ""));

    assertThat("Verify payment confirmation message",
               message,
               allOf(containsString("Payment"), containsString("Success")));

    assertThat("Verify total amount greater than zero", totalAmount, greaterThan(0.0));

    assertThat("Verify redirection URL", driver.getCurrentUrl(), containsString("confirmation"));

    driver.quit();
}
```

---

# 🧠 1️⃣2️⃣ Difference Summary Table

| Feature | TestNG Assert | SoftAssert | Hamcrest |
| --- | --- | --- | --- |
| Stops on failure | ✅ Yes | ❌ No | ✅ Yes |
| Reports multiple failures | ❌ No | ✅ Yes | ❌ No |
| Readability | Medium | Medium | ✅ High |
| Complex matching | Limited | Limited | ✅ Very Flexible |
| Logical combinations | ❌ No | ❌ No | ✅ Yes (`allOf`, `anyOf`) |
| Common use | Functional tests | Batch verifications | Readable validation |

---

# ✅ Summary in One Line

> 🔹 **Use** `Assert` for simple direct verifications.  
> 🔹 **Use** `SoftAssert` when you need to collect multiple results.  
> 🔹 **Use** `Hamcrest Matchers` when you want expressive, flexible, human-readable validation in automation frameworks.

---

Would you like me to show you  
👉 a **real-time hybrid example** where TestNG, SoftAssert, and Hamcrest are used **together** in a single Selenium test (like full payment flow validation)?

##### You said:

give for rest assured

###### ChatGPT said:

Excellent 🔥 — now let’s go **deep into** `Assert` and `Hamcrest Matchers` in REST Assured,  
which is extremely important for **API Testing automation** interviews and frameworks.

We’ll cover everything step-by-step —  
✅ From basics → advanced usage → real e-commerce payment API example.

---

## 🧠 1️⃣ What is REST Assured?

`REST Assured` is a **Java library** for **testing REST APIs**.  
It helps to:

* Send API requests (`GET`, `POST`, `PUT`, `DELETE`, etc.)
    
* Validate **status codes**, **response bodies**, and **headers**
    
* Perform **BDD-style assertions** using **Hamcrest Matchers**
    

---

## 🧩 2️⃣ Types of Assertions in REST Assured

| Type | Description | Example |
| --- | --- | --- |
| **Inline Assertions** | Done inside `.then()` using Hamcrest matchers | `.then().body("status", equalTo("success"))` |
| **External Assertions (TestNG/JUnit)** | Done after extracting response data | `Assert.assertEquals(statusCode, 200)` |
| **Multiple Assertions** | Combine both styles for deeper checks | BDD + TestNG combo |

---

## ⚙️ 3️⃣ Basic REST Assured Structure

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

given()
    .baseUri("https://api.example.com")
    .when()
    .get("/payment/status")
    .then()
    .statusCode(200)
    .body("status", equalTo("SUCCESS"));
```

✅ Here:

* `given()` → Setup request
    
* `when()` → Trigger API call
    
* `then()` → Verify response using **Hamcrest Matchers**
    

---

## 🧱 4️⃣ Using `Assert` (TestNG / JUnit) with REST Assured

You can extract response data and validate using **TestNG Assert**:

```java
import io.restassured.response.Response;
import org.testng.Assert;

Response response = 
    given()
        .baseUri("https://api.example.com")
        .when()
        .get("/payment/status");

int statusCode = response.getStatusCode();
String status = response.jsonPath().getString("status");

Assert.assertEquals(statusCode, 200, "Invalid Status Code");
Assert.assertEquals(status, "SUCCESS", "Payment status failed");
```

🟢 **Use this approach** when you need detailed validation logic or multiple fields.

---

## 🧠 5️⃣ Hamcrest Matchers in REST Assured

REST Assured integrates **Hamcrest** for **BDD-style validation** directly in `.then()` section.

### 🔹 Import Required:

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

### 🔹 Example:

```java
given()
    .baseUri("https://api.example.com")
    .when()
    .get("/order/123")
    .then()
    .statusCode(200)
    .body("orderId", equalTo(123))
    .body("payment.status", is("Success"))
    .body("items.size()", greaterThan(0));
```

✅ **Advantages:**

* Fluent and readable
    
* No need for explicit response extraction
    
* Combines multiple checks easily
    

---

## 🧩 6️⃣ Commonly Used Hamcrest Matchers in REST Assured

| Matcher | Usage | Example |
| --- | --- | --- |
| `equalTo(value)` | Exact equality | `.body("status", equalTo("Success"))` |
| `is(value)` | Same as equalTo | `.body("amount", is(1000))` |
| `not(value)` | Negation | `.body("status", not("Failed"))` |
| `hasItem(value)` | For lists | `.body("items.name", hasItem("Laptop"))` |
| `hasItems(...)` | Multiple items | `.body("items.name", hasItems("Phone", "Tablet"))` |
| `containsString(value)` | Partial text match | `.body("message", containsString("Payment"))` |
| `startsWith(value)` | Prefix | `.body("status", startsWith("Suc"))` |
| `endsWith(value)` | Suffix | `.body("status", endsWith("cess"))` |
| `greaterThan(value)` | Numeric compare | `.body("amount", greaterThan(0))` |
| `lessThan(value)` | Numeric compare | `.body("discount", lessThan(50))` |
| `anyOf(...)` | Logical OR | `.body("status", anyOf(is("Success"), is("Pending")))` |
| `allOf(...)` | Logical AND | `.body("message", allOf(containsString("Payment"), containsString("Success")))` |

---

## 🧾 7️⃣ Real E-commerce Payment API Example

### 🧩 Scenario:

User makes a payment — `/api/payment/confirm` returns:

```java
{
  "transactionId": "TXN12345",
  "status": "Success",
  "amount": 999.99,
  "currency": "INR",
  "message": "Payment Successful",
  "paymentMode": "UPI"
}
```

### ✅ Test Case (Hamcrest + REST Assured)

```java
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
import org.testng.annotations.Test;

public class PaymentAPITest {

    @Test
    public void verifyPaymentConfirmation() {
        given()
            .baseUri("https://api.ecommerce.com")
            .contentType("application/json")
            .body("{\"orderId\":\"ORD12345\", \"amount\":999.99, \"mode\":\"UPI\"}")
        .when()
            .post("/api/payment/confirm")
        .then()
            .statusCode(200)
            .body("status", equalTo("Success"))
            .body("message", containsString("Payment"))
            .body("amount", greaterThan(0.0f))
            .body("currency", is("INR"))
            .body("paymentMode", anyOf(is("UPI"), is("Card"), is("NetBanking")));
    }
}
```

🟢 Here we validated:

* HTTP status
    
* Response fields
    
* Value ranges
    
* Logical OR for multiple payment modes
    

---

## ⚙️ 8️⃣ Extract + Test Using Assert + Hamcrest Hybrid

You can combine both styles for flexible logic:

```java
import io.restassured.response.Response;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;
import org.testng.Assert;

Response response = 
    given()
        .baseUri("https://api.ecommerce.com")
        .when()
        .get("/api/payment/ORD12345");

int statusCode = response.getStatusCode();
String status = response.jsonPath().getString("status");
double amount = response.jsonPath().getDouble("amount");

// TestNG assertions
Assert.assertEquals(statusCode, 200, "Invalid Status Code");
Assert.assertNotNull(status, "Status missing");

// Hamcrest matchers
assertThat(status, is("Success"));
assertThat(amount, greaterThan(0.0));
```

✅ Use this style when you want flexibility + detailed failure messages.

---

## 🧠 9️⃣ Validating Complex JSON Responses

Example:

```java
{
  "orders": [
    { "id": 1, "status": "Delivered" },
    { "id": 2, "status": "Shipped" }
  ]
}
```

Validation:

```java
given()
    .when()
    .get("/orders")
    .then()
    .statusCode(200)
    .body("orders.id", hasItems(1, 2))
    .body("orders.status", hasItem("Shipped"));
```

---

## ⚡ 1️⃣0️⃣ Validate Response Headers and Time

```java
given()
    .when()
    .get("/api/payment/ORD12345")
    .then()
    .statusCode(200)
    .header("Content-Type", equalTo("application/json"))
    .time(lessThan(2000L)); // response within 2 seconds
```

---

## 💥 1️⃣1️⃣ Error Handling Example (Negative Test)

```java
given()
    .baseUri("https://api.ecommerce.com")
    .when()
    .get("/api/payment/invalidOrder")
    .then()
    .statusCode(404)
    .body("error.message", containsString("Order not found"))
    .body("error.code", equalTo("404_NOT_FOUND"));
```

---

## 🧩 1️⃣2️⃣ Difference Between Assert & Hamcrest in REST Assured

| Feature | TestNG / JUnit Assert | Hamcrest Matcher |
| --- | --- | --- |
| Style | Procedural | Fluent / BDD-style |
| Readability | Medium | ✅ Very high |
| Multiple Checks | Manual | Inline (chained) |
| JSON Support | Needs parsing | Built-in path validation |
| Failure Message | Simple | Descriptive |
| Typical Use | Extracted response validation | Inline `.then().body()` checks |

---

## 🧠 1️⃣3️⃣ Chaining Multiple Conditions (allOf / anyOf)

```java
given()
    .when()
    .get("/api/payment/ORD12345")
    .then()
    .body("message", allOf(containsString("Payment"), containsString("Success")))
    .body("status", anyOf(is("Success"), is("Completed")));
```

✅ Combines multiple conditions cleanly.

---

## 🧾 1️⃣4️⃣ Complete Example: Payment Module Test Flow

```java
@Test
public void testFullPaymentFlow() {
    given()
        .baseUri("https://api.ecommerce.com")
        .contentType("application/json")
        .body("{\"userId\":1, \"orderId\":\"ORD1001\", \"amount\":500.0}")
    .when()
        .post("/api/payment/confirm")
    .then()
        .statusCode(200)
        .body("status", equalTo("Success"))
        .body("transactionId", notNullValue())
        .body("message", containsString("Successful"))
        .body("paymentMode", anyOf(is("UPI"), is("Card")))
        .body("amount", greaterThan(0.0f))
        .body("currency", is("INR"))
        .header("Content-Type", containsString("application/json"));
}
```

---

## ✅ 1️⃣5️⃣ Summary

| Use Case | Use This |
| --- | --- |
| Simple equality checks | `Assert.assertEquals()` |
| Multiple, human-readable validations | `Hamcrest Matchers` |
| Inline JSON + header validation | `.then().body()` + Hamcrest |
| Extract → post-validation logic | `Assert` + extracted values |
| Logical / compound checks | `allOf()`, `anyOf()` |

---

Would you like me to give you a **real-world API test class** that covers:

* `GET`, `POST`, `PUT`, `DELETE`
    
* uses both `Assert` and `Hamcrest`
    
* for a full **e-commerce payment + order API flow** (end-to-end)?
    

##### You said:

json and json path in detail and give playground for practice

###### ChatGPT said:

Perfect 🔥 — this is one of the **most important topics** in API Testing and automation with **REST Assured** and **Selenium frameworks**:

Let’s go **step-by-step** and **in-depth** on 👇

> **JSON + JSONPath** with full explanation, syntax, practical examples, and free playgrounds for hands-on practice.

---

# 🧠 1️⃣ What is JSON?

### 🔹 Definition:

**JSON** (JavaScript Object Notation) is a **lightweight data-interchange format** used to store and exchange data between systems — mostly between **client** and **server** in REST APIs.

It’s easy for **humans to read** and **machines to parse**.

---

### 🧩 Basic JSON Example

```java
{
  "id": 101,
  "name": "Shreenibas",
  "email": "shree@test.com",
  "isActive": true,
  "skills": ["Java", "Selenium", "API Testing"],
  "address": {
    "city": "Bhubaneswar",
    "pin": 751024
  }
}
```

---

# 🧱 2️⃣ JSON Data Types

| Type | Example | Notes |
| --- | --- | --- |
| **String** | `"Selenium"` | Text in double quotes |
| **Number** | `101`, `99.9` | No quotes |
| **Boolean** | `true`, `false` | Lowercase only |
| **Null** | `null` | Represents no value |
| **Array** | `["A", "B", "C"]` | List of values |
| **Object** | `{"key":"value"}` | Key-value pairs |

---

# 🧠 3️⃣ JSON Structure Hierarchy

| Level | Type | Description |
| --- | --- | --- |
| Root | Object `{}` | Holds all key–value pairs |
| Nested Object | Object inside another | `"address": { "city": "Delhi" }` |
| Array | `[]` | List of objects or values |
| Nested Array | Array inside array/object | `"orders": [ { "id":1 }, { "id":2 } ]` |

---

# 🧩 4️⃣ What is JSONPath?

### 🔹 Definition:

**JSONPath** is a **query language** for extracting specific data from JSON.  
It’s similar to **XPath** (for XML).

👉 It helps you **navigate JSON** using keys, indexes, and filters.

---

# ⚙️ 5️⃣ Basic JSONPath Syntax

| Symbol | Meaning | Example |
| --- | --- | --- |
| `$` | Root element | `$` |
| `.` | Child operator | `$.name` |
| `[]` | Array index or filter | `$.skills[0]` |
| `*` | Wildcard (any element) | `$.skills[*]` |
| `..` | Recursive descent (any depth) | `$..id` |
| `[?()]` | Filter expression | `$.students[?(@.marks>80)]` |
| `[start:end]` | Slice operator | `$.skills[0:2]` |

---

# 🧾 6️⃣ Example JSON for Practice

Let’s use this JSON:

```java
{
  "company": "TechCorp",
  "employees": [
    {
      "id": 1,
      "name": "Alice",
      "role": "QA",
      "skills": ["Selenium", "Java", "API Testing"],
      "salary": 60000
    },
    {
      "id": 2,
      "name": "Bob",
      "role": "Developer",
      "skills": ["Java", "SpringBoot"],
      "salary": 90000
    },
    {
      "id": 3,
      "name": "Carol",
      "role": "Manager",
      "skills": ["Leadership", "Planning"],
      "salary": 120000
    }
  ]
}
```

---

# 🧠 7️⃣ JSONPath Examples Explained

| Query | Description | Output |
| --- | --- | --- |
| `$.company` | Get company name | `"TechCorp"` |
| `$.employees[0].name` | Get first employee name | `"Alice"` |
| `$.employees[*].name` | Get all employee names | `["Alice","Bob","Carol"]` |
| `$..name` | Get all names (at any level) | `["Alice","Bob","Carol"]` |
| `$.employees[?(@.role=="Developer")].name` | Get developer’s name | `"Bob"` |
| `$.employees[?(@.salary>70000)].name` | Employees with salary &gt; 70000 | `["Bob","Carol"]` |
| `$.employees[?(@.skills[?(@=="Java")])].name` | Employees having Java skill | `["Alice","Bob"]` |
| `$.employees[-1:]` | Last employee | `{ "id":3,"name":"Carol"... }` |
| `$.employees[0:2].name` | First two names | `["Alice","Bob"]` |

---

# 🧩 8️⃣ JSONPath in REST Assured

In **REST Assured**, `JsonPath` helps to extract data from API response.

### Example:

```java
import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import static io.restassured.RestAssured.*;

Response response = 
    given()
        .baseUri("https://api.techcorp.com")
    .when()
        .get("/employees");

JsonPath json = response.jsonPath();
System.out.println(json.getString("employees[0].name"));   // Alice
System.out.println(json.getList("employees.name"));        // [Alice, Bob, Carol]
System.out.println(json.getInt("employees[1].salary"));    // 90000
```

---

# ⚙️ 9️⃣ JSONPath — Filtering and Conditions in REST Assured

```java
List<String> highEarners = json.getList("employees.findAll { it.salary > 80000 }.name");
System.out.println(highEarners); // [Bob, Carol]
```

✅ `findAll { it.condition }` → Groovy syntax used by REST Assured internally.

---

# 🧩 🔟 Advanced JsonPath with Groovy (used by REST Assured)

| Expression | Description |
| --- | --- |
| `find { it.key == 'value' }` | Returns first match |
| `findAll { it.salary > 80000 }` | Returns all matches |
| `collect { it.name }` | Extract property values |
| `size()` | Returns array length |
| `sum()` | Returns total sum of numeric array |

### Example:

```java
List<Integer> salaries = json.getList("employees.salary");
int total = salaries.stream().mapToInt(Integer::intValue).sum();
System.out.println("Total Salary: " + total);
```

---

# 🧾 1️⃣1️⃣ Example: Extract Nested Data

```java
String firstSkill = json.getString("employees[0].skills[1]");  // Java
List<String> allSkills = json.getList("employees.skills.flatten()");
System.out.println(allSkills);
```

👉 `.flatten()` merges all nested arrays into one.

---

# 🧠 1️⃣2️⃣ Real REST Assured Example with JSONPath

```java
@Test
public void verifyEmployeeData() {
    Response response = 
        given()
            .baseUri("https://api.techcorp.com")
        .when()
            .get("/employees");

    JsonPath json = response.jsonPath();
    
    // Extract values
    List<String> names = json.getList("employees.name");
    List<Integer> salaries = json.getList("employees.salary");
    String firstRole = json.getString("employees[0].role");

    System.out.println("Names: " + names);
    System.out.println("Salaries: " + salaries);
    System.out.println("First role: " + firstRole);

    // Assertions
    assertThat(json.getString("company"), equalTo("TechCorp"));
    assertThat(json.getInt("employees.size()"), greaterThan(2));
    assertThat(names, hasItems("Alice", "Bob"));
}
```

---

# 🧩 1️⃣3️⃣ Common Mistakes to Avoid

| Mistake | Example | Fix |
| --- | --- | --- |
| Wrong index | `$.employees[3]` | Check array size first |
| Wrong type | Using `.getInt()` on string | Match correct data type |
| Misusing filter | `@.role` vs `@['role']` | Use correct attribute name |
| Forget `$` root | `.employees` without `$` | Always start with `$` (except REST Assured auto-handling) |

---

# 🧰 1️⃣4️⃣ Tools & Playgrounds for Practice

Here are the **best free JSON & JSONPath playgrounds** 👇

| Tool | Link | Features |
| --- | --- | --- |
| **JSONPath Online Evaluator (jsonpath.com)** | 🌐 [https://jsonpath.com](https://jsonpath.com) | Paste JSON + run queries live |
| **JSONPath Finder (jsonpathfinder.com)** | 🌐 [https://jsonpathfinder.com](https://jsonpathfinder.com) | Click elements → auto generates JSONPath |
| **CodeBeautify JSON Viewer** | 🌐 [https://codebeautify.org/jsonviewer](https://codebeautify.org/jsonviewer) | Format, validate, visualize |
| **JsonPath Expression Tester (jsonpath.herokuapp.com)** | 🌐 https://jsonpath.herokuapp.com/ | Advanced filter testing |
| **REQBIN API Playground** | 🌐 [https://reqbin.com/](https://reqbin.com/) | Send API requests and test JSONPath inline |

👉 I recommend using [**https://jsonpath.com**](https://jsonpath.com) for live testing — just paste the sample JSON and try the queries above.

---

# 🧾 1️⃣5️⃣ Mini Practice Challenges 🧩

### Use this JSON 👇 in [https://jsonpath.com](https://jsonpath.com)

```java
{
  "store": {
    "book": [
      { "category": "reference", "price": 8.95 },
      { "category": "fiction", "price": 12.99 },
      { "category": "fiction", "price": 22.99 }
    ],
    "bicycle": {
      "color": "red",
      "price": 19.95
    }
  }
}
```

| Task | JSONPath | Expected Output |
| --- | --- | --- |
| All book categories | `$.store.book[*].category` | `["reference","fiction","fiction"]` |
| Second book price | `$.store.book[1].price` | `12.99` |
| All prices &gt; 10 | `$.store.book[?(@.price>10)].price` | `[12.99, 22.99]` |
| Bicycle color | `$.store.bicycle.color` | `"red"` |

---

# 🧠 1️⃣6️⃣ Summary Table

| Concept | JSON | JSONPath | REST Assured Usage |
| --- | --- | --- | --- |
| Structure | Key-value | Query language | Data extraction |
| Syntax | `{}` and `[]` | `$`, `.`, `[]`, `?()` | `jsonPath().get()` |
| Used for | Representing data | Querying JSON | Validate/extract API response |
| Example | `{ "name":"John" }` | `$.name` | `response.jsonPath().get("name")` |

---

Would you like me to give you a **hands-on REST Assured project exercise** (with sample APIs + JSONPath queries + assertions) that you can directly run in Eclipse or IntelliJ?  
It will simulate a **real e-commerce API** (products + cart + payments).

##### You said:

ok

###### ChatGPT said:

Perfect 👍 let’s now move to a **hands-on REST Assured project exercise** using **JSON + JSONPath** with a **realistic e-commerce API simulation** —  
so you can directly practice in **Eclipse/IntelliJ** or **Postman** and master data extraction + validation.

---

## 🏪 Realistic Scenario — E-Commerce REST API

You’re testing an **E-Commerce backend** that handles:

* Product catalog
    
* Cart operations
    
* Order placement
    
* Payment module
    

Each API returns **JSON** responses you’ll validate using **REST Assured** + **JSONPath**.

---

## ⚙️ Project Setup (pom.xml)

Make sure these dependencies exist:

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

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

    <!-- Hamcrest for assertions -->
    <dependency>
        <groupId>org.hamcrest</groupId>
        <artifactId>hamcrest</artifactId>
        <version>2.2</version>
    </dependency>
</dependencies>
```

---

## 🧩 Step 1️⃣ — Sample Product List API Response

### **GET /products**

```java
{
  "store": {
    "products": [
      {
        "id": 101,
        "name": "Laptop",
        "brand": "HP",
        "price": 75000,
        "stock": 10,
        "category": "Electronics"
      },
      {
        "id": 102,
        "name": "Smartphone",
        "brand": "Samsung",
        "price": 35000,
        "stock": 25,
        "category": "Mobiles"
      },
      {
        "id": 103,
        "name": "Shoes",
        "brand": "Puma",
        "price": 3500,
        "stock": 100,
        "category": "Fashion"
      }
    ]
  }
}
```

---

## 🧠 Step 2️⃣ — JSONPath Queries to Extract Data

| Goal | JSONPath | Output |
| --- | --- | --- |
| All product names | `$.store.products[*].name` | `["Laptop","Smartphone","Shoes"]` |
| First product name | `$.store.products[0].name` | `"Laptop"` |
| All prices | `$.store.products[*].price` | `[75000, 35000, 3500]` |
| Brand of product with id 102 | `$.store.products[?(@.id==102)].brand` | `"Samsung"` |
| Products with price &lt; 40000 | `$.store.products[?(@.price<40000)].name` | `["Smartphone","Shoes"]` |

👉 Try these in [https://jsonpath.com](https://jsonpath.com) to visualize them live.

---

## 💻 Step 3️⃣ — REST Assured Test Code

```java
package com.ecommerce.api;

import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import org.testng.annotations.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class ProductAPITest {

    @Test
    public void verifyProductListAPI() {
        // Fake endpoint for demo (you can mock it using ReqRes or Postman Mock)
        Response response = given()
                .baseUri("https://api.mocki.io/v2/5185415ba171ea3a00704eed") // use your endpoint
            .when()
                .get("/products");

        // Validate status code
        response.then().statusCode(200);

        JsonPath json = response.jsonPath();

        // Extract values
        String firstProduct = json.getString("store.products[0].name");
        int secondProductPrice = json.getInt("store.products[1].price");
        int totalProducts = json.getList("store.products").size();

        System.out.println("First Product: " + firstProduct);
        System.out.println("Second Product Price: " + secondProductPrice);
        System.out.println("Total Products: " + totalProducts);

        // Assertions
        assertThat(firstProduct, equalTo("Laptop"));
        assertThat(secondProductPrice, greaterThan(30000));
        assertThat(totalProducts, equalTo(3));
    }
}
```

---

## 🧩 Step 4️⃣ — Extract and Validate with Filters

```java
@Test
public void verifyFilterProducts() {
    Response response = get("https://mockapi.io/fake-store/products");
    JsonPath json = response.jsonPath();

    // Extract product names cheaper than 40000
    List<String> cheapProducts = json.getList("store.products.findAll { it.price < 40000 }.name");
    System.out.println("Affordable Products: " + cheapProducts);

    // Assert
    assertThat(cheapProducts, hasItems("Smartphone", "Shoes"));
}
```

---

## 💰 Step 5️⃣ — Simulated Payment API

### **POST /payment**

```java
{
  "paymentId": "P12345",
  "orderId": "O9876",
  "amount": 35000,
  "method": "UPI",
  "status": "Success",
  "transaction": {
    "timestamp": "2025-11-11T08:30:00Z",
    "bankRef": "ICIC12345",
    "currency": "INR"
  }
}
```

### ✅ Validation Example

```java
@Test
public void verifyPaymentResponse() {
    String responseBody = "{ \"paymentId\":\"P12345\", \"orderId\":\"O9876\", \"amount\":35000, \"method\":\"UPI\", \"status\":\"Success\" }";

    JsonPath json = new JsonPath(responseBody);

    // Extract
    String status = json.getString("status");
    int amount = json.getInt("amount");

    // Assert
    assertThat(status, equalTo("Success"));
    assertThat(amount, greaterThan(0));
}
```

---

## 🧾 Step 6️⃣ — JSONPath Practice Challenges for You 🎯

| Task | JSONPath | Expected Result |
| --- | --- | --- |
| Get total number of products | `$.store.products.length()` | `3` |
| Get all categories | `$.store.products[*].category` | `["Electronics","Mobiles","Fashion"]` |
| Find product with minimum price | `$.store.products.min { it.price }.name` | `"Shoes"` |
| Get all stock quantities | `$.store.products[*].stock` | `[10,25,100]` |
| Get products with brand "HP" | `$.store.products[?(@.brand=='HP')].name` | `"Laptop"` |

---

## 🧠 Step 7️⃣ — Integration Idea (for Real Practice)

You can simulate the whole flow:

1. **GET /products** → extract product ID & price
    
2. **POST /cart** → add product to cart
    
3. **POST /order** → place order
    
4. **POST /payment** → simulate payment success
    
5. **GET /order/{id}** → verify order status = "Completed"
    

Each response is JSON — you’ll extract and assert data with **JsonPath**.

---

## 🧰 Step 8️⃣ — Recommended Practice Tools

| Tool | Use | Link |
| --- | --- | --- |
| **Postman** | Create Mock APIs | [https://www.postman.com/](https://www.postman.com/) |
| **ReqRes** | Public JSON API | [https://reqres.in/](https://reqres.in/) |
| **MockAPI.io** | Custom JSON endpoints | [https://mockapi.io/](https://mockapi.io/) |
| **JSONPath.com** | Test JSONPath queries | [https://jsonpath.com/](https://jsonpath.com/) |

---

## 🏁 Summary

| Concept | Where Used | Tool / Syntax |
| --- | --- | --- |
| JSON | API Response | `{ "key": "value" }` |
| JSONPath | Query data | `$.store.products[0].name` |
| REST Assured | Validate response | `response.jsonPath().get("key")` |
| Hamcrest | Assertions | `assertThat(value, equalTo("Success"))` |
| Groovy | Advanced filters | `findAll { it.price < 40000 }` |

---

Would you like me to add the **next part** —

> 🔹 “E-Commerce Full Flow API Automation Project” (Products → Cart → Payment → Assertions)  
> with **end-to-end REST Assured TestNG code** and reusable JSONPath extraction?

It’ll be a real-world ready mini framework example.

##### You said:

yes

###### ChatGPT said:

Perfect ⚡ — let’s build your **End-to-End E-Commerce API Automation Project** using **REST Assured + TestNG + JSONPath + Hamcrest**.

We’ll simulate a **real automation tester workflow** for:  
🛒 Products → 🧺 Cart → 📦 Order → 💳 Payment

This will give you a *mini automation framework* you can run in Eclipse or IntelliJ — perfect for resume projects and interviews.

---

## 🧱 1️⃣ PROJECT STRUCTURE

```java
ecommerce-api-automation/
│
├── pom.xml
├── src/
│   └── test/java/
│       └── com/ecommerce/tests/
│           ├── BaseTest.java
│           ├── ProductTest.java
│           ├── CartTest.java
│           ├── OrderTest.java
│           └── PaymentTest.java
└── testng.xml
```

---

## ⚙️ 2️⃣ pom.xml Dependencies

```java
<dependencies>
    <!-- REST Assured -->
    <dependency>
        <groupId>io.rest-assured</groupId>
        <artifactId>rest-assured</artifactId>
        <version>5.4.0</version>
        <scope>test</scope>
    </dependency>

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

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

    <!-- JSON -->
    <dependency>
        <groupId>org.json</groupId>
        <artifactId>json</artifactId>
        <version>20240303</version>
    </dependency>
</dependencies>
```

---

## 🌐 3️⃣ Mock API Setup (you can use any of these)

| Tool | Use | URL |
| --- | --- | --- |
| **ReqRes** | Ready-made REST API | [https://reqres.in](https://reqres.in) |
| **MockAPI.io** | Create custom endpoints | [https://mockapi.io](https://mockapi.io) |
| **Postman Mock Server** | Create & test local API mocks | https://postman.com |

If you use **MockAPI.io**, create 4 endpoints:

```java
GET   /products
POST  /cart
POST  /order
POST  /payment
```

Each will return simple JSON data.

---

## 🧩 4️⃣ BaseTest.java

Centralized setup (Base URI and reusable methods).

```java
package com.ecommerce.tests;

import io.restassured.RestAssured;
import io.restassured.response.Response;
import org.testng.annotations.BeforeClass;

public class BaseTest {

    @BeforeClass
    public void setup() {
        RestAssured.baseURI = "https://mockapi.io/api/v1"; // Replace with your mock API base URL
    }

    public Response getRequest(String endpoint) {
        return RestAssured
                .given()
                .when()
                .get(endpoint)
                .then()
                .extract()
                .response();
    }

    public Response postRequest(String endpoint, Object body) {
        return RestAssured
                .given()
                .header("Content-Type", "application/json")
                .body(body)
                .when()
                .post(endpoint)
                .then()
                .extract()
                .response();
    }
}
```

---

## 🛍️ 5️⃣ ProductTest.java — Fetch and Validate Products

```java
package com.ecommerce.tests;

import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import org.testng.annotations.Test;

import java.util.List;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class ProductTest extends BaseTest {

    @Test
    public void verifyProductList() {
        Response response = getRequest("/products");
        response.then().statusCode(200);

        JsonPath json = response.jsonPath();

        // Validate
        List<String> productNames = json.getList("store.products.name");
        System.out.println("Products: " + productNames);

        assertThat(productNames, hasItems("Laptop", "Smartphone", "Shoes"));
        assertThat(json.getInt("store.products.size()"), greaterThan(0));

        // Extract one product for next step
        int selectedProductId = json.getInt("store.products[1].id");
        System.setProperty("productId", String.valueOf(selectedProductId));
    }
}
```

---

## 🧺 6️⃣ CartTest.java — Add Product to Cart

```java
package com.ecommerce.tests;

import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import org.json.JSONObject;
import org.testng.annotations.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class CartTest extends BaseTest {

    @Test(dependsOnMethods = "com.ecommerce.tests.ProductTest.verifyProductList")
    public void addToCart() {
        int productId = Integer.parseInt(System.getProperty("productId"));

        JSONObject request = new JSONObject();
        request.put("productId", productId);
        request.put("quantity", 2);

        Response response = postRequest("/cart", request.toString());
        response.then().statusCode(201);

        JsonPath json = response.jsonPath();

        assertThat(json.getString("message"), equalTo("Item added to cart"));
        assertThat(json.getInt("cart.quantity"), equalTo(2));

        String cartId = json.getString("cart.id");
        System.setProperty("cartId", cartId);
    }
}
```

---

## 📦 7️⃣ OrderTest.java — Place an Order

```java
package com.ecommerce.tests;

import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import org.json.JSONObject;
import org.testng.annotations.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class OrderTest extends BaseTest {

    @Test(dependsOnMethods = "com.ecommerce.tests.CartTest.addToCart")
    public void placeOrder() {
        String cartId = System.getProperty("cartId");

        JSONObject request = new JSONObject();
        request.put("cartId", cartId);
        request.put("address", "Bhubaneswar, Odisha");

        Response response = postRequest("/order", request.toString());
        response.then().statusCode(201);

        JsonPath json = response.jsonPath();

        assertThat(json.getString("status"), equalTo("Order Placed"));
        assertThat(json.getString("orderId"), notNullValue());

        System.setProperty("orderId", json.getString("orderId"));
    }
}
```

---

## 💳 8️⃣ PaymentTest.java — Verify Payment Success

```java
package com.ecommerce.tests;

import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import org.json.JSONObject;
import org.testng.annotations.Test;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class PaymentTest extends BaseTest {

    @Test(dependsOnMethods = "com.ecommerce.tests.OrderTest.placeOrder")
    public void verifyPaymentSuccess() {
        String orderId = System.getProperty("orderId");

        JSONObject request = new JSONObject();
        request.put("orderId", orderId);
        request.put("method", "UPI");
        request.put("amount", 35000);

        Response response = postRequest("/payment", request.toString());
        response.then().statusCode(200);

        JsonPath json = response.jsonPath();

        assertThat(json.getString("status"), equalTo("Success"));
        assertThat(json.getInt("amount"), greaterThan(0));
        assertThat(json.getString("transaction.currency"), equalTo("INR"));

        System.out.println("✅ Payment successful for order: " + orderId);
    }
}
```

---

## ⚡ 9️⃣ testng.xml

Run all tests in proper sequence:

```java
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="E-Commerce API Suite">
    <test name="API Tests">
        <classes>
            <class name="com.ecommerce.tests.ProductTest"/>
            <class name="com.ecommerce.tests.CartTest"/>
            <class name="com.ecommerce.tests.OrderTest"/>
            <class name="com.ecommerce.tests.PaymentTest"/>
        </classes>
    </test>
</suite>
```

---

## 🧠 🔟 What You Learn Here

| Concept | Description |
| --- | --- |
| **Chaining Tests** | Pass data (productId, cartId, orderId) between tests dynamically |
| **JSONPath Extraction** | Parse and assert JSON response |
| **Hamcrest Matchers** | Perform readable validations |
| **Reusable Methods** | Centralize setup & requests |
| **End-to-End Flow** | Realistic automation pattern |

---

## 🧰 1️⃣1️⃣ How to Practice

1. Go to [**https://mockapi.io**](https://mockapi.io)
    
2. Create a new project
    
3. Add endpoints `/products`, `/cart`, `/order`, `/payment` with JSON similar to examples above
    
4. Copy the base URL into your `BaseTest.java`
    
5. Run from TestNG or `mvn test`
    

You’ll see each test depend on the previous one — forming a **complete e-commerce flow**.

---

## 🧾 1️⃣2️⃣ Output Example (Console)

```java
Products: [Laptop, Smartphone, Shoes]
Affordable Products: [Smartphone, Shoes]
Item added to cart
✅ Order placed successfully
✅ Payment successful for order: O12345
```
