Như bài trước mình đã phân tích, cấu trúc của screenplay (trong context UI automation) gồm 3 phần với các mục đich như sau:
- Ability (khả năng): khởi tạo WebDriver và inject nó vào test case (sẽ viết ở bài khác).
- Action (hành động): thực hiện các action liên tiếp và action to có thể chứa nhiều action con (nội dung của bài này)
- Question (kiểm tra thông tin): lấy thông tin từ website và so sánh với kết quả mong đợi. (bài khác).
Nội dung bài viết
I. Nguyên lý hoạt động
Screenplay hoạt động dựa trên 1 biến thể của Command pattern. Nó định nghĩa như sau:
- Testcase là client code
- Actor (class) là Invoker
- Task (interface) là Command
- Task1,2,3,4,5 …. chính là những action, có thể dùng trực tiếp hoặc lồng vào nhau. Ví dụ: Task 1 là gộp của task 4 và task 5. Task2 có chứa task 5…
II. Code đơn giản
Minh viết lại code ở mức dễ hiểu hơn rất nhiều so với code thực tế của screenplay để các bạn không bị confused.
Test case
public class ProfileTest { Actor lucas = Actor.named("lucas"); @Test void go_to_profile_page() { lucas.attemptTo(Open.profilePage()); } }
Actor
public class Actor { private String name; private Actor(String name) { this.name = name; } public static Actor named(String name) { return new Actor(name); } public void attemptTo(Task...tasks) { for (Task task : tasks) { task.execute(this); } } }
Task
public interface Task { void execute(Actor actor); }
Task 1
public class Open implements Task { @Override public void execute(Actor actor) { actor.attemptTo( openHomePage(), login(), openProfilePage() ); } public static Task profilePage() { return new Open(); } }
Task 2,3,4
public class Tasks { public static Task openHomePage(){ return (actor) -> System.out.println("open homepage"); } public static Task login(){ return (actor) -> System.out.println("login"); } public static Task openProfilePage(){ return (actor) -> System.out.println("open profile page"); } }
Ở đây mình sử dụng lambda expression vì Task là 1 functional interface.
open homepage login open profile page
So sánh với code thực tế của Screenplay
Lưu ý:
wasAbleTo()
chính làattemptsTo()
givenThat(), when(), then()
thêm vào để cho dòng code giống như 1 câu văn xuôi, không có tác dụng gì khác.
III. Tổng kết
Như bạn đã thấy, screenplan khác hoàn toàn Page Object Model, nó chỉ còn task, không còn các page nữa. Code thực tế của framework thì còn lằng nhằng hơn rất nhiều vì nó còn có các thứ khác nữa, mình thì không có sức để đọc và viết hết được. =)))