diff --git a/src/main/java/com/anhtester/globals/ConfigsGlobal.java b/src/main/java/com/anhtester/globals/ConfigsGlobal.java index 062dd82..9c195c5 100644 --- a/src/main/java/com/anhtester/globals/ConfigsGlobal.java +++ b/src/main/java/com/anhtester/globals/ConfigsGlobal.java @@ -3,7 +3,9 @@ import com.anhtester.helpers.PropertiesHelper; public class ConfigsGlobal { - public static String URI = PropertiesHelper.getValue("BASE_URI"); + public static String AUTHOR = PropertiesHelper.getValue("AUTHOR"); + public static String BASE_URI = PropertiesHelper.getValue("BASE_URI"); + public static String BASE_PATH = PropertiesHelper.getValue("BASE_PATH"); public static String USERNAME = PropertiesHelper.getValue("USERNAME"); public static String PASSWORD = PropertiesHelper.getValue("PASSWORD"); public static int TCS_TOTAL; diff --git a/src/main/java/com/anhtester/globals/EndPointGlobal.java b/src/main/java/com/anhtester/globals/EndPointGlobal.java new file mode 100644 index 0000000..d0e656c --- /dev/null +++ b/src/main/java/com/anhtester/globals/EndPointGlobal.java @@ -0,0 +1,8 @@ +package com.anhtester.globals; + +public class EndPointGlobal { + public static final String EP_LOGIN = "/login"; + public static final String EP_REGISTER = "/register"; + public static final String EP_CATEGORY = "/category"; + public static final String EP_BOOKS = "/books"; +} diff --git a/src/main/java/com/anhtester/globals/TokenGlobal.java b/src/main/java/com/anhtester/globals/TokenGlobal.java index 1e9758c..c3499e4 100644 --- a/src/main/java/com/anhtester/globals/TokenGlobal.java +++ b/src/main/java/com/anhtester/globals/TokenGlobal.java @@ -2,4 +2,8 @@ public class TokenGlobal { public static String TOKEN; + + public static String getBearerToken() { + return TOKEN; + } } diff --git a/src/main/java/com/anhtester/keywords/ApiKeyword.java b/src/main/java/com/anhtester/keywords/ApiKeyword.java new file mode 100644 index 0000000..7f8f142 --- /dev/null +++ b/src/main/java/com/anhtester/keywords/ApiKeyword.java @@ -0,0 +1,203 @@ +package com.anhtester.keywords; + +import com.anhtester.utils.LogUtils; +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 { + + 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()); + return response; + } + + public static Response get(String path, Map 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()); + return response; + } + + 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()); + return response; + } + + 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()); + return response; + } + + 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()); + return response; + } + + 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()); + return response; + } + + public static Response post(String path, String filePathBody) { + LogUtils.info("POST: " + path); + LogUtils.info("Body: " + filePathBody); + Response response = + given(SpecBuilder.getRequestSpecBuilder()). + body(new File(filePathBody)). + when(). + post(path). + then(). + spec(SpecBuilder.getResponseSpecBuilder()). + extract().response(); + + LogUtils.info("RESPONSE: \n" + response.prettyPrint()); + return response; + } + + 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()); + return response; + } + + 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()); + return response; + } + + public static String getResponseKeyValue(Response response, String responseKey) { + JsonPath jsonPath = response.jsonPath(); + String key_value = jsonPath.get(responseKey).toString(); + LogUtils.info("Get body by key (" + responseKey + "): " + key_value); + return key_value; + } + + public static String getResponseKeyValue(String responseBody, String responseKey) { + JsonPath jsonPath = new JsonPath(responseBody); + String key_value = jsonPath.get(responseKey).toString(); + LogUtils.info("Get body by key (" + responseKey + "): " + key_value); + return key_value; + } + + public static int getStatusCode(Response response) { + int status_code = response.getStatusCode(); + LogUtils.info("Get Status Code: " + status_code); + return status_code; + } + + public static String getStatusLine(Response response) { + String status_line = response.getStatusLine(); + LogUtils.info("Get Status Line: " + status_line); + return status_line; + } + + public static String getResponseHeader(Response response, String header_key) { + String response_header = response.getHeader(header_key); + LogUtils.info("Get Header by key (" + header_key + "): " + response_header); + return response_header; + } + + public static String getResponseContentType(Response response) { + String content_type = response.getContentType(); + LogUtils.info("Get Content Type: " + content_type); + return content_type; + } + + public static String getResponseCookieName(Response response, String cookieName) { + String cookie_value = response.getCookie(cookieName); + LogUtils.info("Get Cookie by name (" + cookieName + "): " + cookie_value); + return cookie_value; + } + + public static void verifyStatusCode(Response response, int expectedStatusCode) { + LogUtils.info("Verify Status code: " + response.getStatusCode() + " == " + expectedStatusCode); + Assert.assertEquals(response.getStatusCode(), expectedStatusCode, "FAIL. The status code not match."); + } +} \ No newline at end of file diff --git a/src/main/java/com/anhtester/keywords/SpecBuilder.java b/src/main/java/com/anhtester/keywords/SpecBuilder.java new file mode 100644 index 0000000..4bf1da3 --- /dev/null +++ b/src/main/java/com/anhtester/keywords/SpecBuilder.java @@ -0,0 +1,48 @@ +package com.anhtester.keywords; + +import com.anhtester.globals.ConfigsGlobal; +import com.anhtester.globals.TokenGlobal; +import com.anhtester.utils.LogUtils; +import io.restassured.builder.RequestSpecBuilder; +import io.restassured.builder.ResponseSpecBuilder; +import io.restassured.filter.log.LogDetail; +import io.restassured.filter.log.RequestLoggingFilter; +import io.restassured.filter.log.ResponseLoggingFilter; +import io.restassured.http.ContentType; +import io.restassured.specification.RequestSpecification; +import io.restassured.specification.ResponseSpecification; + +public class SpecBuilder { + + 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 RequestLoggingFilter()). + addFilter(new ResponseLoggingFilter()). + log(LogDetail.ALL). + build(); + } + + public static ResponseSpecification getResponseSpecBuilder() { + return new ResponseSpecBuilder(). + expectContentType(ContentType.JSON). + log(LogDetail.ALL). + build(); + } + + public static RequestSpecification getRequestNotAuthSpecBuilder() { + return new RequestSpecBuilder(). + setBaseUri(ConfigsGlobal.BASE_URI). + setBasePath(ConfigsGlobal.BASE_PATH). + setContentType(ContentType.JSON). + setAccept(ContentType.JSON). + addFilter(new RequestLoggingFilter()). + addFilter(new ResponseLoggingFilter()). + log(LogDetail.ALL). + build(); + } +} \ No newline at end of file diff --git a/src/test/java/com/anhtester/Bai10_ReadPropertiesFile/DemoBaseTest.java b/src/test/java/com/anhtester/Bai10_ReadPropertiesFile/DemoBaseTest.java index 2fc36be..cc427e5 100644 --- a/src/test/java/com/anhtester/Bai10_ReadPropertiesFile/DemoBaseTest.java +++ b/src/test/java/com/anhtester/Bai10_ReadPropertiesFile/DemoBaseTest.java @@ -34,7 +34,7 @@ public void testUpdateUser_PATCH() { Gson gson = new Gson(); RequestSpecification request = given(); - request.baseUri(ConfigsGlobal.URI) + request.baseUri(ConfigsGlobal.BASE_URI) .accept("application/json") .contentType("application/json") .header("Authorization", "Bearer " + TokenGlobal.TOKEN) @@ -57,7 +57,7 @@ public void testUpdateUser_PATCH_Builder() { Gson gson = new Gson(); RequestSpecification request = given(); - request.baseUri(ConfigsGlobal.URI) + request.baseUri(ConfigsGlobal.BASE_URI) .accept("application/json") .contentType("application/json") .header("Authorization", "Bearer " + TokenGlobal.TOKEN) diff --git a/src/test/java/com/anhtester/Bai12_ValidateJsonSchema/JsonSchemaValidationTest.java b/src/test/java/com/anhtester/Bai12_ValidateJsonSchema/JsonSchemaValidationTest.java index c213e5f..108aeca 100644 --- a/src/test/java/com/anhtester/Bai12_ValidateJsonSchema/JsonSchemaValidationTest.java +++ b/src/test/java/com/anhtester/Bai12_ValidateJsonSchema/JsonSchemaValidationTest.java @@ -20,7 +20,7 @@ public void validateJsonSchema_GetBookById() { // Perform the API request and get the response Response response = given() - .baseUri(ConfigsGlobal.URI) + .baseUri(ConfigsGlobal.BASE_URI) .when() .get("/book/10") .then() @@ -44,7 +44,7 @@ public void validateJsonSchema_GetBookAll() { // Perform the API request and get the response Response response = given() - .baseUri(ConfigsGlobal.URI) + .baseUri(ConfigsGlobal.BASE_URI) .when() .get("/books") .then() diff --git a/src/test/java/com/anhtester/Bai13_ThucHanh/BookTest.java b/src/test/java/com/anhtester/Bai13_ThucHanh/BookTest.java index 29140f6..a807b9d 100644 --- a/src/test/java/com/anhtester/Bai13_ThucHanh/BookTest.java +++ b/src/test/java/com/anhtester/Bai13_ThucHanh/BookTest.java @@ -73,7 +73,7 @@ public void testAddNewBook(){ Gson gson = new Gson(); RequestSpecification request = given(); - request.baseUri(ConfigsGlobal.URI) + request.baseUri(ConfigsGlobal.BASE_URI) .accept(ContentType.JSON) .contentType(ContentType.JSON) .header("Authorization", "Bearer " + TokenGlobal.TOKEN) diff --git a/src/test/java/com/anhtester/Bai14_Annotation/DemoRunTestXML_02.java b/src/test/java/com/anhtester/Bai14_Annotation/DemoRunTestXML_02.java index 24dee7d..60daed0 100644 --- a/src/test/java/com/anhtester/Bai14_Annotation/DemoRunTestXML_02.java +++ b/src/test/java/com/anhtester/Bai14_Annotation/DemoRunTestXML_02.java @@ -45,7 +45,7 @@ public void testAddNewBook() { Gson gson = new Gson(); RequestSpecification request = given(); - request.baseUri(ConfigsGlobal.URI) + request.baseUri(ConfigsGlobal.BASE_URI) .accept(ContentType.JSON) .contentType(ContentType.JSON) .header("Authorization", "Bearer " + TokenGlobal.TOKEN) diff --git a/src/test/java/com/anhtester/Bai17_Keyword/BookTest_Keyword.java b/src/test/java/com/anhtester/Bai17_Keyword/BookTest_Keyword.java new file mode 100644 index 0000000..9b80bc0 --- /dev/null +++ b/src/test/java/com/anhtester/Bai17_Keyword/BookTest_Keyword.java @@ -0,0 +1,18 @@ +package com.anhtester.Bai17_Keyword; + +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_Keyword 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")); + } +} diff --git a/src/test/java/com/anhtester/Bai17_Keyword/CategoryTest_Keyword.java b/src/test/java/com/anhtester/Bai17_Keyword/CategoryTest_Keyword.java new file mode 100644 index 0000000..a5940a2 --- /dev/null +++ b/src/test/java/com/anhtester/Bai17_Keyword/CategoryTest_Keyword.java @@ -0,0 +1,63 @@ +package com.anhtester.Bai17_Keyword; + +import com.anhtester.common.BaseTest; +import com.anhtester.globals.EndPointGlobal; +import com.anhtester.keywords.ApiKeyword; +import com.anhtester.listeners.TestListener; +import com.anhtester.utils.LogUtils; +import io.restassured.path.json.JsonPath; +import io.restassured.response.Response; +import org.testng.Assert; +import org.testng.annotations.Listeners; +import org.testng.annotations.Test; + +import static io.restassured.RestAssured.given; + +@Listeners(TestListener.class) +public class CategoryTest_Keyword extends BaseTest { + + int CATEGORY_ID; + String CATEGORY_NAME; + + @Test(priority = 1) + public void testAddNewCategory() { + String dataFile = "src/test/resources/testdata/CreateCategory.json"; + +// RequestSpecification request = given(); +// request.baseUri("https://api.anhtester.com/api") +// .accept(ContentType.JSON) +// .contentType(ContentType.JSON) +// .header("Authorization", "Bearer " + TokenGlobal.TOKEN) +// .body(new File(dataFile)); + + Response response = ApiKeyword.post(EndPointGlobal.EP_CATEGORY, dataFile); + + //response.then().statusCode(200); + 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() { + +// RequestSpecification request = given(); +// request.baseUri("https://api.anhtester.com/api") +// .accept(ContentType.JSON) +// .contentType(ContentType.JSON) +// .header("Authorization", "Bearer " + TokenGlobal.TOKEN); + + 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."); + + } +} \ No newline at end of file diff --git a/src/test/java/com/anhtester/common/BaseTest.java b/src/test/java/com/anhtester/common/BaseTest.java index 3b3fcfa..ee373ca 100644 --- a/src/test/java/com/anhtester/common/BaseTest.java +++ b/src/test/java/com/anhtester/common/BaseTest.java @@ -1,8 +1,10 @@ package com.anhtester.common; import com.anhtester.globals.ConfigsGlobal; +import com.anhtester.globals.EndPointGlobal; import com.anhtester.globals.TokenGlobal; import com.anhtester.helpers.PropertiesHelper; +import com.anhtester.keywords.ApiKeyword; import com.anhtester.listeners.TestListener; import com.anhtester.model.LoginPOJO; import com.anhtester.model.data.LoginPOJO_Builder; @@ -27,13 +29,16 @@ public void loginUser() { Gson gson = new Gson(); - RequestSpecification request = given(); - request.baseUri(ConfigsGlobal.URI) - .accept("application/json") - .contentType("application/json") - .body(gson.toJson(loginPOJO)); +// RequestSpecification request = given(); +// request.baseUri(ConfigsGlobal.BASE_URI) +// .accept("application/json") +// .contentType("application/json") +// .body(gson.toJson(loginPOJO)); +// +// Response response = request.when().post("/login"); + + Response response = ApiKeyword.postNotAuth(EndPointGlobal.EP_LOGIN, gson.toJson(loginPOJO)); - Response response = request.when().post("/login"); response.then().statusCode(200); TokenGlobal.TOKEN = response.getBody().path("token"); diff --git a/src/test/java/com/anhtester/listeners/TestListener.java b/src/test/java/com/anhtester/listeners/TestListener.java index c60d85d..2a8c1f8 100644 --- a/src/test/java/com/anhtester/listeners/TestListener.java +++ b/src/test/java/com/anhtester/listeners/TestListener.java @@ -1,6 +1,7 @@ package com.anhtester.listeners; import com.anhtester.globals.ConfigsGlobal; +import com.anhtester.helpers.PropertiesHelper; import com.anhtester.utils.LogUtils; import org.testng.ITestContext; import org.testng.ITestListener; @@ -9,8 +10,9 @@ public class TestListener implements ITestListener { @Override public void onStart(ITestContext result) { - LogUtils.info("\n **********************************"); + LogUtils.info("\n===============================================================\n==================== " + result.getSuite().getName().toUpperCase() + " STARTING ===================\n==============================================================="); //Read Properties - loadAllFiles() + PropertiesHelper.loadAllFiles(); //Select Database - lưu trữ vào biến toàn cục //Connect tới bên thứ 3 cho thuê reports chẳng hạn } @@ -20,6 +22,7 @@ public void onFinish(ITestContext result) { //Tổng kết lại tình hình chạy test //In ra logs cho biết là đã kết thức và chạy được bao nhiêu cái pass/fail //Gửi mail đến mail chung để nắm bắt tình hình - Lấy ra các biến toàn cục hoặc file logs, report + LogUtils.info("\n################################# FINISH ################################"); LogUtils.info("Đã gửi mail đến admin@anhtester.com"); LogUtils.info("Tổng số test cases: " + ConfigsGlobal.TCS_TOTAL); LogUtils.info("Số test cases passed: " + ConfigsGlobal.PASSED_TOTAL); @@ -28,7 +31,8 @@ public void onFinish(ITestContext result) { @Override public void onTestStart(ITestResult result) { - LogUtils.info("Đang chạy test case: " + result.getName()); + LogUtils.info("\n*****************************************************************"); + LogUtils.info("Đang chạy test case " + result.getName()); //Mình sẽ bắt cái tên TCs để ghi logs và ghi vào report (Allure report) ConfigsGlobal.TCS_TOTAL++; } @@ -36,27 +40,20 @@ public void onTestStart(ITestResult result) { @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 passed: " + result.getName()); + LogUtils.info("Test case " + result.getName() + " is passed."); ConfigsGlobal.PASSED_TOTAL++; } @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 failed: " + result.getName()); + LogUtils.error("Test case " + result.getName() + " is failed."); LogUtils.error(result.getThrowable()); ConfigsGlobal.FAILED_TOTAL++; } - @Override - public void onTestFailedButWithinSuccessPercentage(ITestResult result) { - // TODO Auto-generated method stub - - } - @Override public void onTestSkipped(ITestResult result) { - // TODO Auto-generated method stub - + LogUtils.warn("Test case " + result.getName() + " is skipped."); } -} +} \ No newline at end of file diff --git a/src/test/resources/testdata/CreateCategory.json b/src/test/resources/testdata/CreateCategory.json index 0bdc52e..b0badcc 100644 --- a/src/test/resources/testdata/CreateCategory.json +++ b/src/test/resources/testdata/CreateCategory.json @@ -1 +1 @@ -{"name":"Auto API A12"} \ No newline at end of file +{"name":"Auto API A21"} \ No newline at end of file