NỘI DUNG BÀI HỌC

✅ Cài đặt và sử dụng Allure report

✅ Cài đặt Allure Report trong Maven project


Trước tiên, mình sẽ thêm biến môi trường Allure-2.27.0 vào máy tính của mình cũng giống như cài đặt biến môi trường cho Java JDK và Maven.

Mình đặt tên biến môi trường là ALLURE_HOME

Tải gói Allure-2.27.0 cho Window tại đây (cứ tải bản mới nhất nhé)

Vì An chỉ dạy trên môi trường máy window nên có gì các bạn kiếm bản cho MacOS hoặc Linux như hình hướng dẫn bên dưới:

Link download theo phiên bản: https://github.com/allure-framework/allure2/releases


Tiếp theo thì các bạn giải nén ra để nó vào ổ C (ổ chứa hệ điều hành) để tạo biến môi trường trong máy ổn định.



Tạo biến môi trường giống với setup biến môi trường Java JDK á



Edit biến path



Chạy lệnh trong CMD để kiểm tra

allure --version



Tiếp theo là cấu hình Allure Report nào !!

Bước 1: Thêm thư viện Allure Reports vào pom.xml trong Maven Project

 <!-- https://mvnrepository.com/artifact/io.qameta.allure/allure-testng -->
<dependency>
	<groupId>io.qameta.allure</groupId>
	<artifactId>allure-testng</artifactId>
	<version>2.27.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/io.qameta.allure/allure-attachments -->
<dependency>
	<groupId>io.qameta.allure</groupId>
	<artifactId>allure-attachments</artifactId>
	<version>2.27.0</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
<dependency>
	<groupId>org.aspectj</groupId>
	<artifactId>aspectjweaver</artifactId>
	<version>1.9.22</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
	<groupId>org.projectlombok</groupId>
	<artifactId>lombok</artifactId>
	<version>1.18.32</version>
	<scope>provided</scope>
</dependency>

(Cập nhật ngày 08/04/2024)

Hoặc vào link này để download bản tùy ý:

https://mvnrepository.com/artifact/io.qameta.allure/allure-testng


Tiếp theo là thêm đoạn build dùng để thực thi và config allure trong maven. Các bạn chú ý là chúng ta sẽ để đoạn build ngoài thẻ dependencies nhé.

<build>
	<pluginManagement>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-surefire-plugin</artifactId>
				<version>3.2.5</version>
				<configuration>
					<suiteXmlFiles>
						<!-- Call Suite name -->
						<suiteXmlFile>suites/SuiteLoginTest.xml</suiteXmlFile>
					</suiteXmlFiles>
					<argLine>
                            -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/1.9.22/aspectjweaver-1.9.22.jar"
                        </argLine>
					<testFailureIgnore>true</testFailureIgnore>
					<systemPropertyVariables>
						<!--Đường dẫn xuất ra report-->
						<allure.results.directory>target/allure-results</allure.results.directory>
					</systemPropertyVariables>
				</configuration>
			</plugin>
		</plugins>
	</pluginManagement>
</build>


- Chỗ <suiteXmlFile>suites/SuiteLoginTest.xml</suiteXmlFile>  chỉ đường dẫn đến file XML khi chạy trực tiếp từ pom.xml

- Chỗ <allure.results.directory>target/allure-results</allure.results.directory>  đoạn này chỉ đường dẫn xuất data của report. Nằm trong folder target/allure-results. Nếu muốn mang ra ngoài thì sửa lại là allure-results thôi là xong.


