NỘI DUNG BÀI HỌC

✅ Hiểu tại sao OOP là cốt lõi để xây dựng framework automation có thể tái sử dụng và dễ bảo trì.
✅ Phân biệt rõ ràng hai khái niệm: ClassObject.
✅ Nắm vững cách khởi tạo đối tượng với __init__ và vai trò của từ khóa self.
✅ Xây dựng các Class có đầy đủ AttributesMethods.
✅ Hiểu rõ về Scope để tránh lỗi logic.
✅ Vận dụng OOP để xây dựng Page Object Model (POM) đầu tiên với Python Playwright.

1. Tại sao phải dùng OOP? Code "lộn xộn" vs. Code "ngăn nắp"

 

Hãy tưởng tượng bạn đang xây dựng một bộ kịch bản kiểm thử cho trang web thương mại điện tử. Bạn có các test case cho việc: Đăng nhập, Tìm kiếm sản phẩm, Thêm vào giỏ hàng, Thanh toán.

Kịch bản "lộn xộn" (Procedural Script): Mỗi file test case (test_login.py, test_search.py) đều chứa các dòng code lặp đi lặp lại để tìm đến ô username, ô password, nút login. Khi giao diện trang đăng nhập thay đổi (ví dụ: ID của ô username đổi từ "user" thành "username"), bạn phải vào TẤT CẢ các file và sửa lại. Rất tốn thời gian và dễ gây sai sót.

Kịch bản "ngăn nắp" (Object-Oriented Script): Bạn tạo một "bản thiết kế" duy nhất cho trang đăng nhập, gọi là class LoginPage. Bên trong đó, bạn định nghĩa một lần duy nhất các element (username_input, password_input, login_button) và các hành động (login(user, pass)).

Khi giao diện thay đổi, bạn chỉ cần vào file LoginPage.py và sửa MỘT LẦN DUY NHẤT. Tất cả các test case khác gọi đến LoginPage sẽ tự động được cập nhật.

👉 Lập trình Hướng đối tượng (OOP) chính là công cụ giúp chúng ta biến code từ "lộn xộn", khó bảo trì thành "ngăn nắp", có tổ chức và dễ dàng tái sử dụng.

 

2. Khái niệm Cốt lõi - Lớp (Class) và Đối tượng (Object)

Đây là hai khái niệm cơ bản nhất của OOP.

  • Class (Lớp): Là một bản thiết kế 📐 hoặc một khuôn mẫu. Nó định nghĩa các đặc điểm (thuộc tính) và hành vi (phương thức) chung cho một loại đối tượng nào đó.

    • Ví dụ cuộc sống: Bản thiết kế của một chiếc xe hơi, định nghĩa rằng xe sẽ có bánh xe, cửa sổ, màu sơn và có thể chạy, dừng, rẽ trái, rẽ phải.

  • Object (Đối tượng) - Ngôi nhà thực tế 🏠: Là một thể hiện cụ thể được tạo ra từ bản thiết kế (Class). Mỗi đối tượng sẽ có những giá trị đặc điểm riêng của nó.

    • Ví dụ cuộc sống: Chiếc Vinfast Fadil màu đỏ của bạn, chiếc Mercedes C300 màu đen của sếp. Cả hai đều là những đối tượng được tạo ra từ bản thiết kế "Xe hơi", nhưng có các giá trị thuộc tính (hãng, model, màu sắc) khác nhau.


Ví dụ về Class và Object:

# Class: Bản thiết kế
class Dog:
    # Phương thức (hành động)
    def bark(self):
        print("Gâu gâu!")

# Object: Tạo ra một chú chó cụ thể từ bản thiết kế
my_dog = Dog()

# Gọi hành động của đối tượng đó
my_dog.bark()
# Output: Gâu gâu!​

3. "Trái tim" của Class: __init__self

3.1 __init__ - Phương thức khởi tạo

__init__ là một phương thức đặc biệt (gọi là constructor) sẽ tự động được gọi ngay khi bạn tạo ra một đối tượng mới từ class. Nhiệm vụ chính của nó là gán các giá trị ban đầu cho các thuộc tính của đối tượng.

🔹 Ví dụ trong cuộc sống: Khi một ngôi nhà được xây xong (đối tượng được tạo), đội thi công (hàm __init__) sẽ ngay lập tức sơn tường màu trắng, lắp cửa sổ loại X (gán các giá trị thuộc tính ban đầu).

 

