HomeLập trìnhPythonCách viết bài...

Cách viết bài kiểm tra đơn vị cho các hàm Python


Hướng dẫn này sẽ hướng dẫn bạn cách viết bài kiểm tra đơn vị cho các hàm Python. Nhưng tại sao bạn nên xem xét việc viết bài kiểm tra đơn vị?

Chà, khi làm việc trong một dự án lớn, bạn sẽ thường phải cập nhật một số mô-đun nhất định và mã cấu trúc lại khi cần. Nhưng những thay đổi như vậy có thể gây ra hậu quả ngoài ý muốn đối với các mô-đun khác sử dụng mô-đun được cập nhật bên trong chúng. Điều này đôi khi có thể phá vỡ chức năng hiện có.

Là nhà phát triển, bạn nên kiểm tra mã của mình để đảm bảo rằng tất cả các mô-đun trong ứng dụng đều hoạt động như dự định. Kiểm tra đơn vị cho phép bạn kiểm tra xem các đơn vị mã nhỏ bị cô lập có hoạt động chính xác hay không và cho phép bạn khắc phục sự không nhất quán phát sinh từ các bản cập nhật và tái cấu trúc.

Hướng dẫn này sẽ giúp bạn bắt đầu thử nghiệm đơn vị trong Python. Bạn sẽ học cách sử dụng Python tích hợp sẵn unittest mô-đun để thiết lập và chạy thử nghiệm đơn vị và viết các trường hợp thử nghiệm để kiểm tra các chức năng của Python. Bạn cũng sẽ học cách kiểm tra các chức năng đưa ra ngoại lệ.

Bắt đầu nào!

Thử nghiệm bằng Python – Những bước đầu tiên

Chúng ta sẽ bắt đầu bằng cách định nghĩa một hàm Python và viết các bài kiểm tra đơn vị để kiểm tra xem nó có hoạt động như mong đợi hay không. Để tập trung vào cách thiết lập các bài kiểm tra đơn vị, chúng ta sẽ xem xét một chức năng đơn giản is_prime()nhận vào một số và kiểm tra xem nó có phải là số nguyên tố hay không.

import math

def is_prime(num):
    '''Check if num is prime or not.'''
    for i in range(2,int(math.sqrt(num))+1):
        if num%i==0:
            return False
    return True

Hãy bắt đầu REPL Python, gọi hàm is_prime() với các đối số và xác minh kết quả.

>>> from prime_number import is_prime
>>> is_prime(3)
True
>>> is_prime(5)
True
>>> is_prime(12)
False
>>> is_prime(8)
False
>>> assert is_prime(7) == True

Bạn cũng có thể sử dụng assert tuyên bố để xác minh rằng is_prime() trả về giá trị Boolean dự kiến, như được hiển thị ở trên. Nếu giá trị trả về từ hàm khác với giá trị Boolean dự kiến, một AssertionError được nuôi dưỡng.

loại này Kiểm tra bằng taykhông hiệu quả khi bạn muốn kiểm tra toàn diện hàm của mình để tìm danh sách đối số lớn hơn nhiều. Bạn có thể muốn thiết lập thử nghiệm tự động để chạy và xác thực đầu ra của chức năng dựa trên các trường hợp thử nghiệm được xác định trong bộ thử nghiệm.

Đọc thêm  strftime – Chuỗi dấu thời gian DateTime của Python

Cách sử dụng Python unittest mô-đun

Python vận chuyển với unittest mô-đun cho phép bạn định cấu hình kiểm tra tự động cho các chức năng và lớp trong ứng dụng của mình. Quy trình chung để thiết lập các bài kiểm tra đơn vị trong Python như sau:

# <module-name>.py

import unittest
from <module> import <function_to_test>
# all entries within <> are placeholders

class TestClass(unittest.TestCase):
	def test_<name_1>(self):
		# check function_to_test

	def test_<name_2>(self):
		# check function_to_test
	:
	:
	:

	def test_<name_n>(self):
		# check function_to_test

Đoạn mã trên <module-name>.py làm như sau:

  • Nhập tích hợp sẵn của Python unittest mô-đun.
  • Nhập hàm Python để kiểm tra, <function_to_test> từ mô-đun mà nó được định nghĩa, <module>.
  • Tạo một lớp kiểm tra (TestClass) kế thừa từ unittest.TestCase lớp.
  • Mỗi bài kiểm tra sẽ được chạy phải được định nghĩa là các phương thức bên trong lớp kiểm tra.
  • 💡 Ghi chú: Cho unittest mô-đun để xác định các phương thức này dưới dạng thử nghiệm và chạy chúng, tên của các phương thức này phải bắt đầu bằng test_.
  • Các TestCase lớp học trong unittest mô-đun cung cấp các phương thức xác nhận hữu ích để kiểm tra xem hàm được kiểm tra có trả về các giá trị mong đợi hay không.

Các phương thức xác nhận phổ biến nhất được liệt kê bên dưới và chúng tôi sẽ sử dụng một số trong số chúng trong hướng dẫn này.