Đây là tất cả các thư viện An đã add vào pom.xml của cả project đây:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.anhtester</groupId>
    <artifactId>RestAssuredTestNG2023</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

    <dependencies>

        <!-- https://mvnrepository.com/artifact/org.testng/testng -->
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <version>7.10.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.rest-assured/rest-assured -->
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <version>5.4.0</version>
        </dependency>
        <!-- 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>

        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-api -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>2.0.12</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-simple -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-simple</artifactId>
            <version>2.0.12</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.10.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.32</version>
            <scope>provided</scope>
        </dependency>

        <!-- https://mvnrepository.com/artifact/net.datafaker/datafaker -->
        <dependency>
            <groupId>net.datafaker</groupId>
            <artifactId>datafaker</artifactId>
            <version>2.1.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.23.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api -->
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.23.1</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.qameta.allure/allure-testng -->
        <dependency>
            <groupId>io.qameta.allure</groupId>
            <artifactId>allure-testng</artifactId>
            <version>2.27.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/io.qameta.allure/allure-attachments -->
        <dependency>
            <groupId>io.qameta.allure</groupId>
            <artifactId>allure-attachments</artifactId>
            <version>2.27.0</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.aspectj/aspectjweaver -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.9.22</version>
        </dependency>

    </dependencies>

    <build>
        <pluginManagement>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>3.2.5</version>
                    <configuration>
                        <suiteXmlFiles>
                            <!-- Call Suite name -->
                            <suiteXmlFile>suites/SuiteRunTest.xml</suiteXmlFile>
                        </suiteXmlFiles>
                        <argLine>
                            -javaagent:"${settings.localRepository}/org/aspectj/aspectjweaver/1.9.22/aspectjweaver-1.9.22.jar"
                        </argLine>
                        <testFailureIgnore>true</testFailureIgnore>
                        <systemPropertyVariables>
                            <!-- Đường dẫn xuất ra data của report -->
                            <allure.results.directory>target/allure-results</allure.results.directory>
                        </systemPropertyVariables>
                    </configuration>
                </plugin>
            </plugins>
        </pluginManagement>
    </build>

</project>

 

Bước 2: Tạo class AllureManager để config allure reports

Tạo class AllureManager để vào package reports thuộc package main. Hoặc muốn để đâu cũng được. Gọn ràng là được.

package com.anhtester.reports;

import io.qameta.allure.Attachment;

public class AllureManager {
    //Add text to report
    @Attachment(value = "{0}", type = "text/plain")
    public static String saveTextLog(String message) {
        return message;
    }
}

 

Các ghi chú trong Allure Report:

@Epic
@Features
@Stories/@Story
@Severity(SeverityLevel.BLOCKER)
@Description("In this cool test we will check cool thing")
@Step
@Attachment
@Link

 

Cái ghi chú quan trọng của mình là @Step. Nó đại diện cho từng @Test và chúng ta sẽ config nó sau. Còn cái Ghi chú còn lại thì bổ trợ làm rõ ràng hơn cho Suite test case.

Các bạn nghiên cứu thêm tại đây: https://allurereport.org/docs/testng/

Mô tả chi tiết hơn tại đây: https://www.seleniumeasy.com/selenium-tutorials/allure-report-example-with-annotations

Demo: https://demo.qameta.io/allure/#behaviors

 

Bước 3: Thêm Allure Reports vào TestListener class

Chúng ta sẽ thêm hàm add text logs từ AllureManager vào phương thức onTestFailue trong TestListener. Hoặc thêm vào bất kì phương thức nào nếu cần.

@Override
public void onTestSuccess(ITestResult result) {
    //Cộng 1 đơn vị vào 1 biến toàn cục để nắm bắt số lượng tcs pass
    LogUtils.info("Test case " + result.getName() + " is passed.");
    ConfigsGlobal.PASSED_TOTAL++;

    //Add text detail to Allure Report
    AllureManager.saveTextLog("Test case " + result.getName() + " is passed.");
}

@Override
public void onTestFailure(ITestResult result) {
    //Cộng 1 đơn vị vào 1 biến toàn cục để nắm bắt số lượng tcs fail
    LogUtils.error("Test case " + result.getName() + " is failed.");
    LogUtils.error(result.getThrowable());
    ConfigsGlobal.FAILED_TOTAL++;

    //Add text detail to Allure Report
    AllureManager.saveTextLog("Test case " + result.getName() + " is failed.");
}


Bước 4: Mở Allure Reports sau khi chạy test

Sau khi chạy test case các bạn thấy là nó sẽ tự sinh ra cho mình folder "allure-results" nằm trong target/allure-results nó chứa các file json. Đó cũng là data của report.

[Selenium Java] Bài 33: Cài đặt và sử dụng Extent Report Allure Report | Anh Tester

Từ giao diện IntelliJ IDEA, sau khi các bạn chạy test case trên xong thì mở "Terminal" lên để chạy lệnh sau.



