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ả.
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 shapes
và test
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 Circle
và Square
.
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.py
và test_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 Circle
và Shape
từ các mô-đun circle
và shape
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 Square
và Shape
từ các mô-đun square
và shape
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
.