0
0
Lập trình
Admin Team
Admin Teamtechmely

Viết Unit Tests cho Mã Python với unittest & doctest

Đăng vào 6 tháng trước

• 5 phút đọc

Giới thiệu

Trong Python, việc viết và quản lý các bài kiểm tra đơn vị (unit tests) là rất quan trọng để đảm bảo mã của bạn hoạt động đúng. Hai công cụ phổ biến trong thư viện chuẩn của Python để hỗ trợ việc này là unittestdoctest. Bài viết này sẽ cung cấp cho bạn cái nhìn sâu sắc về cách sử dụng chúng để viết, tổ chức, chạy và tự động hóa các bài kiểm tra.

Nội dung bài viết

1. Tổng quan về unittest và doctest

1.1. unittest

unittest là một framework kiểm thử hoàn chỉnh, cung cấp nhiều tính năng để viết và tổ chức các bài kiểm tra. Nó được lấy cảm hứng từ JUnit, một framework kiểm thử phổ biến trong Java. Dưới đây là một số khái niệm cơ bản:

  • Test case: Một đơn vị kiểm thử, kiểm tra kết quả đầu ra cho một tập hợp đầu vào nhất định.
  • Test suite: Tập hợp của nhiều test case hoặc test suite khác.
  • Test fixture: Nhóm hành động cần thiết để thiết lập môi trường cho kiểm thử.
  • Test runner: Thành phần xử lý việc thực thi các bài kiểm tra và thông báo kết quả cho người dùng.

1.2. doctest

doctest là một framework kiểm thử nhẹ nhàng hơn, cho phép bạn viết các bài kiểm tra trong docstring của mã. Nó có thể đọc các trường hợp kiểm tra từ tài liệu của dự án và từ docstring của mã.

2. Cài đặt và cấu trúc

Để bắt đầu với unittest, bạn không cần cài đặt thêm gì vì nó đã có sẵn trong thư viện chuẩn của Python. Đối với doctest, bạn cũng có thể sử dụng nó mà không cần cài đặt thêm. Bạn chỉ cần import chúng vào mã của mình:

python Copy
import unittest
import doctest

3. Viết bài kiểm tra với unittest

3.1. Ví dụ cơ bản

Dưới đây là một ví dụ đơn giản về cách viết bài kiểm tra cho một hàm phân loại theo độ tuổi:

python Copy
# age.py

def categorize_by_age(age):
    if 0 <= age <= 9:
        return "Trẻ em"
    elif 9 < age <= 18:
        return "Vị thành niên"
    elif 18 < age <= 65:
        return "Người lớn"
    elif 65 < age <= 150:
        return "Người cao tuổi"
    else:
        return f"Tuổi không hợp lệ: {age}"

Để kiểm tra hàm này, bạn có thể viết một test case như sau:

python Copy
# test_age.py

import unittest
from age import categorize_by_age

class TestCategorizeByAge(unittest.TestCase):
    def test_child(self):
        self.assertEqual(categorize_by_age(5), "Trẻ em")

    def test_adolescent(self):
        self.assertEqual(categorize_by_age(15), "Vị thành niên")

    def test_adult(self):
        self.assertEqual(categorize_by_age(30), "Người lớn")

    def test_golden_age(self):
        self.assertEqual(categorize_by_age(70), "Người cao tuổi")

    def test_negative_age(self):
        self.assertEqual(categorize_by_age(-1), "Tuổi không hợp lệ: -1")

    def test_too_old(self):
        self.assertEqual(categorize_by_age(151), "Tuổi không hợp lệ: 151")

3.2. Chạy bài kiểm tra

Để chạy các bài kiểm tra, bạn cần làm cho module kiểm tra có thể thực thi:

python Copy
if __name__ == "__main__":
    unittest.main()

Sau đó, bạn có thể chạy file này từ dòng lệnh:

Copy
python test_age.py

3.3. Tuỳ chỉnh thông tin đầu ra

Bạn có thể điều chỉnh độ chi tiết của thông tin đầu ra bằng cách thêm tham số verbosity:

python Copy
unittest.main(verbosity=2)

4. Viết bài kiểm tra với doctest

Ví dụ về cách sử dụng doctest trong mã:

python Copy
def add(a, b):
    """
    Trả về tổng của hai số.
    >>> add(1, 2)
    3
    >>> add(-1, 1)
    0
    """
    return a + b

Để chạy doctest, bạn có thể thêm đoạn mã sau vào cuối file:

python Copy
if __name__ == "__main__":
    import doctest
    doctest.testmod()

5. Thực hành tốt nhất

  • Viết bài kiểm tra cho từng tình huống: Đảm bảo rằng bạn đã bao phủ tất cả các trường hợp có thể xảy ra, bao gồm cả các trường hợp biên.
  • Sử dụng docstring để mô tả: Giúp người đọc hiểu rõ hơn về mục đích của hàm và cách thức hoạt động của nó.
  • Chạy bài kiểm tra thường xuyên: Điều này giúp phát hiện lỗi sớm và đảm bảo rằng mã của bạn luôn hoạt động như mong đợi.

6. Những cạm bẫy thường gặp

  • Quá phụ thuộc vào các bài kiểm tra: Không nên chỉ dựa vào các bài kiểm tra mà không có sự kiểm tra thủ công.
  • Không cập nhật bài kiểm tra khi thay đổi mã: Nếu bạn thay đổi logic của hàm, hãy nhớ cập nhật các bài kiểm tra tương ứng.

7. Mẹo hiệu suất

  • Sử dụng setUp()tearDown(): Để thiết lập và dọn dẹp môi trường kiểm thử. Điều này giúp giảm thiểu mã trùng lặp và dễ dàng quản lý hơn.
  • Chạy kiểm thử song song: Sử dụng thư viện như pytest để chạy các bài kiểm tra song song, giúp tiết kiệm thời gian.

8. Giải quyết sự cố

Trong quá trình viết và chạy các bài kiểm tra, bạn có thể gặp một số vấn đề như không tìm thấy hàm hoặc lỗi logic. Hãy kiểm tra lại:

  • Đường dẫn import có đúng không?
  • Các tham số đầu vào có chính xác không?

9. Kết luận

Việc viết và tổ chức các bài kiểm tra đơn vị là rất quan trọng trong phát triển phần mềm. Sử dụng unittestdoctest sẽ giúp bạn kiểm soát chất lượng mã tốt hơn. Hãy bắt đầu viết bài kiểm tra cho mã của bạn ngay hôm nay để đảm bảo rằng mọi thứ hoạt động đúng cách.

10. Câu hỏi thường gặp

Q1: Tại sao cần viết unit test?
A1: Unit test giúp phát hiện lỗi sớm và đảm bảo rằng mã của bạn hoạt động như mong đợi.

Q2: Sự khác biệt giữa unittest và doctest là gì?
A2: unittest là một framework kiểm thử hoàn chỉnh, trong khi doctest cho phép viết kiểm thử ngay trong docstring của mã.

Q3: Làm thế nào để chạy các bài kiểm tra tự động?
A3: Bạn có thể sử dụng các công cụ CI/CD để tự động chạy bài kiểm tra mỗi khi có thay đổi trong mã.

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào