NỘI DUNG BÀI HỌC
✅ Hiểu được mối liên kết giữa các tầng trong POM (BasePage → Page Object → Test Layer).
✅ Nắm vững cấu trúc dự án hoàn chỉnh và ý nghĩa từng thư mục trong automation framework.
✅ Phân biệt và áp dụng được các mô-đun mở rộng trong POM: Component, Utils, Data, Config.
✅ Biết cách xây dựng dòng chảy nghiệp vụ (Business Flow) giữa các Page Object.
✅ Định hình được tư duy thiết kế framework chuyên nghiệp có khả năng mở rộng và tái sử dụng.
I. ÔN TẬP NGẮN: TRIẾT LÝ CỐT LÕI CỦA POM
1. POM là gì?
Page Object Model là mô hình giúp tách biệt:
-
WHAT – Nghiệp vụ cần kiểm thử.
-
HOW – Cách thực hiện thao tác trên UI.
2. Mục tiêu chính
-
Tập trung logic kỹ thuật vào BasePage.
-
Mô tả nghiệp vụ rõ ràng trong Page Object.
-
Giúp test case ngắn gọn, dễ đọc, dễ mở rộng.
II. TỔNG QUAN VỀ CẤU TRÚC POM NÂNG CAO
Một framework chuyên nghiệp thường mở rộng từ kiến trúc POM cơ bản sang mô hình đa tầng sau:
project_root/
│
├── pages/ ← PAGE OBJECT LAYER (Nghiệp vụ & Nền tảng)
│ ├── base_page.py → Base class cho tất cả Page Object
│ └── login_page.py → Chứa locators + các action của trang Login
│
├── components/ ← (Optional) COMPONENT LAYER
│ └── header_component.py → Component UI tái sử dụng đơn giản
│
├── resources/ ← (Optional) DATA & CONFIG LAYER
│ └── config.json → File cấu hình hoặc test data đơn giản
│
├── utils/ ← (Optional) HELPER LAYER
│ └── helper.py → Các hàm hỗ trợ phi UI (vd: log, đọc file)
│
├── tests/ ← TEST SCENARIO LAYER (WHAT)
│ └── test_login_pom.py → Chứa các test case cho luồng đăng nhập
│
├── conftest.py ← THE GLUE (CONNECTOR)
│ → Setup/Teardown và quản lý fixture
│
├── reports/ ← OUTPUT LAYER (Kết quả kiểm thử)
│ └── report.html → File báo cáo kết quả test đơn giản
│
└── screenshots/ ← EVIDENCE LAYER (Ảnh minh chứng)
└── screenshot.png → File ảnh chụp màn hình khi test lỗi
1. Định nghĩa
BasePage giờ đây nằm trực tiếp trong thư mục pages/. Đây là lớp nền tảng duy nhất mà login_page.py (và các page sau này) kế thừa. Lớp này xử lý:
-
Wait động (Explicit Wait).
-
Logging.
-
Screenshot on Fail.
2. Ví dụ – pages/base_page.py
IV. COMPONENT OBJECT – TÁCH NHỮNG PHẦN TỬ UI DÙNG CHUNG
1. Khái niệm Ngay cả trong dự án tối giản, ta vẫn nên dùng Component cho các phần tử xuất hiện xuyên suốt (như Header sau khi đăng nhập thành công). Nó kế thừa trực tiếp từ BasePage.
2. Ví dụ – components/header_component.py
from pages.base_page import BasePage
class HeaderComponent(BasePage):
"""Đại diện cho thanh header sau khi login."""
MENU_BUTTON = "#react-burger-menu-btn"
LOGOUT_LINK = "#logout_sidebar_link"
def logout(self):
"""Mở menu và đăng xuất."""
self._click(self.MENU_BUTTON, "Menu Button")
self._click(self.LOGOUT_LINK, "Logout Link")
V. DATA-DRIVEN TESTING (DDT) CƠ BẢN
Thay vì tạo thư mục data/ riêng biệt, ta gộp vào resources/ để giữ đúng tính tối giản (1 file dùng chung cho config và data).
1. Ví dụ cấu trúc file – resources/config.json
{
"valid_user": {
"username": "standard_user",
"password": "secret_sauce"
},
"locked_user": {
"username": "locked_out_user",
"password": "secret_sauce"
}
}
2. Cách sử dụng trong test – tests/test_login_pom.py
import json
from pages.login_page import LoginPage
def test_login_from_json(page):
login_page = LoginPage(page)
# Đọc data từ thư mục resources
with open("resources/config.json") as f:
data = json.load(f)
valid = data["valid_user"]
login_page.login(valid["username"], valid["password"])
login_page.assert_login_successful()
VI. PAGE OBJECT MỞ RỘNG – CHUỖI HÀNH ĐỘNG NGHIỆP VỤ
Trong cấu trúc tinh gọn này, chúng ta mô phỏng luồng: Login thành công → Đăng xuất qua Header Component.
Ưu điểm của chuỗi này:
-
Mỗi trang có trách nhiệm riêng.
-
Không cần lặp lại logic login hay add to cart ở nhiều test khác.
-
Test mô tả hành trình người dùng thực tế bằng ngôn ngữ nghiệp vụ.
Sơ đồ 1 chiều
tests/ (WHAT)
↓ (gọi nghiệp vụ)
pages/ (Page Objects – HOW nghiệp vụ theo trang)
↓ (tái sử dụng)
components/ (UI dùng chung theo thành phần)
↓ (kế thừa/ủy quyền)
core/ (Base classes: BasePage, BaseComponent – HOW kỹ thuật)
↓ (thao tác thật)
Playwright API (page, locator, expect)
resources/ (config, testdata) → được đọc bởi tests/ hoặc pages/ (khi cần)
utils/ (db, api, file, logger) → được gọi bởi tests/ hoặc pages/ (khi cần)
conftest.py (fixtures) → khởi tạo “đối tượng + dữ liệu” và bơm vào tests/
reports/, screenshots/ → nhận log, ảnh, kết quả assert khi chạy
VIII. TỔNG KẾT KIẾN THỨC POM NÂNG CAO
| Khái niệm | Định nghĩa | Ứng dụng trong automation |
|---|---|---|
| BasePage nâng cao | Lớp cha chuẩn hóa hành động với Wait, Logging, Screenshot | Giúp test ổn định, dễ debug |
| Component Object | Mô hình tách phần tử UI dùng chung (header, sidebar, popup) | Tăng tái sử dụng, giảm lặp code |
| Data-Driven Testing | Cách tách dữ liệu test ra khỏi logic test | Dễ mở rộng, dễ quản lý test data |
| Business Flow | Chuỗi hành động kết hợp nhiều Page Object | Mô phỏng luồng người dùng thực tế |
| Clean Test Case | Test chỉ thể hiện luồng nghiệp vụ, không chứa kỹ thuật | Dễ đọc, dễ bảo trì, rõ ràng với non-dev |
IX. BÀI TẬP THỰC HÀNH
Trang web: https://hrm.anhtester.com/erp/login
Yêu cầu:
📦 PlaywrightProject/
│
├── Core/ # Thư mục chứa lớp nền (BasePage) dùng chung
│ ├── base_page.py # Định nghĩa các hàm cơ bản: open_url, click, fill, screenshot
│ └── __init__.py # Giúp Python nhận diện đây là package
│
├── components/ # Thư mục chứa các thành phần UI tái sử dụng (Header, Footer)
│ ├── header_component.py # Xử lý menu header: click từng mục, chụp ảnh, logout
│ └── __init__.py
│
├── pages/ # Thư mục chứa các Page Object đại diện cho từng trang
│ ├── login_page.py # Trang đăng nhập: đọc dữ liệu từ JSON, login, chụp ảnh, logout
│ └── __init__.py
│
├── data/ # Lưu trữ dữ liệu test (JSON, CSV, Excel)
│ ├── credentials.json # Chứa thông tin đăng nhập test
│ └── __init__.py
│
├── results/ # Lưu kết quả chạy test (report HTML)
│ ├── report.html # Báo cáo tự động sinh sau khi chạy pytest
│ └── __init__.py
│
├── screenshots/ # Thư mục lưu toàn bộ ảnh chụp màn hình khi test
│ └── (ảnh tự sinh khi chạy test)
│
├── tests/ # Chứa file test case thực tế (Pytest)
│ ├── test_login_flow.py # Kịch bản: mở → đăng nhập → chụp ảnh → logout
└── __init__.py
Đánh giá hoàn thành:
| Tiêu chí | Mức độ đạt yêu cầu |
|---|---|
| Có Component Header riêng | ✅ |
| Dữ liệu test tách riêng file JSON | ✅ |
| Flow liên kết nhiều Page Object | ✅ |
| Không chứa locator trong test | ✅ |
| Test chạy ổn định, dễ đọc | ✅ |