3.2 self - Đại diện cho chính đối tượng (object)

self là một quy ước trong Python, dùng để chỉ chính đối tượng đang được đề cập đến. Nó giúp phân biệt các thuộc tính của đối tượng (self.name) với các biến thông thường khác (name). self luôn là tham số đầu tiên của mọi phương thức trong một class.


🔹 Ví dụ trong cuộc sống: Khi bạn ở trong nhà của mình và nói "phòng khách của tôi", từ "tôi" ở đây chính là self, nó chỉ rõ là phòng khách của ngôi nhà cụ thể này chứ không phải của nhà hàng xóm.

class User:
    # Hàm khởi tạo, được gọi khi new_user = User(...)
    def __init__(self, user_name, user_email):
        print(f"Một user mới đang được tạo...")
        # Dùng `self` để gán giá trị cho các thuộc tính của chính đối tượng này
        self.name = user_name
        self.email = user_email
        self.is_active = True # Gán một giá trị mặc định

# Tạo ra 2 đối tượng User khác nhau
user_A = User("Alice", "alice@email.com")
user_B = User("Bob", "bob@email.com")

# Mỗi đối tượng có thuộc tính `name` của riêng nó
print(f"Tên user A: {user_A.name}") # Output: Tên user A: Alice
print(f"Tên user B: {user_B.name}") # Output: Tên user B: Bob


🔹 Ứng dụng trong Automation: Khi khởi tạo một Page Object, chúng ta thường truyền đối tượng page vào __init__ để trang đó có thể tương tác với trình duyệt.

class SearchPage:
    def __init__(self, page):
        self.page = page
        self.search_input = "#search"
        self.search_button = "#searchBtn"

    def search(self, keyword):
        self.page.fill(self.search_input, keyword)
        self.page.click(self.search_button)

 

✍️ Bài tập thực hành phần 3

Thiết kế Xe hơi: Viết một class Car với hàm __init__ nhận vào 2 tham số là brand (hãng xe) và model. Bên trong __init__, hãy gán chúng cho các thuộc tính self.brandself.model. Sau đó, tạo ra 2 đối tượng xe hơi khác nhau và in ra thông tin của chúng.


4. Thuộc tính và Phương thức - "Đặc điểm" và "Hành động"

  • Attributes (Thuộc tính): Là các biến gắn liền với một đối tượng, dùng để lưu trữ trạng thái hoặc dữ liệu của đối tượng đó (ví dụ: self.name, self.color). Chúng là những "danh từ" mô tả đối tượng.

  • Methods (Phương thức): Là các hàm thuộc về một class, dùng để định nghĩa các hành vi hoặc hành động mà đối tượng có thể thực hiện (ví dụ: login(), calculate_sum()). Chúng là những "động từ" của đối tượng.

🔹 Ứng dụng trong Automation (Page Object Model):

Đây là ứng dụng quan trọng nhất của OOP trong automation.

  • Class: HomePage - Đại diện cho trang chủ.

  • Attributes: Các locators của element trên trang (search_box , login_button ).

  • Methods: Các hành động người dùng có thể làm trên trang (search_product(item_name), go_to_login_page()).

class HomePage:
    def __init__(self, page):
        self.page = page
        self.search_box = "#search"
        self.login_button = "#login"

    def search_product(self, item_name):
        self.page.fill(self.search_box, item_name)
        self.page.press(self.search_box, "Enter")

    def go_to_login(self):
        self.page.click(self.login_button)
​

 

5. Scope - "Phạm vi ảnh hưởng" của biến

 

Scope định nghĩa nơi một biến có thể được truy cập. Hiểu sai về scope là một nguyên nhân phổ biến gây ra lỗi.

  • Local Scope: Biến được tạo bên trong một hàm/phương thức. Nó chỉ tồn tại và có thể được sử dụng bên trong hàm đó mà thôi.

  • Global Scope: Biến được khai báo ở cấp cao nhất của file Python. Nó có thể được truy cập từ bất kỳ đâu trong file. (Nên hạn chế sử dụng biến global).

  • Instance Scope: Biến được gắn với một đối tượng cụ thể thông qua self (ví dụ: self.name). Nó tồn tại chừng nào đối tượng còn tồn tại và có thể được truy cập bởi mọi phương thức trong class đó.