Hoặc chọn từ menu: View > Tool Windows > Terminal



Hoặc dùng phím tắt Alt + F12


Tiếp theo là chạy lệnh trong Terminalallure serve target/allure-results


Sau khi chạy nó sẽ sinh ra cho mình folder tạm và host tạm để display Report.

Đợi tầm 3 giây nó sinh ra cho mình 1 đường link tự động mở trên Browser luôn. Không thì các bạn click link trong vùng Terminal như hình trên cũng được.



Giao diện từng Step



Nó chưa đính kèm được các Text Logs mà khi nảy mình thêm vào trong phần TestListener đúng không?

Các bạn chú ý:
 phải dùng bản TestNG 7.4.0 thì Allure report nó mới hiểu Attachments cái text hoặc hình vào trong report được.




Và nó chưa đính kèm được các steps detail (request, response, body,...) vào trong reports đúng không, yeah mình sẽ hướng dẫn các bạn cụ thể phần bên dưới tiếp theo.


Khi không cần xem report nữa thì mình tắt Terminal đi với phím tắt Ctrl +C sau đó chọn Y (đồng ý tắt) và Enter

 

🔆 Chạy Test Cases bằng Maven pom.xml

Để mở Allure Report chúng ta có cách khác là chạy test cases bằng Maven trong pom.xml

Giờ chúng ta mở tab Maven trong IntelliJ IDEA lên và gõ lệnh: mvn clean test



Thì nó sẽ thực thi cái file SUITE XML mà mình chỉ định lúc thêm đoạn <build> để chỉ định vị trí xuất data allure report.



✳️ Tạo các steps detail trong Allure Report

Để thêm các bước chi tiết của test cases vào trong Allure Report thì chúng ta cần thêm các @Step vào trong các class keyword của mình. Cụ thể là ApiKeyword, SpecBuilder,...các class helper và các vị trí khác mà mình muốn thêm chi tiết.




🔆 Add step detail vào từng bước của test cases

Ví dụ hàm get trong ApiKeyword

@Step("GET: {0}")
public static Response get(String path) {
    LogUtils.info("GET: " + path);
    Response response =
        given(SpecBuilder.getRequestSpecBuilder()).
    when().
    get(path).
    then().
    spec(SpecBuilder.getResponseSpecBuilder()).
    extract().
    response();

    LogUtils.info("RESPONSE: \n" + response.prettyPrint());
    AllureManager.saveTextLog("RESPONSE: \n" + response.prettyPrint());
    return response;
}


Mình thêm cái @Step là để gắn step detail vào report. Các bạn ghi mô tả tuỳ ý.

{0}, {1},...là đại diện cho giá trị của các tham số của phương thức. Theo thứ tự trừ trái sang phải. Và bắt đầu từ 0 (tham số thứ nhất)

Và các bạn có thể thêm chi tiết hơn thông qua hàm ghi text logs vào Allure report bằng cách gọi hàm saveTextLog bên trong hàm tuỳ ý

Ví dụ hàm post có 2 tham số

@Step("POST: {0} with body {1}")
public static Response post(String path, Object payLoad) {
    LogUtils.info("POST: " + path);
    LogUtils.info("Body: " + payLoad);
    Response response =
        given(SpecBuilder.getRequestSpecBuilder()).
    body(payLoad).
    when().
    post(path).
    then().
    spec(SpecBuilder.getResponseSpecBuilder()).
    extract().response();

    LogUtils.info("RESPONSE: \n" + response.prettyPrint());
    AllureManager.saveTextLog("RESPONSE: \n" + response.prettyPrint());
    return response;
}

 

 

🔆 Một số hàm An khai báo sẵn các steps details


ApiKeyword

package com.anhtester.keywords;

import com.anhtester.reports.AllureManager;
import com.anhtester.utils.LogUtils;
import io.qameta.allure.Step;
import io.restassured.path.json.JsonPath;
import io.restassured.response.Response;
import org.testng.Assert;

import java.io.File;
import java.util.Map;

import static io.restassured.RestAssured.given;

public class ApiKeyword {

