HomeLập trìnhPythonGiới thiệu về...

Giới thiệu về kiểm tra đơn vị trong Python


Bạn vừa viết xong một đoạn mã và đang băn khoăn không biết phải làm gì. Bạn sẽ gửi yêu cầu kéo và yêu cầu đồng đội của mình xem lại mã chứ? Hay bạn sẽ kiểm tra mã theo cách thủ công?

Bạn nên làm cả hai điều này, nhưng với một bước bổ sung: bạn cần kiểm tra đơn vị mã của mình để đảm bảo rằng mã hoạt động như dự kiến.

Các bài kiểm tra đơn vị có thể đạt hoặc không đạt và điều đó làm cho chúng trở thành một kỹ thuật tuyệt vời để kiểm tra mã của bạn. Trong hướng dẫn này, tôi sẽ trình bày cách viết bài kiểm tra đơn vị bằng Python và bạn sẽ thấy việc thực hiện chúng trong dự án của riêng bạn dễ dàng như thế nào.

Cách tốt nhất bạn có thể hiểu về kiểm thử là nếu bạn thực hành nó. Với mục đích đó, trong một tệp có tên name_function.py, tôi sẽ viết một hàm đơn giản lấy họ và tên, đồng thời trả về một tên đầy đủ:

#Generate a formatted full name
def formatted_name(first_name, last_name):
   full_name = first_name + ' ' + last_name
   return full_name.title()

Hàm formatted_name() lấy tên và họ rồi kết hợp chúng với khoảng trắng ở giữa để tạo thành tên đầy đủ. Sau đó nó viết hoa chữ cái đầu tiên của mỗi từ. Để kiểm tra xem mã này có hoạt động không, bạn cần viết một số mã sử dụng chức năng này. Trong names.py, tôi sẽ viết một số mã đơn giản cho phép người dùng nhập họ và tên của họ:

from name_function import formatted_name

print("Please enter the first and last names or enter x to E[x]it.")

while True:
   first_name = input("Please enter the first name: ")
   if first_name == "x":
       print("Good bye.")
       break

   last_name = input("Please enter the last name: ")
   if last_name == "x":
       print("Good bye.")
       break

   result = formatted_name(first_name, last_name)
   print("Formatted name is: " + result + ".")

Mã này nhập formatted_name() từ name_function.py và khi chạy, cho phép người dùng nhập một loạt họ và tên, đồng thời hiển thị tên đầy đủ được định dạng.

Có một mô-đun trong thư viện chuẩn của Python có tên là unittest chứa các công cụ để kiểm tra mã của bạn. Kiểm tra đơn vị kiểm tra xem tất cả các phần cụ thể trong hoạt động của chức năng của bạn có đúng không, điều này sẽ giúp việc tích hợp chúng cùng với các phần khác dễ dàng hơn nhiều.

Đọc thêm  Cách tải xuống và cắt MP3 từ YouTube bằng Python

Trường hợp thử nghiệm là một tập hợp các thử nghiệm đơn vị cùng nhau chứng minh rằng một chức năng hoạt động như dự định, trong một loạt các tình huống mà chức năng đó có thể tự tìm thấy và dự kiến ​​chức năng đó sẽ xử lý. Trường hợp thử nghiệm nên xem xét tất cả các loại đầu vào có thể có mà một chức năng có thể nhận được từ người dùng và do đó nên bao gồm các thử nghiệm để thể hiện từng tình huống này.

Đây là một kịch bản điển hình để viết bài kiểm tra:

Trước tiên, bạn cần tạo một tệp thử nghiệm. Sau đó, nhập mô-đun unittest, xác định lớp thử nghiệm kế thừa từ unittest.TestCase và cuối cùng, viết một loạt phương thức để kiểm tra tất cả các trường hợp hành vi của hàm của bạn.

Có một lời giải thích từng dòng bên dưới đoạn mã sau:

import unittest
from name_function import formatted_name

