Chuyển đến nội dung chính

Hướng dẫn Unit Testing trong Python

Tìm hiểu unit testing là gì, vì sao quan trọng và cách bạn có thể triển khai bằng Python.
Đã cập nhật 5 thg 10, 2026  · 10 phút đọc

Khám phá cùng AI

ChatGPTClaudePerplexity

Unit testing là một phương pháp kiểm thử phần mềm, trong đó các đơn vị riêng lẻ của mã nguồn được đưa vào nhiều bài kiểm tra khác nhau để xác định chúng có phù hợp để sử dụng hay không. Nó giúp xác định và khẳng định chất lượng mã của bạn.

Thông thường, khi quá trình phát triển hoàn tất, nhà phát triển sẽ mã hóa các tiêu chí, hoặc các kết quả được biết là có tính thực tiễn và hữu ích, vào script kiểm thử để xác minh độ đúng đắn của một đơn vị cụ thể. Trong quá trình thực thi các ca kiểm thử, nhiều framework sẽ ghi lại các bài kiểm tra không đạt bất kỳ tiêu chí nào và báo cáo chúng trong phần tóm tắt.

Các nhà phát triển được kỳ vọng sẽ viết các script kiểm thử tự động, nhằm đảm bảo mỗi phần hay mỗi đơn vị đều đáp ứng thiết kế và hoạt động như mong đợi.

Kiểm thử đơn vị trong Python

Việc viết kiểm thử thủ công cho mã của bạn chắc chắn là tẻ nhạt và tốn thời gian, nhưng framework kiểm thử đơn vị tích hợp sẵn của Python đã giúp mọi thứ dễ dàng hơn nhiều.

Framework kiểm thử đơn vị trong Python có tên là unittest và đi kèm sẵn với Python.

Kiểm thử đơn vị giúp mã của bạn sẵn sàng cho tương lai vì bạn dự đoán các trường hợp mã có thể thất bại hoặc sinh lỗi. Dù bạn không thể dự đoán tất cả, bạn vẫn xử lý được phần lớn trường hợp.

Một đơn vị có thể được phân loại theo nhiều dạng:

  • Cả một mô-đun,
  • Một hàm riêng lẻ,
  • Một giao diện hoàn chỉnh như một lớp hoặc một phương thức.

Cách tốt nhất để viết kiểm thử đơn vị cho mã của bạn là bắt đầu từ đơn vị nhỏ nhất có thể kiểm thử, sau đó chuyển sang các đơn vị khác và xem đơn vị nhỏ nhất đó tương tác với các đơn vị khác như thế nào, bằng cách này bạn có thể xây dựng bộ kiểm thử đơn vị toàn diện cho ứng dụng của mình.

Framework kiểm thử đơn vị của Python lấy cảm hứng từ JUnit của Java và có các tính năng tương tự như những framework kiểm thử đơn vị chính trong các ngôn ngữ khác. Framework kiểm thử đơn vị của Python cung cấp nhiều tính năng, bao gồm:

  • Tự động hóa kiểm thử
  • Chia sẻ mã thiết lập và kết thúc cho các bài kiểm tra
  • Gộp các bài kiểm tra thành bộ sưu tập
  • Tính độc lập của các bài kiểm tra với framework báo cáo

Bây giờ hãy lấy một ví dụ và hiểu vì sao bạn cần kiểm thử đơn vị cho mã của mình.

Bắt đầu với Python unittest

Dưới đây, chúng tôi liệt kê các bước bạn cần sử dụng framework unittest của Python

Tạo hàm tính thể tích hình lập phương

Hãy viết đoạn mã để tính thể tích hình lập phương trong Python

def cuboid_volume(l):
    return (l*l*l)
length = [2,1.1, -2.5, 2j, 'two']
for i in range(len(length)):
    print ("The volume of cuboid:",cuboid_volume(length[i]))
The volume of cuboid: 8
The volume of cuboid: 1.3310000000000004
The volume of cuboid: -15.625
The volume of cuboid: (-0-8j)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-67e1c37a435f> in <module>
      1 for i in range(len(length)):
----> 2     print ("The volume of cuboid:",cuboid_volume(length[i]))
<ipython-input-2-f50464fd88da> in cuboid_volume(l)
      1 def cuboid_volume(l):
----> 2     return (l*l*l)
TypeError: can't multiply sequence by non-int of type 'str'

Phân tích kết quả