    @Step("GET: {0}")
    public static Response get(String path) {
        LogUtils.info("GET: " + path);
        Response response =
                given(SpecBuilder.getRequestSpecBuilder()).
                        when().
                        get(path).
                        then().
                        spec(SpecBuilder.getResponseSpecBuilder()).
                        extract().
                        response();

        LogUtils.info("RESPONSE: \n" + response.prettyPrint());
        AllureManager.saveTextLog("RESPONSE: \n" + response.prettyPrint());
        return response;
    }

    @Step("GET: {0} with headers {1}")
    public static Response get(String path, Map<String, String> headers) {
        LogUtils.info("GET: " + path);
        LogUtils.info("HEADERS: " + headers);
        Response response =
                given(SpecBuilder.getRequestSpecBuilder().headers(headers)).
                        when().
                        get(path).
                        then().
                        spec(SpecBuilder.getResponseSpecBuilder()).
                        extract().
                        response();

        LogUtils.info("RESPONSE: \n" + response.prettyPrint());
        AllureManager.saveTextLog("RESPONSE: \n" + response.prettyPrint());
        return response;
    }

    @Step("GET: {0} with BEARER TOKEN {1}")
    public static Response get(String path, String authBearerToken) {
        LogUtils.info("GET: " + path);
        LogUtils.info("BEARER TOKEN: " + authBearerToken);
        Response response =
                given(SpecBuilder.getRequestSpecBuilder().header("Authorization", "Bearer " + authBearerToken)).
                        when().
                        get(path).
                        then().
                        spec(SpecBuilder.getResponseSpecBuilder()).
                        extract().
                        response();

        LogUtils.info("RESPONSE: \n" + response.prettyPrint());
        AllureManager.saveTextLog("RESPONSE: \n" + response.prettyPrint());
        return response;
    }

    @Step("GET (not auth): {0}")
    public static Response getNotAuth(String path) {
        LogUtils.info("GET not authorization: " + path);
        Response response =
                given(SpecBuilder.getRequestNotAuthSpecBuilder()).
                        when().
                        get(path).
                        then().
                        spec(SpecBuilder.getResponseSpecBuilder()).
                        extract().
                        response();

        LogUtils.info("RESPONSE: \n" + response.prettyPrint());
        AllureManager.saveTextLog("RESPONSE: \n" + response.prettyPrint());
        return response;
    }

    @Step("POST: {0} with body {1}")
    public static Response post(String path, Object payLoad) {
        LogUtils.info("POST: " + path);
        LogUtils.info("Body: " + payLoad);
        Response response =
                given(SpecBuilder.getRequestSpecBuilder()).
                        body(payLoad).
                        when().
                        post(path).
                        then().
                        spec(SpecBuilder.getResponseSpecBuilder()).
                        extract().response();

        LogUtils.info("RESPONSE: \n" + response.prettyPrint());
        AllureManager.saveTextLog("RESPONSE: \n" + response.prettyPrint());
        return response;
    }

    @Step("POST (not auth): {0} with body {1}")
    public static Response postNotAuth(String path, Object payLoad) {
        LogUtils.info("POST not authorization: " + path);
        LogUtils.info("Body: " + payLoad);
        Response response =
                given(SpecBuilder.getRequestNotAuthSpecBuilder()).
                        body(payLoad).
                        when().
                        post(path).
                        then().
                        spec(SpecBuilder.getResponseSpecBuilder()).
                        extract().response();

        LogUtils.info("RESPONSE: \n" + response.prettyPrint());
        AllureManager.saveTextLog("RESPONSE: \n" + response.prettyPrint());
        return response;
    }

    @Step("POST: {0} with body by File {1}")
    public static Response post(String path, File fileBody) {
        LogUtils.info("POST: " + path);
        LogUtils.info("Body: " + fileBody.getPath());
        Response response =
                given(SpecBuilder.getRequestSpecBuilder()).
                        body(fileBody).
                        when().
                        post(path).
                        then().
                        spec(SpecBuilder.getResponseSpecBuilder()).
                        extract().response();

        LogUtils.info("RESPONSE: \n" + response.prettyPrint());
        AllureManager.saveTextLog("RESPONSE: \n" + response.prettyPrint());
        return response;
    }

