Mình sẽ làm 2 phần:
- Tạo ra Base class để setup chung
- Tạo ra các class thực hiện phần call api riêng
Nội dung bài viết
I. Tạo ra Base class để setup chung
Phần này khá đơn giản, mình tạo ra 1 class, tạm đặt tên là BaseClass để chứa đoạn @BeforeAll.
public class BaseClass { @BeforeAll static void init() { RestAssured.baseURI = "http://localhost"; RestAssured.basePath = "/student"; RestAssured.port = 8080; } }
Các bạn có thể xem ở commit
II. Tạo ra các class thực hiện phần call api riêng
Vì sao lại cần tách class để làm gì?
- Hiện tại mình đang viết trực tiếp phần call API nằm trong các method @Test –> sẽ bị duplicate code giữa các test trong cùng 1 class với nhau. Ví dụ bạn có 3 Test liên quan đến phần GET –> bạn phải viết 3 lần dòng.
given().when().get("/list");
- Khi làm API flow, 1 API có thể sẽ được rất nhiều flow gọi tới, nên việc viết tách riêng sẽ tập trung code –> dễ maintain.
Cách viết khá đơn giản. Ví dụ API Get Student
public class GetStudent { public Response getListStudent() { return given().log().all() .when() .get("/list"); } public Response getListStudentById(String id) { return given().log().all() .when() .get("/{id}", id); } }
Ở class Test, mình sẽ không cần phải viết lại given()… nữa
class GETListStudentTest extends BaseClass { GetStudent getStudent = new GetStudent(); @Test public void getListStudent() { Response res = getStudent.getListStudent(); res.then().statusCode(200); } @Test public void getFirstStudent() { Response res = getStudent.getListStudentById("1"); res.then().statusCode(200).body("email", equalTo("adalberto.glover@yahoo.com")); } }
Mình sẽ làm tương tự cho các API còn lại. Các bạn nên tự làm nốt cho 3 API kia, nếu không “tự xử” được thì xem cách làm của mình nhé.
public class POSTNewStudentTest extends BaseClass { private Student student; private final PostStudent postStudent = new PostStudent(); @BeforeEach void createStudent() { student = Student.getInstance(); } @Test void postNewStudent() { Response res = postStudent.createAStudent(student); res.then().statusCode(201).body("msg", equalTo("Student added")); } }
public class PUTStudentTest extends BaseClass { private Student student; private final PutStudent putStudent = new PutStudent(); private final GetStudent getStudent = new GetStudent(); @BeforeEach void createStudent() { student = Student.getInstance(); } @Test void changeInformationOfAnExistingStudent() { student.setFirstName("Giang"); Response res = putStudent.updateStudent(student, "1"); res.then().statusCode(200).body("msg", equalTo("Student Updated")); JsonPath jsonPath = getStudent.getListStudent().then().extract().body().jsonPath(); List<Student> students = jsonPath.getList("", Student.class); assertThat(students.get(0).getFirstName(), equalTo("Giang")); } }
public class DELETEStudentTest extends BaseClass { private Student student; private final PostStudent postStudent = new PostStudent(); private final DeleteStudent deleteStudent = new DeleteStudent(); @BeforeEach void createStudent() { student = Student.getInstance(); postStudent.createAStudent(student); } @Test void deleteAnExistingStudent() { Response res = deleteStudent.deleteStudent(student); res.then().statusCode(204); } }
Chi tiết, các bạn xem ở commit https://github.com/lucas-nguyen-17/restassured/commit/f4bc269cee32c90df51c91a91f9fc53ffda0d4a3
III. Kết luận
Đây là 1 technique rất đơn giản, nhưng khá hữu ích cho việc viết code dễ maintain hơn. Tất nhiên là code này vẫn đang chỉ ở giai đoạn nhập môn, còn nhiều vấn đề lắm, mình sẽ từ từ giải quyết ở các bài tiếp theo.
Cho mình hỏi, cái hàm Student.getInstance(); thì viết như nào ạ
Đây bạn https://github.com/lucas-nguyen-17/restassured/blob/master/src/main/java/com/giangtester/models/Student.java