global_variable = "Tôi ở khắp mọi nơi" # Global scope

class MyClass:
    def __init__(self):
        self.instance_variable = "Tôi thuộc về đối tượng" # Instance scope

    def my_method(self):
        local_variable = "Tôi chỉ ở trong hàm này" # Local scope
        print(local_variable)
        print(self.instance_variable)
        print(global_variable)

obj = MyClass()
obj.my_method()
# Output:
# Tôi chỉ ở trong hàm này
# Tôi thuộc về đối tượng
# Tôi ở khắp mọi nơi

print(global_variable) # OK
print(obj.instance_variable) # OK
# print(local_variable) # Lỗi! NameError: name 'local_variable' is not defined


🔹 Ứng dụng trong Automation (Page Object Model):

BASE_URL = "https://example.com"  # Global scope

class BaseTest:
    def __init__(self, page):
        self.page = page  # Instance scope

    def open_home(self):
        self.page.goto(BASE_URL)


6. Mini Quiz 🎯

 

  1. Đâu là "bản thiết kế" và đâu là "sản phẩm cụ thể": Class hay Object?

  2. Phương thức đặc biệt nào sẽ tự động chạy khi một đối tượng được tạo?

  3. Trong một class, từ khóa self đại diện cho điều gì?

  4. Nơi lưu trữ locator của element trong Page Object Model nên là Thuộc tính hay Phương thức?

  5. Một biến được tạo bên trong một phương thức mà không có self đứng trước thì thuộc scope nào?


7. Bài tập tổng hợp cuối buổi

 

Bài 1: Lớp Product (Sản phẩm) Viết một class Product để quản lý thông tin sản phẩm.

  • __init__: Nhận vào name, price, và quantity (số lượng).

  • Phương thức get_total_price(): Trả về tổng giá trị của sản phẩm đó (price * quantity).

  • Phương thức display_info(): In ra thông tin sản phẩm theo định dạng: "Sản phẩm: [Tên], Đơn giá: [Giá], Số lượng: [Số lượng], Tổng giá trị: [Tổng giá trị]".

Bài 2: Máy tính đơn giản Viết một class Calculator.

  • Không cần __init__ phức tạp.

  • Phương thức add(a, b): Trả về tổng của a và b.

  • Phương thức subtract(a, b): Trả về hiệu của a và b.

  • Phương thức multiply(a, b): Trả về tích của a và b.

  • Phương thức divide(a, b): Trả về thương của a và b. Dùng try-except để xử lý trường hợp b bằng 0.

Bài 3: Automation - LoginPage Object Tạo một class LoginPage hoàn chỉnh (không cần chạy Selenium thật, chỉ cần viết code).

  • __init__(self, driver): Lưu lại driver.

  • Thuộc tính: username_locator, password_locator, login_button_locator.

  • Phương thức enter_username(self, username): Giả lập việc tìm element username và gõ username vào. Dùng print() để mô phỏng.

  • Phương thức enter_password(self, password): Tương tự cho password.

  • Phương thức click_login(self): Tương tự cho nút login.

  • Phương thức login(self, username, password): Gọi 3 phương thức trên theo đúng thứ tự để thực hiện toàn bộ quy trình đăng nhập.

Teacher

Teacher

Hà Lan

QA Automation

With over 5 years of experience in web, API, and mobile test automation, built strong expertise in designing and maintaining automation frameworks across various domains and international projects. Committed to mentoring and knowledge sharing, I provide practical guidance and proven techniques to help aspiring testers develop their skills and succeed in the automation field.

Cộng đồng Automation Testing Việt Nam:

🌱 Telegram Automation Testing:   Cộng đồng Automation Testing
🌱 
Facebook Group Automation: Cộng đồng Automation Testing Việt Nam
🌱 
Facebook Fanpage: Cộng đồng Automation Testing Việt Nam - Selenium
🌱 Telegram
Manual Testing:   Cộng đồng Manual Testing
🌱 
Facebook Group Manual: Cộng đồng Manual Testing Việt Nam

Chia sẻ khóa học lên trang

Bạn có thể đăng khóa học của chính bạn lên trang Anh Tester để kiếm tiền

Danh sách bài học