NỘI DUNG BÀI HỌC

✳️ JSON Schema là gì?
✳️ Validate JSON Schema là gì?
✳️ Khi nào cần Validate JSON Schema?
✳️ Cách thực hiện Validate JSON Schema với REST Assured

✅ JSON Schema là gì?

Theo trang tác giả json-schema.org nói thì "JSON Schema is a declarative language that you can use to annotate and validate the structure, constraints, and data types of your JSON documents. It provides a way to standardize and define expectations for your JSON data."
https://json-schema.org/overview/what-is-jsonschema

Có thể hiểu nhanh JSON-Schema là lược đồ để xác định tiêu chuẩn, kiểu dữ liệu và cấu trúc dữ liệu JSON của bạn.

Các tiêu chuẩn được xác định và thay đổi theo năm tháng, các bạn có thể xem link sau:
https://json-schema.org/specification-links#table-of-all-versions-of-everything

✅ Validate JSON Schema là gì?

Validate JSON Schema là áp dụng tiêu chuẩn JSON Schema để kiểm tra cấu trúc dữ liệu JSON của Response trả về khi kiểm thử API. Chúng ta chỉ kiểm tra cái khung cấu trúc của response thôi, chứ không kiểm tra data của response.

✅ Khi nào cần Validate JSON Schema?

- Khi cần kiểm tra cấu trúc Response trả về có đúng kiểu dữ liệu hay không.
- Khi mình muốn verify nhanh các thuộc tính trong JSON mà không muốn mất quá nhiều thời gian để kiểm tra từng thuộc tính dữ liệu trong response.
- Khi có nhiều bộ data trả về mà mình không muốn phải test hết từng bộ data trong response đó, chỉ muốn kiểm tra cấu trúc của response trả về đúng cấu trúc hay không thôi là được rồi. Ví dụ: khi thực hiện GET USER thì nó trả ra mấy trăm bộ data tương ứng nhiều User, giờ không lẻ chúng ta verify hết đống đó tới chừng nào xong, thế thì giờ chúng ta chỉ cần kiểm tra cấu trúc của response thôi, không cần kiểm tra hết từng bộ data trong response đó.

✅ Cách thực hiện Validate JSON Schema với REST Assured

Giả sử chúng ta có một data JSON từ Response trả về của api GET BOOK BY ID
https://api.anhtester.com/swagger/index.html#/Book%20Management/getBookWithId

{
    "message": "Success",
    "response": {
        "id": 10,
        "name": "Tester v1.1",
        "category_id": 1,
        "price": 1200,
        "release_date": "2023/12/29",
        "status": 1,
        "image": [
            {
                "id": 1,
                "path": "public/images/1avh0VncWchVJd1SrYpcgLTU4NccDVW6Ck8ixmW3.png"
            }
        ]
    }
}


Chúng ta cần xác định được đâu là cấu trúc đúng của api GET BOOK BY ID này, sau đó lấy làm chuẩn, tiếp theo là check một vài bộ data khác xem nó có đúng theo cấu trúc đã xác định làm chuẩn hay không.

🔆 Chuyển JSON thành JSON Schema

Các bạn vào link tài liệu gốc để hiểu hơn về các tiêu chuẩn và cách convert mẫu từ json sang json schema
https://json-schema.org/learn/getting-started-step-by-step

Nhưng với Anh Tester thì có cách này hay hơn nhiều nè 😄

Bạn vào link sau https://transform.tools/json-to-json-schema

Sau đó dán cái Response vào là nó tự generate sang Schema luôn 😋



Tương ứng với JSON Response trên thì chúng ta sẽ có JSON Schema sau:

{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Generated schema for Root",
  "type": "object",
  "properties": {
    "message": {
      "type": "string"
    },
    "response": {
      "type": "object",
      "properties": {
        "id": {
          "type": "number"
        },
        "name": {
          "type": "string"
        },
        "category_id": {
          "type": "number"
        },
        "price": {
          "type": "number"
        },
        "release_date": {
          "type": "string"
        },
        "status": {
          "type": "number"
        },
        "image": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "id": {
                "type": "number"
              },
              "path": {
                "type": "string"
              }
            },
            "required": [
              "id",
              "path"
            ]
          }
        }
      },
      "required": [
        "id",
        "name",
        "category_id",
        "price",
        "release_date",
        "status",
        "image"
      ]
    }
  },
  "required": [
    "message",
    "response"
  ]
}


🔆 Những điểm cần chú ý trong JSON Schema

- Tiêu chuẩn: thường dùng draft-06 hoặc draft-07

"$schema": "http://json-schema.org/draft-07/schema#"


- Loại kiểu dữ liệu (thường gặp):

"type": "object",
"type": "array",
"type": "string",
"type": "number"