Kết quả trên sẽ giúp bạn có trực giác về tầm quan trọng của việc có kiểm thử đơn vị cho mã của mình. Có ba điều chắc chắn không đúng trong đoạn mã trên:

  • Thứ nhất, thể tích hình hộp chữ nhật lại âm,
  • Thứ hai, thể tích là một số phức,
  • Cuối cùng, mã dẫn đến TypeError vì bạn không thể nhân một chuỗi, vốn không phải số nguyên.

Vấn đề thứ ba may mắn đã gây lỗi, còn vấn đề thứ nhất & thứ hai vẫn cho kết quả dù thể tích của hình hộp chữ nhật không thể âm hay là số phức.

Các bài kiểm thử đơn vị thường được viết thành mã riêng ở một tệp khác, và có thể có các quy ước đặt tên khác nhau mà bạn có thể theo. Bạn có thể đặt tên tệp kiểm thử đơn vị là tên mã/đơn vị + test ngăn cách bằng dấu gạch dưới hoặc test + tên mã/đơn vị ngăn cách bằng dấu gạch dưới.

Ví dụ, giả sử tên tệp mã trên là cuboid_volume.py, thì tên tệp kiểm thử đơn vị của bạn có thể là cuboid_volume_test.py

Không dài dòng nữa, hãy viết kiểm thử đơn vị cho đoạn mã trên.

Sử dụng assertAlmostEqual

Đầu tiên, hãy tạo một tệp python tên volume_cuboid.py, chứa mã tính thể tích và tệp thứ hai tên test_volume_cuboid.py, chứa mã kiểm thử đơn vị.

import unittest

Lớp TestCuboid kế thừa từ mô-đun unittest, và trong lớp này, bạn sẽ định nghĩa nhiều phương thức mà bạn muốn bài kiểm thử đơn vị kiểm tra với hàm cuboid_volume của bạn.

Hàm đầu tiên bạn sẽ định nghĩa là test_volume, hàm này sẽ kiểm tra xem đầu ra mà cuboid_volume trả về có bằng với điều bạn kỳ vọng không. Để làm điều này, bạn sẽ dùng phương thức assertAlmostEqual.

Kiểm thử 1

class TestCuboid(unittest.TestCase):
    def test_volume(self):
        self.assertAlmostEqual(cuboid_volume(2),8)
        self.assertAlmostEqual(cuboid_volume(1),1)
        self.assertAlmostEqual(cuboid_volume(0),0)
        self.assertAlmostEqual(cuboid_volume(5.5),166.375)

code 1

code 2

Hãy chạy script trên. Bạn sẽ chạy mô-đun unittest như một script bằng cách chỉ định -m khi chạy.

!python -m unittest test_volume_cuboid.py

Kết quả:

.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK

Tuyệt! Bạn đã chạy thành công bài kiểm thử đơn vị đầu tiên.

Bài kiểm thử chạy thành công và trả về OK, nghĩa là hàm cuboid_volume hoạt động như bạn kỳ vọng.

Kiểm thử 2

Hãy xem điều gì xảy ra khi một trong các phương thức assertAlmostEqual thất bại.

code 3

Lưu ý câu lệnh assert cuối cùng đã được chỉnh sửa.

!python -m unittest test_volume_cuboid.py

Kết quả:

F
======================================================================
FAIL: test_volume (test_volume_cuboid.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\hda3kor\Documents\Unit_Testing_Python\test_volume_cuboid.py", line 15, in test_volume
    self.assertAlmostEqual(cuboid_volume(5.5),0)
AssertionError: 166.375 != 0 within 7 places (166.375 difference)
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)

Từ kết quả trên, bạn có thể thấy câu lệnh assert cuối cùng gây ra AssertionError, do đó bài kiểm thử đơn vị thất bại. Mô-đun kiểm thử đơn vị của Python hiển thị lý do thất bại cùng với số lượng lỗi của mã.

Sử dụng assertRaises

Bây giờ hãy khám phá một phương thức assert khác, tức assertRaises, phương thức này sẽ giúp bạn biết liệu hàm cuboid_volume xử lý giá trị đầu vào có đúng không.

Giả sử bạn muốn kiểm tra liệu hàm cuboid_volume có xử lý kiểu hoặc lớp của đầu vào hay không; ví dụ, nếu bạn truyền một chuỗi làm đầu vào, liệu nó sẽ xử lý đầu vào đó bằng ngoại lệ hoặc bằng điều kiện if, vì chiều dài của hình hộp chữ nhật không bao giờ là một chuỗi.

code 4

!python -m unittest test_volume_cuboid.py