    @Step("PUT: {0} with body {1}")
    public static Response put(String path, Object payLoad) {
        LogUtils.info("PUT: " + path);
        LogUtils.info("Body: " + payLoad);
        Response response =
                given(SpecBuilder.getRequestSpecBuilder()).
                        body(payLoad).
                        when().
                        put(path).
                        then().
                        extract().response();

        LogUtils.info("RESPONSE: \n" + response.prettyPrint());
        AllureManager.saveTextLog("RESPONSE: \n" + response.prettyPrint());
        return response;
    }

    @Step("DELETE: {0} with body {1}")
    public static Response delete(String path, Object payLoad) {
        LogUtils.info("DELETE: " + path);
        LogUtils.info("Body: " + payLoad);
        Response response =
                given(SpecBuilder.getRequestSpecBuilder()).
                        body(payLoad).
                        when().
                        delete(path).
                        then().
                        extract().response();

        LogUtils.info("RESPONSE: \n" + response.prettyPrint());
        AllureManager.saveTextLog("RESPONSE: \n" + response.prettyPrint());
        return response;
    }

    @Step("Get Response value by key: {1}")
    public static String getResponseKeyValue(Response response, String responseKey) {
        JsonPath jsonPath = response.jsonPath();
        String key_value = jsonPath.get(responseKey).toString();
        LogUtils.info("Value by key (" + responseKey + "): " + key_value);
        AllureManager.saveTextLog("Value by key (" + responseKey + "): " + key_value);
        return key_value;
    }

    @Step("Get Response value by key: {1}")
    public static String getResponseKeyValue(String responseBody, String responseKey) {
        JsonPath jsonPath = new JsonPath(responseBody);
        String key_value = jsonPath.get(responseKey).toString();
        LogUtils.info("Value by key (" + responseKey + "): " + key_value);
        AllureManager.saveTextLog("Value by key (" + responseKey + "): " + key_value);
        return key_value;
    }

    @Step("Get Status Code")
    public static int getStatusCode(Response response) {
        int status_code = response.getStatusCode();
        LogUtils.info("Get Status Code: " + status_code);
        AllureManager.saveTextLog("The Status Code: " + status_code);
        return status_code;
    }

    @Step("Get Status Line")
    public static String getStatusLine(Response response) {
        String status_line = response.getStatusLine();
        LogUtils.info("Get Status Line: " + status_line);
        AllureManager.saveTextLog("The Status Line: " + status_line);
        return status_line;
    }

    @Step("Get Response Header by key: {1}")
    public static String getResponseHeader(Response response, String header_key) {
        String response_header = response.getHeader(header_key);
        LogUtils.info("Get Response Header by key (" + header_key + "): " + response_header);
        AllureManager.saveTextLog("The Header by key (" + header_key + "): " + response_header);
        return response_header;
    }

    @Step("Get Response Content Type")
    public static String getResponseContentType(Response response) {
        String content_type = response.getContentType();
        LogUtils.info("Get Content Type: " + content_type);
        AllureManager.saveTextLog("The Content Type: " + content_type);
        return content_type;
    }

    @Step("Get Response Cookie by name: {1}")
    public static String getResponseCookieName(Response response, String cookieName) {
        String cookie_value = response.getCookie(cookieName);
        LogUtils.info("Get Cookie by name (" + cookieName + "): " + cookie_value);
        AllureManager.saveTextLog("The Cookie by name (" + cookieName + "): " + cookie_value);
        return cookie_value;
    }

    @Step("Verify Status Code expected: {1}")
    public static void verifyStatusCode(Response response, int expectedStatusCode) {
        LogUtils.info("Verify Status code: " + response.getStatusCode() + " == " + expectedStatusCode);
        AllureManager.saveTextLog("Verify Status code: " + response.getStatusCode() + " == " + expectedStatusCode);
        Assert.assertEquals(response.getStatusCode(), expectedStatusCode, "FAIL. The status code not match.");
    }
}


BookTest_AllureReport.java

package com.anhtester.Bai18_AllureReport;

import com.anhtester.common.BaseTest;
import com.anhtester.globals.EndPointGlobal;
import com.anhtester.keywords.ApiKeyword;
import com.anhtester.utils.LogUtils;
import io.restassured.response.Response;
import org.testng.annotations.Test;

public class BookTest_AllureReport extends BaseTest {