- Các thuộc tính required:
là những thuộc tính bắt buộc có trong bộ data.

Ví dụ:

"required": [
  "id",
  "name",
  "category_id",
  "price",
  "release_date",
  "status",
  "image"
]


Tương tự ví dụ convert JSON to JSON Schema cho api GET ALL BOOK



{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "title": "Generated schema for Root",
  "type": "object",
  "properties": {
    "message": {
      "type": "string"
    },
    "response": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "id": {
            "type": "number"
          },
          "name": {
            "type": "string"
          },
          "category_id": {
            "type": "number"
          },
          "price": {
            "type": "number"
          },
          "release_date": {
            "type": "string"
          },
          "status": {
            "type": "number"
          },
          "image": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "number"
                },
                "path": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "path"
              ]
            }
          }
        },
        "required": [
          "id",
          "name",
          "category_id",
          "price",
          "release_date",
          "status",
          "image"
        ]
      }
    }
  },
  "required": [
    "message",
    "response"
  ]
}


Các bạn chú ý chổ An khoanh vùng đỏ, nó khác nhau kiểu dữ liệu chổ arrayobject. Vì khi get all book thì có nhiều bộ data book trả về, nên nó không còn là dạng object như get book by id nữa.


🔆 Validate JSON Schema trong Rest Assured

Sau khi các bạn có được JSON Schema đã generate thì chúng ta lưu nó vào file json đặt trong source auto test của mình.

Chú ý: đặt file json schema ở thư mục "src/test/resources", phải như vậy thì xíu nữa nó mới tự tìm thấy được trong code.



Tiếp theo chúng ta cần phải cài đặt thư viện thêm để hỗ trợ Validate JSON Schema, cũng thuộc của REST Assured luôn.

<!-- https://mvnrepository.com/artifact/io.rest-assured/json-schema-validator -->
<dependency>
	<groupId>io.rest-assured</groupId>
	<artifactId>json-schema-validator</artifactId>
	<version>5.4.0</version>
</dependency>


Tiếp theo là viết test cases auto để validate json schema.

Test case cho chức năng Get Book By Id trước nhé:

import com.anhtester.common.BaseTest;
import com.anhtester.globals.ConfigsGlobal;
import com.anhtester.globals.TokenGlobal;
import com.anhtester.model.RegisterUserPOJO_Lombok;
import com.anhtester.model.data.UserPOJO_Lombok_Builder;
import com.google.gson.Gson;
import io.restassured.module.jsv.JsonSchemaValidator;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
import org.testng.annotations.Test;

import java.io.InputStream;

import static io.restassured.RestAssured.given;

public class JsonSchemaValidationTest extends BaseTest {
    @Test
    public void validateJsonSchema_GetBookById() {
        InputStream GetBookIdSchema = getClass().getClassLoader()
            .getResourceAsStream("GetBookIdSchema.json");

        // Perform the API request and get the response
        Response response = given()
            .baseUri(ConfigsGlobal.URI)
            .when()
            .get("/book/10")
            .then()
            .statusCode(200)
            .and()
            .extract()
            .response();

        response.prettyPrint();

        // Validate the response against the JSON schema
        response.then().assertThat().body(JsonSchemaValidator.matchesJsonSchema(GetBookIdSchema));
    }
}


Đoạn code:

InputStream GetBookIdSchema = getClass().getClassLoader()
            .getResourceAsStream("GetBookIdSchema.json");

Là dùng để đọc cái file json schema mà mình đã lưu vào thư mục "src/test/resources", nó tự động hiểu đường dẫn và tự tìm đến tên file json chỉ định.

Sau đó dùng hàm assertThat để kiểm tra body trả về so với nội dung cấu trúc Schema từ JSON Schema file thông qua hàm hỗ trợ từ thư viện trên.

JsonSchemaValidator.matchesJsonSchema(GetBookIdSchema)

Phải cài thư viện "json-schema-validator" ở trên trước thì mới thấy được hàm hỗ trợ này.

Kết quả:

{
    "message": "Success",
    "response": {
        "id": 10,
        "name": "Tester v1.1",
        "category_id": 1,
        "price": 1200,
        "release_date": "2023/12/29",
        "status": 1,
        "image": [
            {
                "id": 1,
                "path": "public/images/1avh0VncWchVJd1SrYpcgLTU4NccDVW6Ck8ixmW3.png"
            }
        ]
    }
}

===============================================
Default Suite
Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
===============================================


Tương tự chúng ta viết thêm test cases cho các tính năng khác: GetAllBook, CreateUser

Nhớ lưu ý là lưu từng JSON Schema vào json file rồi lưu file vào thư mục resources cho đúng trước nhé.

