PYTHON UNIT TESTING
CÁC CHỦ ĐỀ
BÀI MỚI NHẤT
MỚI CẬP NHẬT

Thông báo: Download 4 khóa học Python từ cơ bản đến nâng cao tại đây.

Organizing Code & Running Unittest trong Python

Trong bài viết này, bạn sẽ học cách tổ chức mã kiểm thử và sử dụng các lệnh khác nhau để chạy các kiểm thử đơn vị. Việc kiểm thử đơn vị không chỉ giúp đảm bảo chất lượng mã mà còn giúp phát hiện và sửa lỗi sớm trong quá trình phát triển. Bằng cách tổ chức mã kiểm thử một cách hợp lý và sử dụng hiệu quả các công cụ kiểm thử, bạn có thể duy trì và nâng cao chất lượng của dự án phần mềm. Hãy cùng tìm hiểu cách làm thế nào để thực hiện điều này một cách hiệu quả.

test php

banquyen png
Bài viết này được đăng tại freetuts.net, không được copy dưới mọi hình thức.

Ph C6 B0 C6 A1ng 20th E1 BB A9c 20assert   20trong 20Python 20 3  png

Organizing Code trong Python

Nếu bạn chỉ có một vài mô-đun, bạn có thể tạo các mô-đun kiểm thử và đặt chúng trong cùng một thư mục.

Trong thực tế, bạn có thể có nhiều mô-đun được tổ chức thành các gói. Do đó, việc giữ mã phát triển và mã kiểm thử được tổ chức rõ ràng hơn là rất quan trọng.

Một thực hành tốt là giữ mã phát triển và mã kiểm thử trong các thư mục riêng biệt. Và bạn nên đặt mã kiểm thử trong một thư mục có tên là test để dễ nhận biết.

Bài viết này được đăng tại [free tuts .net]

Để minh họa, chúng ta sẽ tạo một dự án mẫu với cấu trúc như sau:

D:\python-unit-testing
├── shapes
│   ├── circle.py
│   ├── shape.py
│   └── square.py
└── test
    ├── test_circle.py
    ├── test_square.py
    └── __init__.py

Đầu tiên, tạo các thư mục shapestest trong thư mục dự án (python-unit-testing).

Thứ hai, tạo ba mô-đun shape.py, circle.py, và square.py và đặt chúng trong thư mục shapes.

shape.py

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area() -> float:
        pass

Lớp Shape là một lớp trừu tượng có phương thức area(). Đây là lớp cơ sở của các lớp CircleSquare.

circle.py

import math
from .shape import Shape

class Circle(Shape):
    def __init__(self, radius: float) -> None:
        if radius < 0:
            raise ValueError('The radius cannot be negative')
        self._radius = radius

    def area(self) -> float:
        return math.pi * math.pow(self._radius, 2)

Lớp Circle kế thừa từ lớp Shape. Nó triển khai phương thức area() trả về diện tích của hình tròn.

square.py

import math
from .shape import Shape

class Square(Shape):
    def __init__(self, length: float) -> None:
        if length < 0:
            raise ValueError('The length cannot be negative')
        self._length = length

    def area(self) -> float:
        return math.pow(self._length, 2)

Tương tự như lớp Circle, lớp Square có phương thức area() trả về diện tích của hình vuông.

Thứ ba, tạo các mô-đun kiểm thử test_circle.pytest_square.py và đặt chúng trong thư mục test:

test_circle.py

import unittest
import math

from shapes.circle import Circle
from shapes.shape import Shape

class TestCircle(unittest.TestCase):
    def test_circle_instance_of_shape(self):
        circle = Circle(10)
        self.assertIsInstance(circle, Shape)

    def test_create_circle_negative_radius(self):
        with self.assertRaises(ValueError):
            circle = Circle(-1)

    def test_area(self):
        circle = Circle(2.5)
        self.assertAlmostEqual(circle.area(), math.pi * 2.5 * 2.5)

Mô-đun test_circle sử dụng CircleShape từ các mô-đun circleshape trong gói shapes.

test_square.py

import unittest

from shapes.square import Square
from shapes.shape import Shape

class TestSquare(unittest.TestCase):
    def test_create_square_negative_length(self):
        with self.assertRaises(ValueError):
            square = Square(-1)

    def test_square_instance_of_shape(self):
        square = Square(10)
        self.assertIsInstance(square, Shape)

    def test_area(self):
        square = Square(10)
        area = square.area()
        self.assertEqual(area, 100)

Mô-đun test_square sử dụng các lớp SquareShape từ các mô-đun squareshape trong gói shapes.

Điều quan trọng là tạo tệp __init__.py và đặt nó trong thư mục test. Nếu không, các lệnh trong phần sau sẽ không hoạt động như mong đợi.

Running Unittest trong Python

Mô-đun unittest cung cấp nhiều cách để chạy các kiểm thử đơn vị.

​Chạy tất cả các kiểm thử

Để chạy tất cả các kiểm thử trong thư mục test, bạn thực hiện lệnh sau từ thư mục dự án (python-unit-testing):