    @Test
    public void testGetBooks() {
        Response response = ApiKeyword.get(EndPointGlobal.EP_BOOKS);
        ApiKeyword.verifyStatusCode(response, 200);
        LogUtils.info(ApiKeyword.getResponseKeyValue(response, "response[0].name"));
    }
}


CategoryTest_AllureReport.java

package com.anhtester.Bai18_AllureReport;

import com.anhtester.common.BaseTest;
import com.anhtester.globals.EndPointGlobal;
import com.anhtester.helpers.JsonHelper;
import com.anhtester.keywords.ApiKeyword;
import com.anhtester.listeners.TestListener;
import com.anhtester.utils.LogUtils;
import io.restassured.response.Response;
import net.datafaker.Faker;
import org.testng.Assert;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;

import java.io.File;
import java.util.Locale;

@Listeners(TestListener.class)
public class CategoryTest_AllureReport extends BaseTest {

    int CATEGORY_ID;
    String CATEGORY_NAME;

    @Test(priority = 1)
    public void testAddNewCategory() {
        String dataFile = "src/test/resources/testdata/CreateCategory.json";

        Faker faker = new Faker(new Locale("vi"));
        CATEGORY_NAME = faker.job().title();
        LogUtils.info("GENERATE CATEGORY NAME: " + CATEGORY_NAME);

        JsonHelper.updateValueJsonFile(dataFile, "name", CATEGORY_NAME);

        Response response = ApiKeyword.post(EndPointGlobal.EP_CATEGORY, new File(dataFile));

        ApiKeyword.verifyStatusCode(response, 200);

        CATEGORY_ID = Integer.parseInt(ApiKeyword.getResponseKeyValue(response, "response.id"));
        CATEGORY_NAME = ApiKeyword.getResponseKeyValue(response, "response.name");

        LogUtils.info("CATEGORY_ID: " + CATEGORY_ID);
        LogUtils.info("CATEGORY_NAME: " + CATEGORY_NAME);

    }

    @Test(priority = 2)
    public void getCategoryById() {
        LogUtils.info("CATEGORY_ID: " + CATEGORY_ID);

        Response response = ApiKeyword.get(EndPointGlobal.EP_CATEGORY + "/" + CATEGORY_ID);

        response.then().statusCode(200);

        Assert.assertEquals(ApiKeyword.getResponseKeyValue(response, "response.name"), CATEGORY_NAME, "The Category Name not match.");

    }
}


SuiteAllureReport.xml

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" >

<suite name="Suite Allure Report" verbose="1">
    <test name="Demo Test Allure Report">
        <classes>
            <class name="com.anhtester.Bai18_AllureReport.BookTest_AllureReport"/>
            <class name="com.anhtester.Bai18_AllureReport.CategoryTest_AllureReport"/>
        </classes>
    </test>
</suite>


Sau khi chạy thì nó sẽ như hình bên trên hoặc sau đây




Chắc nhiều bạn cần mức độ như thế đúng không 😜


✳️ Sử dụng thư viện AllureRestAssured nâng cấp Allure Report

Đầu tiên add thư viện vào pom.xml

<!-- https://mvnrepository.com/artifact/io.qameta.allure/allure-rest-assured -->
<dependency>
	<groupId>io.qameta.allure</groupId>
	<artifactId>allure-rest-assured</artifactId>
	<version>2.25.0</version>
</dependency>


Sau đó add cái filter vào chổ Request, hiện tại đang nằm trong class SpecBuilder đã chỉ ở bài trước.

public static RequestSpecification getRequestSpecBuilder() {
    return new RequestSpecBuilder().
    setBaseUri(ConfigsGlobal.BASE_URI).
    setBasePath(ConfigsGlobal.BASE_PATH).
    addHeader("Authorization", "Bearer " + TokenGlobal.TOKEN).
    setContentType(ContentType.JSON).
    setAccept(ContentType.JSON).
    addFilter(new AllureRestAssured()).
    //addFilter(new RequestLoggingFilter()).
    //addFilter(new ResponseLoggingFilter()).
    log(LogDetail.BODY).
    build();
}


Giờ các bạn thử chạy lại test cases xem kết quả trong Allure Report xem, nó sẽ tự add thêm các thông số từ request với format file json và html khá đẹp mắt, rõ ràng, đầy đủ.

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