class NamesTestCase(unittest.TestCase):

   def test_first_last_name(self):
       result = formatted_name("pete", "seeger")
       self.assertEqual(result, "Pete Seeger")

Đầu tiên, bạn cần nhập một unittest và chức năng bạn muốn kiểm tra, formatted_name() . Sau đó, bạn tạo một lớp, chẳng hạn như NamesTestCase, lớp này sẽ chứa các bài kiểm tra cho hàm formatted_name() của bạn. Lớp này kế thừa từ lớp unittest.TestCase.

NameTestCase chứa một phương thức duy nhất kiểm tra một phần của formatted_name() . Bạn có thể gọi phương thức này là test_first_last_name().

Hãy nhớ rằng mọi phương thức bắt đầu bằng “test_” sẽ được chạy tự động khi bạn chạy test_name_function.py.

Trong phương thức kiểm tra test_first_last_name(), bạn gọi hàm bạn muốn kiểm tra và lưu giá trị trả về. Trong ví dụ này, chúng ta sẽ gọi formatted_name() với các đối số “pete” và “seeger” và lưu kết quả vào biến kết quả.

Trong dòng cuối cùng, chúng ta sẽ sử dụng phương thức khẳng định. Phương thức khẳng định xác minh rằng kết quả bạn nhận được khớp với kết quả bạn mong muốn nhận được. Và trong trường hợp này, chúng tôi biết rằng hàm formatted_name() sẽ trả về tên đầy đủ với các chữ cái đầu tiên được viết hoa, vì vậy chúng tôi mong đợi kết quả là “Pete Seeger”. Để kiểm tra điều này, phương thức assertEqual() của unittest đang được sử dụng.

self.assertEqual(result, “Pete Seeger”)

Về cơ bản, dòng này có nghĩa là: So sánh giá trị trong biến kết quả với “Pete Seeger” và nếu chúng bằng nhau thì không sao, nhưng nếu chúng không bằng nhau thì hãy cho tôi biết.

Đọc thêm  Hàm any() và all() của Python – Được giải thích bằng các ví dụ

Khi chạy test_name_function.py, bạn sẽ nhận được thông báo OK nghĩa là bài kiểm tra đã vượt qua.

Ran 1 test in 0.001s

OK

Để cho bạn thấy một thử nghiệm thất bại trông như thế nào, tôi sẽ sửa đổi một hàm formatted_name() bằng cách đưa vào một đối số tên đệm mới.

Vì vậy, tôi sẽ viết lại hàm như thế này:

#Generate a formatted full name including a middle name
def formatted_name(first_name, last_name, middle_name):
   full_name = first_name + ' ' + middle_name + ' ' + last_name
   return full_name.title()

Phiên bản formatted_name() này sẽ hoạt động với những người có tên đệm, nhưng khi bạn kiểm tra nó, bạn sẽ thấy chức năng này bị hỏng đối với những người không có tên đệm.

Vì vậy, khi bạn chạy test_name_function.py, bạn sẽ nhận được kết quả giống như sau:

Error
Traceback (most recent call last):

File “test_name_function.py”, line 7, in test_first_last_name
    result = formatted_name(“pete”, “seeger”)

TypeError: formatted_name() missing 1 required positional argument: ‘middle_name’

Ran 1 test in 0.002s

FAILED (errors=1)

Trong đầu ra, bạn sẽ thấy thông tin cho bạn biết tất cả những gì bạn cần để biết nơi kiểm tra không thành công:

  • Mục đầu tiên trong kết quả là Lỗi cho bạn biết rằng ít nhất một thử nghiệm trong trường hợp thử nghiệm đã dẫn đến lỗi.
  • Tiếp theo, bạn sẽ thấy tệp và phương pháp xảy ra lỗi.
  • Sau đó, bạn sẽ thấy dòng xảy ra lỗi.
  • Và nó là lỗi gì vậy, trong trường hợp này là thiếu 1 đối số tên_tên_trung_gian.
  • Bạn cũng sẽ thấy số lần chạy thử nghiệm, thời gian cần thiết để hoàn thành các thử nghiệm và một thông báo văn bản thể hiện trạng thái của các thử nghiệm với số lượng lỗi đã xảy ra.