python -m unittest discover -v

Lệnh discover là một lệnh con tìm tất cả các kiểm thử trong dự án.

Kết quả:

test_area (test_circle.TestCircle) ... ok
test_circle_instance_of_shape (test_circle.TestCircle) ... ok
test_create_circle_negative_radius (test_circle.TestCircle) ... ok
test_area (test_square.TestSquare) ... ok
test_create_square_negative_length (test_square.TestSquare) ... ok
test_square_instance_of_shape (test_square.TestSquare) ... ok

----------------------------------------------------------------------
Ran 6 tests in 0.002s

OK

Chạy một mô-đun kiểm thử

Để chạy một mô-đun kiểm thử, bạn sử dụng lệnh sau:

python -m unittest test_package.test_module -v

Ví dụ, lệnh sau chạy tất cả các kiểm thử trong mô-đun test_circle của gói test:

python -m unittest test.test_circle -v

Kết quả:

test_area (test.test_circle.TestCircle) ... ok
test_circle_instance_of_shape (test.test_circle.TestCircle) ... ok     
test_create_circle_negative_radius (test.test_circle.TestCircle) ... ok

---------------------------------------------------------------------- 
Ran 3 tests in 0.000s

OK

Chạy một lớp kiểm thử

Một mô-đun kiểm thử có thể có nhiều lớp. Để chạy một lớp kiểm thử trong một mô-đun kiểm thử, bạn sử dụng lệnh sau:

python -m unittest test_package.test_module.TestClass -v

Ví dụ, lệnh sau kiểm thử lớp TestSquare từ mô-đun test_square của gói test:

python -m unittest test.test_square.TestSquare -v

Kết quả:

test_area (test.test_square.TestSquare) ... ok
test_create_square_negative_length (test.test_square.TestSquare) ... ok
test_square_instance_of_shape (test.test_square.TestSquare) ... ok

----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK

Chạy một phương thức kiểm thử

Để chạy một phương thức kiểm thử của một lớp kiểm thử, bạn sử dụng lệnh sau:

python -m unittest test_package.test_module.TestClass.test_method -v

Ví dụ, lệnh sau kiểm thử phương thức test_area() của lớp TestCircle:

python -m unittest test.test_circle.TestCircle.test_area -v

Kết quả:

test_area (test.test_circle.TestCircle) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

Kết bài

Qua hướng dẫn này, bạn đã học được cách tổ chức mã kiểm thử và sử dụng các lệnh của mô-đun unittest trong Python để thực hiện kiểm thử đơn vị. Việc đặt mã phát triển và mã kiểm thử vào các thư mục riêng biệt, cụ thể là lưu mã kiểm thử trong thư mục test, giúp quản lý và bảo trì mã dễ dàng hơn.

Các lệnh unittest cho phép bạn linh hoạt trong việc kiểm thử, từ việc phát hiện và chạy tất cả các kiểm thử bằng lệnh python -m unittest discover -v, đến việc chạy một mô-đun kiểm thử cụ thể với python -m unittest test_package.test_module -v, hoặc chỉ chạy một lớp kiểm thử với python -m unittest test_package.test_module.TestClass -v, và thậm chí chỉ chạy một phương thức kiểm thử bằng lệnh python -m unittest test_package.test_module.TestClass.test_method -v.

Cùng chuyên mục:

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn xây dựng Command-Line Interface (CLI) bằng Quo trong Python

Hướng dẫn toàn diện về module datetime trong Python

Hướng dẫn toàn diện về module datetime trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Cách truy cập và thiết lập biến môi trường trong Python

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Lớp dữ liệu (Data Classes) trong Python với decorator @dataclass

Từ khóa yield trong Python

Từ khóa yield trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sự khác biệt giữa sort() và sorted() trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Sử dụng Poetry để quản lý dependencies trong Python

Định dạng chuỗi Strings trong Python

Định dạng chuỗi Strings trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Một tác vụ phổ biến khi làm việc với danh sách trong Python

Làm việc với các biến môi trường trong Python

Làm việc với các biến môi trường trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa set() và frozenset() trong Python

Sự khác biệt giữa iterator và iterable trong Python

Sự khác biệt giữa iterator và iterable trong Python

Cách làm việc với file tarball/tar trong Python

Cách làm việc với file tarball/tar trong Python

Chuyển đổi kiểu dữ liệu trong Python

Chuyển đổi kiểu dữ liệu trong Python

Sự khác biệt giữa toán tử == và is trong Python

Sự khác biệt giữa toán tử == và is trong Python

Làm việc với file ZIP trong Python

Làm việc với file ZIP trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Cách sử dụng ThreadPoolExecutor trong Python

Sự khác biệt giữa byte objects và string trong Python

Sự khác biệt giữa byte objects và string trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format  trong Python

Xử lý độ chính xác các hàm floor, ceil, round, trunc, format trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Cách lặp qua nhiều list với hàm zip() trong Python

Top