NỘI DUNG BÀI HỌC
🧠 Tổng quan tư duy
🛠️ Thành phần cơ bản file YML
PHẦN 1: TỔNG QUAN & TƯ DUY (MINDSET)
1. Tại sao cần CI/CD cho Automation? (The "Why")
Mục tiêu: Shift-left mindset - Phát hiện lỗi sớm.
-
Vấn đề "Works on my machine": Code chạy ngon trên máy bạn (Local), nhưng fail trên máy sếp hoặc CI vì khác hệ điều hành, thiếu thư viện.
-
Vấn đề Tần suất: Dev merge code hàng chục lần một ngày. QA không thể ngồi canh để chạy lệnh npx playwright test bằng tay mãi được.
-
Giải pháp CI (Continuous Integration): Tự động kích hoạt test ngay khi có code mới.
-
Test Pass ✅ -> Cho phép Merge.
-
Test Fail ❌ -> Chặn Merge, báo Dev sửa ngay.
-
2. Kiến trúc cơ bản của một Pipeline
Ví dụ thực tế: Hãy tưởng tượng Pipeline là một dây chuyền sản xuất trong nhà máy.
-
Trigger (Cò súng): Sự kiện khởi động dây chuyền (VD: Có code mới đẩy lên nhánh main).
-
Runner (Nhân công): Một máy tính ảo (Virtual Machine - thường là Linux Ubuntu) hoàn toàn mới và "sạch sẽ" do GitHub cung cấp để thực hiện công việc.
-
Jobs & Steps (Quy trình):
-
Job: Một nhóm công việc (VD: Job "Chạy Test").
-
Step: Từng thao tác nhỏ (Lấy code -> Cài Node -> Cài Browser -> Chạy lệnh).
-
-
Artifacts (Thành phẩm): Kết quả đóng gói sau khi chạy xong (Báo cáo HTML, Video, Screenshot lỗi).
PHẦN 2: GIẢI PHẪU FILE YAML & MÔ HÌNH "NGƯỜI NHÂN VIÊN MỚI"
Cách giải thích: Hãy ví file .yml là "Tờ phiếu giao việc" (To-do list) bạn đưa cho một nhân viên mới tinh (máy Runner).
1. Cấu trúc giải phẫu (Anatomy)
Một file YAML chuẩn gồm 3 phần: Tên, Thời điểm, và Hành động.
# 1. TÊN QUY TRÌNH (Nhãn dán)
name: Playwright Tests
# 2. KHI NÀO CHẠY? (Trigger)
on:
push:
branches: [ main ] # Chạy khi có code đẩy vào main
# 3. LÀM GÌ? (Jobs)
jobs:
test-e2e:
runs-on: ubuntu-latest # Thuê máy Ubuntu
steps:
- uses: actions/checkout@v4 # Bước 1: Lấy code
- run: npm ci # Bước 2: Cài thư viện
- run: npx playwright test # Bước 3: Chạy test
2. Từ khóa quan trọng & Ý nghĩa
-
runs-on: ubuntu-latest: Yêu cầu cấp một máy tính chạy hệ điều hành Ubuntu bản mới nhất. (Lý do chọn Ubuntu: Nhẹ, miễn phí, chạy Playwright nhanh hơn Windows).
-
steps: Danh sách hành động tuần tự.
-
run: Chạy câu lệnh Terminal bình thường (Cứ gõ gì ở máy local thì gõ y chang vào đây).
-
uses: Xài "Tool có sẵn" của người khác viết (GitHub Marketplace).
-
Ví dụ: Thay vì tự viết script dài dòng để cài Node.js, ta dùng uses: actions/setup-node@v4.
-
-
-
with: Tham số truyền vào cho uses (Giống tham số hàm).
3. Quy tắc "Sống còn": Thụt đầu dòng (Indentation)
-
YAML không dùng {} hay ;. Nó dùng khoảng trắng (space) để phân cấp cha-con.
-
Quy tắc: Con phải thụt vào so với cha (thường là 2 spaces). Các gạch đầu dòng - phải thẳng hàng.
-
Cấm kỵ: Không dùng phím TAB.
PHẦN 3: QUẢN LÝ BIẾN MÔI TRƯỜNG (ENVIRONMENT VARIABLES)
Trong GitHub Actions, biến môi trường (env) có thể được đặt ở 3 cấp độ khác nhau, tùy thuộc vào phạm vi ảnh hưởng (Scope).
Cấp độ 1: Workflow Level (Toàn cục)
Đặt ngay dưới name. Mọi Job và mọi Step trong file này đều đọc được.
-
Dùng khi: Cấu hình chung cho cả quy trình (VD: URL của môi trường test, Timezone).
Cấp độ 2: Job Level (Cục bộ cho Job)
Đặt bên trong một job. Chỉ các step trong job đó mới đọc được.
-
Dùng khi: Job A test trên Chrome cần biến khác với Job B test trên Firefox (ít gặp).
Cấp độ 3: Step Level (Cục bộ cho Step)
Đặt trong một step cụ thể.
-
Dùng khi: Chỉ một câu lệnh duy nhất cần biến này.
Cấp độ Đặc biệt: GitHub Secrets (Bảo mật tuyệt đối)
Những thông tin nhạy cảm (Password, API Key) KHÔNG ĐƯỢC viết trực tiếp vào file YAML.
-
Cách làm: Vào Settings > Secrets and variables > Actions trên GitHub repo để tạo.
-
Cách dùng: Gọi bằng cú pháp ${{ secrets.TEN_BIEN }}.
PHẦN 4: FILE CẤU HÌNH HOÀN CHỈNH (MẪU)
Dưới đây là file playwright.yml chuẩn mực kết hợp cả quản lý biến và xử lý Report.
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
# ======================================================
# CẤP ĐỘ 1: Workflow Level (Toàn cục)
# Tác dụng: Mọi Job (test-e2e, test-api) đều nhìn thấy.
# ======================================================
env:
PROJECT_NAME: "Learning-Playwright-CI"
ENVIRONMENT: "staging"
# Mẹo: CI=true giúp Playwright biết nó đang chạy trên server
CI: true
jobs:
# ----------------------------------------------------------------
# JOB 1: CHẠY E2E TEST (Cần Browser, cần Report)
# ----------------------------------------------------------------
test-e2e:
name: Run E2E Tests (Chrome)
runs-on: ubuntu-latest
timeout-minutes: 60
# ======================================================
# CẤP ĐỘ 2: Job Level
# Tác dụng: Chỉ áp dụng cho Job "test-e2e" này.
# Job "test-api" bên dưới sẽ KHÔNG thấy các biến này.
# ======================================================
env:
BROWSER: chromium
RETRIES: 2
steps:
# 1. Lấy code về
- uses: actions/checkout@v4
# 2. Cài Node.js (Version 20 LTS)
- uses: actions/setup-node@v4
with:
node-version: 20
# 3. Cài Dependencies (Dùng npm ci cho môi trường sạch)
- name: Install dependencies
run: npm ci
# 4. Cài Playwright Browsers & OS Dependencies
- name: Install Playwright Browsers
run: npx playwright install --with-deps
# 5. Chạy Test
# ======================================================
# CẤP ĐỘ 3: Step Level (Chi tiết nhất)
# Tác dụng: Chỉ lệnh này mới đọc được Password.
# ======================================================
- name: Run Playwright tests
run: npx playwright test
env:
# Lấy mật khẩu từ GitHub Secrets (Bảo mật)
USER_PASSWORD: ${{ secrets.USER_PASSWORD }}
# Ghi đè biến toàn cục (nếu cần test trên URL khác)
BASE_URL: 'https://staging.example.com'
# 6. Upload Report (QUAN TRỌNG: Luôn chạy dù test fail)
- uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report-e2e
path: playwright-report/
retention-days: 30
# ----------------------------------------------------------------
# JOB 2: CHẠY API TEST / SANITY (Ví dụ về Job độc lập)
# Mục đích: Demo cho học viên thấy Job này không bị ảnh hưởng bởi Job trên
# ----------------------------------------------------------------
test-api:
name: Run API Sanity Check
runs-on: ubuntu-latest
# Biến ở Cấp độ 2 của Job này hoàn toàn khác Job trên
env:
API_TIMEOUT: 5000
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm ci
# Demo: Chạy test API nhẹ nhàng (Giả lập)
- name: Run API Tests
run: echo "Running API tests with timeout $API_TIMEOUT..."
# Câu lệnh này sẽ thấy ENV 'PROJECT_NAME' (Cấp 1) và 'API_TIMEOUT' (Cấp 2)
# Nhưng KHÔNG thấy 'BROWSER' (Của Job 1)
TỔNG QUAN: BỨC TRANH LỚN
File này định nghĩa một quy trình gồm 2 công việc (Jobs): test-e2e và test-api.
-
Đặc điểm quan trọng: Hai job này chạy SONG SONG (Parallel). GitHub sẽ cấp cho bạn 2 máy ảo Ubuntu riêng biệt để chạy cùng lúc, không máy nào phải chờ máy nào.
BƯỚC 1: KÍCH HOẠT (TRIGGER)
-
Sự kiện: Ngay khi học viên thực hiện lệnh git push lên nhánh main hoặc tạo một Pull Request.
-
Hệ thống: GitHub Actions nhận tín hiệu và bắt đầu đọc file YAML này.
BƯỚC 2: THIẾT LẬP TOÀN CỤC (WORKFLOW SETUP)
Trước khi chia việc cho các máy con, hệ thống ghi nhận các Biến môi trường Cấp 1 (Global):
-
PROJECT_NAME: "Learning-Playwright-CI"
-
CI: true
-
Ý nghĩa: Bất kể là máy chạy E2E hay máy chạy API, tụi nó đều biết mình đang làm cho dự án "Learning-Playwright-CI".
BƯỚC 3: THỰC THI (EXECUTION) - HAI LUỒNG SONG SONG
Tại đây, dòng thời gian tách làm đôi. GitHub cấp 2 máy tính ảo (Runners).
🟢 LUỒNG A: JOB test-e2e (Máy số 1)
Đây là luồng chính, nặng nhất.
-
Khởi động & Nhận biến Job (Cấp 2):
-
Máy 1 bật lên (Ubuntu).
-
Nó nhận thêm biến riêng: BROWSER=chromium, RETRIES=2.
-
Lưu ý: Nó hoàn toàn không biết gì về biến API_TIMEOUT của máy bên kia.
-
-
Checkout Code (actions/checkout):
-
Máy 1 tải toàn bộ source code từ GitHub về.
-
-
Cài đặt Môi trường (setup-node & npm ci):
-
Cài Node.js v20.
-
Cài các thư viện trong package.json (Playwright, Typescript...).
-
-
Cài Browser (playwright install):
-
Tải Chrome, Firefox, Webkit và các thư viện hệ thống Linux cần thiết.
-
-
Chạy Test (run playwright test) - QUAN TRỌNG:
-
Tại bước này, Biến môi trường Cấp 3 (Step Level) được kích hoạt.
-
Nó tiêm (inject) USER_PASSWORD từ Secrets vào quy trình.
-
Nó ghi đè (override) hoặc thiết lập BASE_URL.
-
Playwright thực thi test dựa trên tất cả các biến đã có (Global + Job + Step).
-
Kịch bản: Nếu Test Pass -> Bước này màu Xanh. Nếu Test Fail -> Bước này màu Đỏ.
-
-
Lưu Báo Cáo (upload-artifact):
-
Nhờ dòng if: always(), bước này chạy bất kể bước 5 có màu Đỏ hay Xanh.
-
Nó đóng gói thư mục playwright-report/ thành một file zip và đẩy lên Server của GitHub để bạn tải về xem.
-
🔵 LUỒNG B: JOB test-api (Máy số 2)
Đây là luồng phụ để demo tính độc lập.
-
Khởi động & Nhận biến Job (Cấp 2):
-
Máy 2 bật lên (Ubuntu).
-
Nó nhận biến riêng: API_TIMEOUT=5000.
-
Lưu ý: Nó không biết BROWSER hay USER_PASSWORD của máy 1.
-
-
Các bước chuẩn bị:
-
Cũng Checkout code, cài Node, cài thư viện (giống máy 1).
-
Khác biệt: Không cần cài Browser (tiết kiệm thời gian).
-
-
Chạy Test API:
-
In ra dòng chữ demo. Trong thực tế, đây là lúc chạy npx playwright test --project=api.
-
BƯỚC 4: KẾT THÚC (COMPLETION)
-
Trạng thái Workflow:
-
Nếu cả Máy 1 và Máy 2 đều báo Xanh ✅ -> Pipeline thành công (Pass).
-
Nếu chỉ cần 1 trong 2 máy báo Đỏ ❌ -> Pipeline thất bại (Fail). Email báo lỗi được gửi về cho người commit code.
-
-
Artifacts: File playwright-report-e2e.zip xuất hiện ở phần Summary của GitHub Actions, sẵn sàng để tải về.
SƠ ĐỒ DÒNG DỮ LIỆU CỦA BIẾN MÔI TRƯỜNG (VISUALIZATION)
| Tên Biến | Máy chạy E2E nhìn thấy? | Máy chạy API nhìn thấy? | Nguồn gốc |
| PROJECT_NAME | ✅ Có | ✅ Có | Cấp 1 (Global) |
| BROWSER | ✅ Có | ❌ Không | Cấp 2 (Job E2E) |
| API_TIMEOUT | ❌ Không | ✅ Có | Cấp 2 (Job API) |
| USER_PASSWORD | ✅ Có (Chỉ lúc chạy test) | ❌ Không | Cấp 3 (Step + Secret) |