Một bài kiểm tra vượt qua có nghĩa là chức năng đang hoạt động theo những gì được mong đợi từ nó. Tuy nhiên, một bài kiểm tra trượt có nghĩa là còn nhiều niềm vui phía trước bạn.

Tôi đã thấy một số lập trình viên thích thay đổi bài kiểm tra hơn là cải thiện mã — nhưng đừng làm thế. Hãy dành thêm một chút thời gian để khắc phục sự cố, vì nó sẽ giúp bạn hiểu rõ hơn về mã và tiết kiệm thời gian về lâu dài.

Đọc thêm  không thể nhân chuỗi với kiểu không int float [Solved Python Error]

Trong ví dụ này, hàm formatted_name() của chúng ta trước tiên yêu cầu hai tham số, và bây giờ khi được viết lại, hàm này yêu cầu thêm một tham số: tên đệm. Việc thêm tên đệm vào chức năng của chúng tôi đã phá vỡ hành vi mong muốn của nó. Vì ý tưởng không phải là thay đổi các bài kiểm tra, nên giải pháp tốt nhất là đặt tên đệm tùy chọn.

Sau khi chúng tôi làm điều này, ý tưởng là làm cho các bài kiểm tra vượt qua khi sử dụng họ và tên, ví dụ như “Pete Seeger”, cũng như khi sử dụng tên, họ và tên đệm, ví dụ như “Raymond Red Reddington”. Vì vậy, hãy sửa đổi mã của formatted_name() một lần nữa:

#Generate a formatted full name including a middle name
def formatted_name(first_name, last_name, middle_name=""):
   if len(middle_name) > 0:
       full_name = first_name + ' ' + middle_name + ' ' + last_name
   else:
       full_name = first_name + ' ' + last_name
   return full_name.title()

Bây giờ chức năng sẽ hoạt động đối với các tên có và không có tên đệm.

Và để đảm bảo rằng nó vẫn hoạt động với “Pete Seeger”, hãy chạy thử nghiệm lại:

Ran 1 test in 0.001s

OK

Và đây là những gì tôi định cho bạn thấy: Thay đổi mã của bạn để phù hợp với các bài kiểm tra của bạn luôn tốt hơn so với cách khác. Bây giờ đã đến lúc thêm một thử nghiệm mới cho những cái tên có tên đệm.

Viết một phương thức mới cho lớp NamesTestCase sẽ kiểm tra tên đệm:

import unittest
from name_function import formatted_name

class NamesTestCase(unittest.TestCase):

    def test_first_last_name(self):
        result = formatted_name("pete", "seeger")
        self.assertEqual(result, "Pete Seeger")

    def test_first_last_middle_name(self):
        result = formatted_name("raymond", "reddington", "red")
        self.assertEqual(result, "Raymond Red Reddington")

Sau khi bạn chạy thử nghiệm, cả hai thử nghiệm sẽ vượt qua:

Ran 2 tests in 0.001s

OK

áo ngực!
Làm tốt!

Bạn đã viết bài kiểm tra của mình để kiểm tra xem chức năng có hoạt động hay không khi sử dụng tên có hoặc không có tên đệm. Hãy theo dõi phần 2, nơi tôi sẽ nói nhiều hơn về thử nghiệm trong Python.


Cảm ơn bạn đã đọc! Xem thêm các bài viết như thế này trên hồ sơ freeCodeCamp của tôi: https://www.freecodecamp.org/news/author/goran/ và những nội dung thú vị khác mà tôi xây dựng trên trang GitHub của mình: https://github.com/GoranAviani



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