import com.anhtester.common.BaseTest;
import com.anhtester.globals.ConfigsGlobal;
import com.anhtester.globals.TokenGlobal;
import com.anhtester.model.RegisterUserPOJO_Lombok;
import com.anhtester.model.data.UserPOJO_Lombok_Builder;
import com.google.gson.Gson;
import io.restassured.module.jsv.JsonSchemaValidator;
import io.restassured.response.Response;
import io.restassured.specification.RequestSpecification;
import org.testng.annotations.Test;

import java.io.InputStream;

import static io.restassured.RestAssured.given;

public class JsonSchemaValidationTest extends BaseTest {
    @Test
    public void validateJsonSchema_GetAllBook() {
        InputStream GetBookAllSchema = getClass().getClassLoader()
                .getResourceAsStream("GetBookAllSchema.json");

        // Perform the API request and get the response
        Response response = given()
                .baseUri(ConfigsGlobal.URI)
                .when()
                .get("/books")
                .then()
                .statusCode(200)
                .and()
                .extract()
                .response();

        response.prettyPrint();

        // Validate the response against the JSON schema
        response.then().assertThat().body(JsonSchemaValidator.matchesJsonSchema(GetBookAllSchema));
    }

    @Test
    public void validateJsonSchema_CreateUser() {
        InputStream CreateUserSchema = getClass().getClassLoader()
                .getResourceAsStream("CreateUserSchema.json");

        RegisterUserPOJO_Lombok registerUserPOJO_lombok = UserPOJO_Lombok_Builder.getUserDataCreate();

        Gson gson = new Gson();

        RequestSpecification request = given();
        request.baseUri(ConfigsGlobal.URI)
                .accept("application/json")
                .contentType("application/json")
                .header("Authorization", "Bearer " + TokenGlobal.TOKEN)
                .body(gson.toJson(registerUserPOJO_lombok));

        Response response = request.when().post("/user");
        response.prettyPrint();

        // Validate the response against the JSON schema
        response.then().assertThat().body(JsonSchemaValidator.matchesJsonSchema(CreateUserSchema));
    }
}


Cái hàm "getUserDataCreate" là từ class Data Builder hôm trước học qua rồi đó.

package com.anhtester.model.data;

import com.anhtester.helpers.SystemHelper;
import com.anhtester.model.RegisterUserPOJO_Lombok;
import net.datafaker.Faker;

import java.util.Locale;

public class UserPOJO_Lombok_Builder {

    public static RegisterUserPOJO_Lombok getUserDataUpdate() {

        Faker faker = new Faker(new Locale("vi"));
        String phoneNumber = faker.phoneNumber().cellPhone();
        phoneNumber = phoneNumber.replace(" ", "");

        return RegisterUserPOJO_Lombok.builder()
                .firstName(faker.name().firstName())
                .lastName(faker.name().lastName())
                .phone(phoneNumber)
                .email(faker.internet().emailAddress())
                .userStatus(1)
                .build();
    }

    public static RegisterUserPOJO_Lombok getUserDataCreate() {

        Faker faker = new Faker(new Locale("vi"));

        String phoneNumber = "0" + faker.number().digits(9);
        System.out.println(phoneNumber);

        String firstname = faker.name().firstName();
        String lastname = faker.name().lastName();
        String username = SystemHelper.removeAccent(firstname + "." + lastname);

        return RegisterUserPOJO_Lombok.builder()
                .username(username)
                .password("Demo@123")
                .firstName(firstname)
                .lastName(lastname)
                .phone(phoneNumber)
                .email(username + "@email.com")
                .userStatus(1)
                .build();
    }

}

 

 

🔆 Format JSON cho đẹp mắt

Trong quá trình làm việc nếu cần format JSON data cho đẹp thì các bạn có thể mang lên tools này:

https://codebeautify.org/jsonviewer

Dán JSON vào xong nhấn nút Beautify á, chọn option 4 Tab Space nhìn thoáng mắt hơn.

Teacher

Teacher

Anh Tester

Software Quality Engineer

Đường dẫu khó chân vẫn cần bước đi
Đời dẫu khổ tâm vẫn cần nghĩ thấu

Cộng đồng Automation Testing Việt Nam:

🌱 Telegram Automation Testing:   Cộng đồng Automation Testing
🌱 
Facebook Group Automation: Cộng đồng Automation Testing Việt Nam
🌱 
Facebook Fanpage: Cộng đồng Automation Testing Việt Nam - Selenium
🌱 Telegram
Manual Testing:   Cộng đồng Manual Testing
🌱 
Facebook Group Manual: Cộng đồng Manual Testing Việt Nam

Chia sẻ khóa học lên trang

Bạn có thể đăng khóa học của chính bạn lên trang Anh Tester để kiếm tiền

Danh sách bài học