Phương pháp Sự miêu tả
assertEqual(expected_value,actual_value) khẳng định rằng expected_value == actual_value
assertTrue(result) khẳng định rằng bool(result)True
assertFalse(result) khẳng định rằng bool(result)False
assertRaises(exception, function, *args, **kwargs) khẳng định rằng function(*args, **kwargs) nâng cao exception

📑 Để biết danh sách đầy đủ các phương thức xác nhận, hãy tham khảo tài liệu unittest.

Để chạy các thử nghiệm này, chúng ta nên chạy unittest làm mô-đun chính, sử dụng lệnh sau:

$ python -m unittest <module-name>.py

Chúng ta có thể thêm if __name__=='__main__' có điều kiện để chạy unittest như mô-đun chính.

if __name__=='__main__':
	unittest.main()

Việc thêm điều kiện ở trên sẽ cho phép chúng tôi chạy thử nghiệm bằng cách chạy trực tiếp mô-đun Python chứa các thử nghiệm.

$ python <module-name>.py

Cách xác định các trường hợp thử nghiệm cho các hàm Python

unittesting-101

Trong phần này, chúng ta sẽ viết các bài kiểm tra đơn vị cho is_prime() sử dụng cú pháp chúng ta đã học.

Để kiểm tra is_prime() hàm trả về Boolean, chúng ta có thể sử dụng assertTrue()assertFalse() các phương pháp. Chúng tôi xác định bốn phương pháp kiểm tra trong TestPrime lớp kế thừa từ unittest.TestCase.

import unittest
# import the is_prime function
from prime_number import is_prime
class TestPrime(unittest.TestCase):
    def test_two(self):
        self.assertTrue(is_prime(2))
    def test_five(self):
    	self.assertTrue(is_prime(5))
    def test_nine(self):
    	self.assertFalse(is_prime(9))
    def test_eleven(self):
    	self.assertTrue(is_prime(11))
if __name__=='__main__':
	unittest.main()
$ python test_prime.py

Trong đầu ra bên dưới, ‘.’ chỉ ra một thử nghiệm thành công.

Output
....
----------------------------------------------------------------------
Ran 4 tests in 0.001s
OK

Trong đoạn mã trên, có bốn phương pháp kiểm tra, mỗi phương pháp kiểm tra một đầu vào cụ thể. Thay vào đó, bạn có thể xác định một phương thức kiểm tra duy nhất để xác nhận xem đầu ra có đúng hay không, cho cả bốn đầu vào.

import unittest
from prime_number import is_prime
class TestPrime(unittest.TestCase):
	def test_prime_not_prime(self):
        self.assertTrue(is_prime(2))
        self.assertTrue(is_prime(5))
        self.assertFalse(is_prime(9))
        self.assertTrue(is_prime(11))

Khi chạy test_prime mô-đun, chúng tôi thấy rằng một thử nghiệm đã được chạy thành công. Nếu bất kỳ phương thức xác nhận nào đưa ra một AssertionErrorsau đó thử nghiệm thất bại.

$ python test_prime.py
Output
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
OK

Cách viết bài kiểm tra đơn vị để kiểm tra ngoại lệ

Trong phần trước, chúng ta đã thử nghiệm is_prime() chức năng với các số nguyên tố và không phải là số nguyên tố làm đầu vào. Cụ thể, các đầu vào đều là số nguyên dương.

Đọc thêm  Cách sử dụng đối tượng timedelta trong Python để làm việc với ngày tháng

Chúng tôi chưa thực thi rằng các đối số trong hàm gọi đến is_prime() phải là số nguyên dương. Bạn có thể sử dụng gợi ý loại để thực thi các loại hoặc đưa ra ngoại lệ cho các đầu vào không hợp lệ.

Trong thử nghiệm các is_prime() chức năng, chúng tôi chưa tính đến những điều sau:

  • Đối với một đối số dấu phẩy động, is_prime() chức năng vẫn sẽ chạy và trở lại True hoặc Falseđó là không chính xác.
  • Đối với các đối số thuộc các loại khác, chẳng hạn, chuỗi ‘năm’ thay vì số 5, hàm sẽ đưa ra một LoạiLỗi.
  • Nếu đối số là một số nguyên âm, thì math.sqrt() chức năng ném một Giá trịError. Bình phương của mọi số thực (dương, âm hoặc 0) luôn không âm. Vì vậy, căn bậc hai chỉ được xác định cho các số không âm.

Hãy xác minh những điều trên bằng cách chạy một số ví dụ trong REPL của Python.

>>> from prime_number import is_prime

>>> is_prime('five')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/bala/unit-test-1/prime_number.py", line 5, in is_prime
for i in range(2,int(math.sqrt(num))+1):
TypeError: must be real number, not str

>>> is_prime(-10)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/bala/unit-test-1/prime_number.py", line 5, in is_prime
for i in range(2,int(math.sqrt(num))+1):
ValueError: math domain error

>>> is_prime(2.5)
True

Cách tăng ngoại lệ cho đầu vào không hợp lệ