Kết quả:

F.
======================================================================
FAIL: test_input_value (test_volume_cuboid.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\hda3kor\Documents\Unit_Testing_Python\test_volume_cuboid.py", line 17, in test_input_value
    self.assertRaises(TypeError, cuboid_volume, True)
AssertionError: TypeError not raised by cuboid_volume
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)

Tuyệt! Vậy từ kết quả trên, rõ ràng là mã của bạn volume_cuboid.py chưa xử lý đúng đầu vào được truyền vào.

Chỉnh sửa hàm tính lập phương

Hãy thêm một điều kiện trong volume_cuboid.py để kiểm tra xem đầu vào hoặc chiều dài của hình hộp chữ nhật có phải boolean hoặc chuỗi không và đưa ra lỗi.

code 5

!python -m unittest test_volume_cuboid.py

Kết quả:

..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK

Chạy script kiểm thử Python trong Jupyter lab

Giờ hãy chạy script kiểm thử trong jupyter lab. Để làm được điều này, trước tiên bạn sẽ định nghĩa script kiểm thử trong jupyter lab như bên dưới.

# -*- coding: utf-8 -*-
"""
Created on Sat Apr 25 20:16:58 2020
@author: Aditya
"""
from volume_cuboid import *
import unittest
class TestCuboid(unittest.TestCase):
    def test_volume(self):
        self.assertAlmostEqual(cuboid_volume(2),8)
        self.assertAlmostEqual(cuboid_volume(1),1)
        self.assertAlmostEqual(cuboid_volume(0),1)
    def test_input_value(self):
        self.assertRaises(TypeError, cuboid_volume, True)

Sau đó, bạn sẽ dùng phương thức unittest.main() để chạy script kiểm thử, bạn có thể truyền nhiều tham số cho phương thức dưới đây, trong đó có verbosity level.

Hãy thử các mức độ chi tiết khác nhau và xem chúng thay đổi mô tả kết quả như thế nào.

Verbosity 0

unittest.main(argv=[''],verbosity=0, exit=False)
Output:
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
<unittest.main.TestProgram at 0x1de02774348>

Verbosity 1

unittest.main(argv=[''],verbosity=1, exit=False)
Output:
..
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
<unittest.main.TestProgram at 0x1de027a1cc8>

Verbosity 2

unittest.main(argv=[''],verbosity=2, exit=False)
Output:
test_input_value (__main__.TestCuboid) ... ok
test_volume (__main__.TestCuboid) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
<unittest.main.TestProgram at 0x1de027a8308>

Hình dung AssertionError

Cuối cùng, hãy sửa câu assertAlmostEqual cuối trong phương thức test_volume và phân tích cách mức độ chi tiết 2 hiển thị lỗi của phương thức.

# -*- coding: utf-8 -*-
"""
Created on Sat Apr 25 20:16:58 2020
@author: Aditya
"""
from volume_cuboid import *
import unittest
class TestCuboid(unittest.TestCase):
    def test_volume(self):
        self.assertAlmostEqual(cuboid_volume(2),8)
        self.assertAlmostEqual(cuboid_volume(1),1)
        self.assertAlmostEqual(cuboid_volume(0),1)
    def test_input_value(self):
        self.assertRaises(TypeError, cuboid_volume, True)
unittest.main(argv=[''],verbosity=2, exit=False)

Kết quả:

