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
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