Để giải quyết vấn đề trên, chúng tôi sẽ xác thực giá trị được sử dụng trong lệnh gọi hàm cho num và nâng cao ngoại lệ khi cần thiết.

  • Kiểm tra nếu num là một số nguyên. Nếu có, tiến hành kiểm tra tiếp theo. Khác, nâng cao một TypeError ngoại lệ.
  • Kiểm tra nếu num là một số nguyên âm. Nếu có, hãy tăng một ValueError ngoại lệ.

Sửa đổi định nghĩa hàm để xác thực đầu vào và đưa ra các ngoại lệ, chúng tôi có:

import math
def is_prime(num):
    '''Check if num is prime or not.'''
    # raise TypeError for invalid input type
    if type(num) != int:
        raise TypeError('num is of invalid type')
    # raise ValueError for invalid input value
    if num < 0:
        raise ValueError('Check the value of num; is num a non-negative integer?')
    # for valid input, proceed to check if num is prime
    for i in range(2,int(math.sqrt(num))+1):
        if num%i==0:
        return False
    return True

Bây giờ chúng ta đã sửa đổi chức năng để tăng ValueError và TypeError đối với các đầu vào không hợp lệ, bước tiếp theo là kiểm tra xem các ngoại lệ này có được đưa ra hay không.

Đọc thêm  Sắp xếp danh sách Python – Cách sắp xếp danh sách trong Python

Làm thế nào để sử dụng assertRaises() Phương pháp kiểm tra ngoại lệ

kiểm tra ngoại lệ

Trong định nghĩa của TestPrime lớp, hãy thêm các phương thức để kiểm tra xem các ngoại lệ có được nêu ra hay không.

Chúng tôi xác định test_typeerror_1()test_typeerror_2() phương pháp để kiểm tra nếu TypeError ngoại lệ được nâng lên và test_valueerror() phương pháp để kiểm tra nếu ValueError ngoại lệ được nâng lên.

📌 Để gọi assertRaises() phương pháp, chúng ta có thể sử dụng cú pháp chung sau:

def test_exception(self):
    self.assertRaises(exception-name,function-name,args)

Chúng ta cũng có thể sử dụng cú pháp sau bằng trình quản lý ngữ cảnh (chúng ta sẽ sử dụng cú pháp này trong ví dụ này):

def test_exception(self):
    with self.assertRaises(exception-name):
        function-name(args)

Thêm các phương pháp kiểm tra để kiểm tra các ngoại lệ, chúng tôi có:

import unittest
from prime_number import is_prime
class TestPrime(unittest.TestCase):
    def test_prime_not_prime(self):
        self.assertTrue(is_prime(2))
        self.assertTrue(is_prime(5))
        self.assertFalse(is_prime(9))
        self.assertTrue(is_prime(11))
    def test_typeerror_1(self):
        with self.assertRaises(TypeError):
        	is_prime(6.5)
    def test_typeerror_2(self):
        with self.assertRaises(TypeError):
        	is_prime('five')
    def test_valueerror(self):
        with self.assertRaises(ValueError):
        	is_prime(-4)
            
if __name__=='__main__':
	unittest.main()

Hãy chạy test_prime mô-đun và quan sát đầu ra:

$ python test_prime.py
Output
....
----------------------------------------------------------------------
Ran 4 tests in 0.002s
OK

Trong các ví dụ chúng tôi đã mã hóa cho đến nay, tất cả các thử nghiệm đều thành công. Hãy sửa đổi một trong các phương pháp, giả sử, test_typeerror_2()theo sau:

def test_typeerror_2(self):
    with self.assertRaises(TypeError):
    	is_prime(5)

Chúng tôi gọi chức năng is_prime() với số 5 làm đối số. Ở đây, 5 là đầu vào hợp lệ mà hàm trả về True. Do đó, chức năng không tăng TypeError. Khi chúng tôi chạy lại các bài kiểm tra, chúng tôi sẽ thấy rằng có một bài kiểm tra không thành công.

$ python test_prime.py
Output

..F.
======================================================================
FAIL: test_typeerror_2 (__main__.TestPrime)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_prime.py", line 17, in test_typeerror_2
is_prime(5)
AssertionError: TypeError not raised
----------------------------------------------------------------------
Ran 4 tests in 0.003s
FAILED (failures=1)

Phần kết luận

Cảm ơn bạn đã đọc đến đây! 😄 Tôi hy vọng hướng dẫn này đã giúp bạn hiểu những kiến ​​thức cơ bản về kiểm thử đơn vị trong Python.

Bạn đã học cách thiết lập các bài kiểm tra để kiểm tra xem một chức năng có hoạt động như mong đợi hay đưa ra một ngoại lệ hay không—tất cả đều sử dụng công cụ tích hợp sẵn của Python unittest mô-đun.

Tiếp tục viết mã và hẹn gặp lại bạn trong phần hướng dẫn tiếp theo!👩🏽‍💻



Zik.vn – Biên dịch & Biên soạn Lại

spot_img

Create a website from scratch

Just drag and drop elements in a page to get started with Newspaper Theme.

Buy Now ⟶

Bài viết liên quang

DMCA.com Protection Status