test_input_value (__main__.TestCuboid) ... ok
test_volume (__main__.TestCuboid) ... FAIL
======================================================================
FAIL: test_volume (__main__.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython-input-28-46ad33b909ee>", line 14, in test_volume
    self.assertAlmostEqual(cuboid_volume(0),1)
AssertionError: 0 != 1 within 7 places (1 difference)
----------------------------------------------------------------------
Ran 2 tests in 0.003s
FAILED (failures=1)
<unittest.main.TestProgram at 0x1de027b5448>

Tóm tắt

Từ các kết quả trên, có thể rút ra những kết luận sau:

  • Verbosity mức 0 chỉ hiển thị số lượng bài kiểm tra đã chạy, tức 2 bài, cùng thời gian chạy,
  • Verbosity mức 1 thêm hai dấu chấm .. biểu thị hai bài kiểm tra đã được thực thi,
  • Verbosity mức 2 hiển thị chi tiết tên phương thức đã chạy cùng trạng thái OK hoặc FAIL.

Các phương thức Assert có sẵn trong unittest

Có rất nhiều phương thức assert trong mô-đun kiểm thử đơn vị của Python mà bạn có thể tận dụng cho mục đích kiểm thử.

Các phương thức assert thường dùng

Các phương thức assert thường dùng

Nguồn: tài liệu unittest

 Kiểm tra sản sinh

Bằng cách dùng các phương thức sau, bạn có thể kiểm tra việc sinh ra ngoại lệ, cảnh báo và thông điệp log.

Kiểm tra sản sinh

Nguồn: tài liệu unittest

 Các phương thức theo tác vụ

Các phương thức theo tác vụ

Nguồn: tài liệu unittest

 

Để biết chi tiết về các phương thức assert, hãy xem tài liệu chính thức của Python.

Bạn cũng có thể tìm hiểu về chúng với sự trợ giúp của mô-đun Pydoc, tương tự như hàm help trong Python. Minh họa cách bạn có thể dùng mô-đun Pydoc để đọc tài liệu của phương thức assertCountEqual được hiển thị dưới đây.

!python -m pydoc unittest.TestCase.assertCountEqual

Kết quả:

Help on function assertCountEqual in unittest.TestCase:
unittest.TestCase.assertCountEqual = assertCountEqual(self, first, second, msg=None)
    An unordered sequence comparison asserting that the same elements,
    regardless of order.  If the same element occurs more than once,
    it verifies that the elements occur the same number of times.
        self.assertEqual(Counter(list(first)),
                         Counter(list(second)))
     Example:
        - [0, 1, 1] and [1, 0, 1] compare equal.
        - [0, 0, 1] and [0, 1] compare unequal.

Kết luận

Hướng dẫn này là phần giới thiệu cơ bản về kiểm thử đơn vị trong Python và tầm quan trọng của nó đối với nhà phát triển. Một bài tập hay cho bạn là viết một mô-đun kiểm thử đơn vị cho bất kỳ dự án trước đây nào của bạn. Điều này sẽ giúp bạn có trải nghiệm thực tế tốt với việc viết kiểm thử đơn vị. Ngoài ra, hãy thử khám phá các phương thức Assert còn lại. Bạn có thể đọc thêm về kiểm thử đơn vị với hướng dẫn Pytest của chúng tôi. 

Nếu bạn mới bắt đầu với Python và muốn học thêm, hãy tham gia khóa học Nhập môn Khoa học Dữ liệu với Python.


Abid Ali Awan's photo
Author
Abid Ali Awan
LinkedIn
Twitter

Là một nhà khoa học dữ liệu được chứng nhận, tôi đam mê tận dụng công nghệ tiên tiến để tạo ra các ứng dụng học máy đổi mới. Với nền tảng vững chắc về nhận dạng giọng nói, phân tích và báo cáo dữ liệu, MLOps, AI hội thoại và NLP, tôi đã rèn giũa kỹ năng phát triển các hệ thống thông minh có thể tạo ra tác động thực sự. Bên cạnh chuyên môn kỹ thuật, tôi cũng là một người truyền đạt tốt, có khả năng chắt lọc các khái niệm phức tạp thành ngôn ngữ rõ ràng, súc tích. Nhờ đó, tôi trở thành một blogger được nhiều người quan tâm trong lĩnh vực khoa học dữ liệu, chia sẻ góc nhìn và kinh nghiệm với cộng đồng các chuyên gia dữ liệu ngày càng lớn. Hiện tại, tôi tập trung vào sáng tạo và biên tập nội dung, làm việc với các mô hình ngôn ngữ lớn để phát triển nội dung mạnh mẽ và hấp dẫn, giúp doanh nghiệp và cá nhân tận dụng tối đa dữ liệu của mình.

Chủ đề
Python

Tìm hiểu thêm về Python với các khóa học này!

Khóa học

Nhập môn Python

4 giờ
7.1M
Nắm vững phân tích dữ liệu với Python chỉ trong 4 giờ. Khóa học online này giúp bạn làm quen với giao diện Python và các thư viện phổ biến.
Xem chi tiếtRight Arrow
Bắt Đầu Khóa Học
Xem thêmRight Arrow
Liên quan

blog

Claude Opus 4.6: Tính năng, Điểm chuẩn, Bài kiểm tra thực hành và hơn thế nữa

Mô hình mới nhất của Anthropic dẫn đầu ở mã hóa tác tử và lập luận phức tạp. Thêm vào đó, nó có cửa sổ ngữ cảnh 1M.
Matt Crabtree's photo

Matt Crabtree

10 phút

Xem ThêmXem Thêm