NỘI DUNG BÀI HỌC
Phần 1: Ôn Lại Những "Siêu Năng Lực" Cốt Lõi Đã Học 🧠
Phần 2: Mở Rộng Chân Trời - Thế Giới Automation Ngoài Playwright 🌐
Phần 3: Hành Trình Của Bạn Chỉ Mới Bắt Đầu! 🚀
🎉 Chúc mừng các bạn! 🎉
Các bạn đã đi hết chặng đường đầu tiên và cũng là quan trọng nhất trên hành trình trở thành một Kỹ sư Kiểm thử Tự động chuyên nghiệp. Các bạn đã không chỉ học về các câu lệnh, mà còn học cách "tư duy" bằng JavaScript và TypeScript - ngôn ngữ của thế giới web hiện đại.
Hãy tự hào về bản thân! Hôm nay, chúng ta sẽ cùng nhau tổng kết lại những "siêu năng lực" mà các bạn đã trang bị, và quan trọng hơn, khám phá xem với chùm chìa khóa vạn năng này, các bạn có thể mở ra những cánh cửa nào khác ngoài Playwright.
Phần 1: Ôn Lại Những "Siêu Năng Lực" Cốt Lõi Đã Học 🧠
Hãy cùng nhìn lại xem trong túi đồ nghề của các bạn giờ đã có những gì nhé. Đây không chỉ là cú pháp, mà là các khái niệm nền tảng giúp bạn giải quyết mọi vấn đề trong automation.
- Biến, Hằng và Các Kiểu Dữ Liệu (let, const, string, array, object):
- Đây là "Nguyên liệu" của bạn. Mọi kịch bản test đều bắt đầu bằng dữ liệu: URL của trang web, tên đăng nhập, mật khẩu, nội dung cần nhập, kết quả mong đợi. Các bạn đã biết cách lưu trữ và thao tác với chúng.
- Toán tử và Cấu trúc Điều khiển (if/else, for, switch):
- Đây là "Bộ não" của kịch bản. Một trang web không bao giờ tĩnh. Nó luôn thay đổi. Các bạn đã học cách dạy cho kịch bản của mình cách đưa ra quyết định: "Nếu thấy nút này thì click, nếu không thì báo lỗi", hay "Lặp lại hành động này cho tất cả các sản phẩm trong danh sách".
- Hàm (Functions):
- Đây là "Công cụ tái sử dụng". Thay vì viết đi viết lại 10 lần các bước đăng nhập, các bạn đã học cách đóng gói chúng vào một hàm login() và gọi nó khi cần. Đây chính là nguyên tắc Vàng DRY (Don't Repeat Yourself).
- Lập trình Bất đồng bộ (async/await):
- Đây là "Siêu năng lực quan trọng nhất" trong Automation. Mọi hành động trên trình duyệt (goto, click, fill) đều cần thời gian để hoàn thành. async/await chính là cách bạn ra lệnh cho kịch bản: "Hãy kiên nhẫn chờ hành động này làm xong rồi hãy làm bước tiếp theo". Thiếu nó, kịch bản của bạn sẽ trở thành một mớ hỗn loạn.
- Modules (import/export):
- Đây là "Bản thiết kế" cho dự án của bạn. Không ai xây một tòa nhà trong một phòng duy nhất. Các bạn đã học cách chia nhỏ code của mình thành các file có tổ chức (Page Objects, fixtures, utils), giúp dự án trở nên sạch sẽ, dễ đọc và dễ bảo trì.
- Sức mạnh của TypeScript:
- Đây là "Người trợ lý thông minh". TypeScript không thay đổi cách bạn tư duy logic, nhưng nó mang lại sự an toàn (an toàn kiểu dữ liệu - type safety) và sự tiện lợi (tự động gợi ý code - autocompletion). Nó giống như một người trợ lý luôn kiểm tra và nhắc nhở, giúp bạn viết code ít lỗi hơn và nhanh hơn rất nhiều.
Phần 2: Mở Rộng Chân Trời - Code Thực Tế Ngoài Playwright 🌐
Với kỹ năng JS/TS, bạn có thể viết được rất nhiều loại kịch bản tự động khác nhau. Hãy xem chúng trông như thế nào.
Kiểm thử End-to-End với các Framework Khác
Kiến thức JS/TS và tư duy logic của bạn có thể áp dụng 100% cho các framework khác. Cú pháp có thể hơi khác một chút, nhưng bản chất là một.
Ví dụ Minh họa với Cypress:
Đây là một kịch bản đăng nhập vào trang hrm.anhtester.com được viết bằng Cypress. Bạn sẽ thấy nó quen thuộc đến ngạc nhiên!
// File: cypress/e2e/login.cy.js
describe('Chức năng Đăng nhập HRM', () => {
it('Đăng nhập thành công với tài khoản hợp lệ', () => {
// Tương tự page.goto()
cy.visit('https://hrm.anhtester.com/');
// Tương tự locator.type() hoặc locator.fill()
cy.get('#iusername').type('admin_example');
cy.get('#ipassword').type('123456');
// Tương tự getByRole('button').click()
cy.get('button[type="submit"]').click();
// Tương tự expect(...).toBeVisible(). Cú pháp khẳng định hơi khác.
cy.get('.page-header h4').should('be.visible');
cy.get('.page-header h4').should('contain', 'Welcome back, Admin!');
});
});
➡️ Điểm mấu chốt: Logic không đổi, chỉ có "từ vựng" (cy.get thay vì page.locator) thay đổi. Bạn hoàn toàn có thể học một framework mới rất nhanh.
Kiểm thử API (API Testing) 🤖
Đây là lúc bạn thấy sức mạnh của JS/TS khi không cần đến trình duyệt. Chúng ta sẽ dùng thư viện Axios để gửi request và Jest (một framework test có cú pháp gần giống Playwright) để kiểm tra.
Ví dụ Minh họa với Jest và Axios:
Kịch bản này kiểm tra API public JSONPlaceholder để lấy thông tin của người dùng có ID là 1.
// File: __tests__/api.test.js
import axios from 'axios';
describe('API Test cho JSONPlaceholder', () => {
test('Nên lấy được thông tin của người dùng có ID 1', async () => {
// Dùng try-catch để xử lý lỗi mạng tốt hơn
try {
// Gửi request GET bằng Axios, dùng async/await
const response = await axios.get('https://jsonplaceholder.typicode.com/users/1');
// 1. Khẳng định request thành công (status code 200)
expect(response.status).toBe(200);
// 2. Khẳng định dữ liệu trong body trả về là đúng
expect(response.data.name).toBe('Leanne Graham');
expect(response.data.email).toBe('Sincere@april.biz');
expect(response.data.address.city).toBe('Gwenborough');
console.log('API test PASSED. Lấy được user:', response.data.name);
} catch (error) {
// Ném lỗi ra để test runner biết là test đã thất bại
throw new Error(error);
}
});
});
➡️ Điểm mấu chốt: Bạn đang dùng async/await và expect để kiểm tra logic của backend, một kỹ năng cực kỳ giá trị.
Kiểm thử Giao diện (Visual Regression Testing) 🎨
Kỹ thuật này giống như chơi game "tìm điểm khác biệt". Playwright có sẵn một công cụ mạnh mẽ để làm việc này là toHaveScreenshot.
Ví dụ Minh họa với toHaveScreenshot:
Kịch bản này đảm bảo trang chủ Playwright không bị thay đổi giao diện ngoài ý muốn.
// File: tests/visual-homepage.spec.ts
import { test, expect } from '@playwright/test';
test('Giao diện trang chủ Playwright nên ổn định', async ({ page }) => {
await page.goto('https://playwright.dev/');
// Dòng lệnh "thần kỳ"
await expect(page).toHaveScreenshot('homepage.png', { maxDiffPixels: 100 });
});
Cách hoạt động:
Lần chạy đầu tiên: Playwright chưa có ảnh mẫu, nó sẽ chụp một tấm ảnh màn hình và lưu lại với tên homepage.png trong một thư mục snapshots. Đây sẽ là "ảnh gốc" (golden snapshot).
Những lần chạy sau: Playwright sẽ chụp một tấm ảnh mới và so sánh từng pixel với "ảnh gốc".
Nếu giống hệt (hoặc sai khác trong ngưỡng cho phép maxDiffPixels), test sẽ PASS.
Nếu khác biệt, test sẽ FAIL và Playwright sẽ tạo ra 3 file ảnh: homepage-expected.png (ảnh gốc), homepage-actual.png (ảnh thực tế bị lỗi), và homepage-diff.png (tô đỏ những vùng bị khác biệt).
Kiểm thử Hiệu năng (Performance Testing) ⚡
Hãy xem cách JS được dùng để viết kịch bản cho công cụ k6, mô phỏng 10 người dùng ảo truy cập website liên tục trong 30 giây.
Ví dụ Minh họa với k6:
// File: performance-test.js
import http from 'k6/http';
import { sleep } from 'k6';
// Cấu hình kịch bản test
export const options = {
// Giai đoạn test: tăng từ 1 lên 10 người dùng trong 10s, giữ 10 người dùng trong 30s, giảm về 0 trong 10s
stages: [
{ duration: '10s', target: 10 },
{ duration: '30s', target: 10 },
{ duration: '10s', target: 0 },
],
};
// Logic mà mỗi người dùng ảo sẽ thực hiện
export default function () {
http.get('https://test.k6.io'); // Truy cập vào trang web
sleep(1); // Mỗi người dùng sẽ nghỉ 1 giây trước khi lặp lại
}
➡️ Điểm mấu chốt: Cùng là JS, nhưng mục tiêu đã thay đổi. Bạn không kiểm tra "đúng/sai" nữa, mà bạn đang đo lường "nhanh/chậm", "ổn định/sập" của hệ thống dưới áp lực.
Kiểm thử End-to-End với WebDriverIO
WebDriverIO (WDIO) là một framework cực kỳ linh hoạt, có thể chạy trên cả giao thức WebDriver (tiêu chuẩn của Selenium) và Chrome DevTools Protocol (giống Playwright). Nó rất mạnh mẽ trong việc kiểm thử trên nhiều trình duyệt và thiết bị di động.
Ví dụ Minh họa với WebDriverIO:
Kịch bản này cũng là đăng nhập vào trang hrm.anhtester.com. Bạn sẽ thấy cú pháp của WDIO có một chút "lai" giữa Playwright và Cypress.
// File: test/specs/login.e2e.js
describe('Chức năng Đăng nhập HRM', () => {
it('Nên đăng nhập thành công với tài khoản hợp lệ', async () => {
// Tương tự page.goto(), browser là đối tượng toàn cục
await browser.url('https://hrm.anhtester.com/');
// Ký tự '$' là một lối tắt cho `findElement`. Nó tương tự page.locator()
const usernameInput = await $('#iusername');
const passwordInput = await $('#ipassword');
const loginButton = await $('button[type="submit"]');
// Tương tự locator.setValue() hoặc locator.fill()
await usernameInput.setValue('admin_example');
await passwordInput.setValue('123456');
// Tương tự locator.click()
await loginButton.click();
// Cú pháp khẳng định của WDIO kết hợp với thư viện `expect`
const welcomeMessage = await $('.page-header h4');
await expect(welcomeMessage).toBeDisplayed();
await expect(welcomeMessage).toHaveTextContaining('Welcome back, Admin!');
});
});
➡️ Điểm mấu chốt: WebDriverIO sử dụng rất nhiều async/await và các khái niệm về locator mà bạn đã học. Nếu bạn đã quen với Playwright, việc chuyển sang WDIO để làm việc với các dự án dựa trên Selenium sẽ không quá khó khăn.
Viết Kịch bản Test và Pre-request Script trong Postman
Postman không chỉ là một công cụ để "bấm nút" gửi API. Sức mạnh thực sự của nó nằm ở tab "Tests" và "Pre-request Script", nơi bạn có thể viết mã JavaScript để tự động hóa các quy trình phức tạp.
Ví dụ Minh họa với Postman:
Hãy tưởng tượng một kịch bản:
Pre-request Script: Trước khi gọi API tạo sản phẩm, chúng ta cần lấy một token xác thực từ một API đăng nhập.
Tests: Sau khi API tạo sản phẩm trả về kết quả, chúng ta cần kiểm tra status code, kiểm tra nội dung response, và lưu ID của sản phẩm vừa tạo để dùng cho các request sau.
Mở Postman, tạo một request mới và dán code vào các tab tương ứng:
Tab "Pre-request Script":
// Giả sử có một request tên là "Login to get token" trong collection của bạn
// Code này sẽ tự động chạy request đó trước
pm.sendRequest("Login to get token", function (err, response) {
if (err) {
console.log(err);
} else {
// Lấy token từ response của request đăng nhập
const token = response.json().access_token;
// Lưu token vào một biến môi trường để request hiện tại có thể sử dụng
pm.environment.set("authToken", token);
console.log("Đã lấy và lưu token thành công!");
}
});
Để sử dụng token này, trong tab "Authorization", bạn chọn "Bearer Token" và nhập vào {{authToken}}.
Tab "Tests":
JavaScript
// 1. Phân tích cú pháp response body từ dạng text sang đối tượng JSON
const jsonData = pm.response.json();
// 2. Kiểm tra Status Code
pm.test("Status code phải là 201 Created", function () {
pm.response.to.have.status(201);
});
// 3. Kiểm tra nội dung trong response body
pm.test("Tên sản phẩm phải khớp với dữ liệu đã gửi", function () {
// Giả sử bạn gửi lên sản phẩm tên là "iPhone 15 Pro"
pm.expect(jsonData.name).to.eql("iPhone 15 Pro");
});
pm.test("Sản phẩm phải có một ID", function () {
pm.expect(jsonData.id).to.not.be.empty;
});
// 4. Lưu ID của sản phẩm vào một biến môi trường
// để dùng cho các request tiếp theo (ví dụ: request "Update Product")
if (jsonData.id) {
pm.environment.set("productId", jsonData.id);
console.log("Đã lưu ID sản phẩm:", jsonData.id);
}
➡️ Điểm mấu chốt: Postman cung cấp một môi trường JavaScript (dựa trên Node.js) với các đối tượng toàn cục tiện lợi (pm, pm.test, pm.expect). Toàn bộ kiến thức về if/else, hàm, và xử lý đối tượng JSON của bạn được áp dụng triệt để ở đây để tạo ra các kịch bản API tự động cực kỳ mạnh mẽ.
Phần 3: Hành Trình Của Bạn Chỉ Mới Bắt Đầu! 🚀
Vậy, con đường tiếp theo là gì?
-
Luyện tập, luyện tập, luyện tập: Hãy tự mình xây dựng một dự án kiểm thử nhỏ từ đầu đến cuối.
-
Đào sâu vào Framework: Hãy chọn một framework (Playwright, Cypress) và trở thành chuyên gia về nó. Đọc tài liệu, khám phá các API nâng cao.
-
Học về Mẫu thiết kế (Design Patterns): Nắm vững Page Object Model (POM) và các kỹ thuật tái sử dụng code.
-
Tìm hiểu về CI/CD: Học cách tích hợp các bài test của bạn vào các quy trình tự động như GitHub Actions. Đây là nơi automation thực sự tỏa sáng.
-
Tham gia cộng đồng: Đừng ngại đặt câu hỏi, theo dõi các blog và tham gia các diễn đàn.
Lời kết: Các bạn đã nắm trong tay chùm chìa khóa JS/TS - một trong những kỹ năng giá trị nhất trong thế giới công nghệ hiện nay. Nó không chỉ mở ra cánh cửa trở thành một Automation Tester giỏi, mà còn mở ra vô số cơ hội khác trong lĩnh vực phát triển web và tự động hóa.