bởi Dmitry Rastorguev

Tôi là một nhà phát triển mới bắt đầu tự học, người có thể viết các ứng dụng đơn giản. Nhưng tôi có một lời thú nhận để thực hiện. Tôi không thể nhớ mọi thứ được kết nối với nhau như thế nào trong đầu.
Tình trạng này sẽ trở nên tồi tệ hơn nếu tôi quay lại mã mà tôi đã viết sau vài ngày. Hóa ra vấn đề này có thể được khắc phục bằng cách làm theo phương pháp Phát triển dựa trên thử nghiệm (TDD).
TDD là gì và tại sao nó quan trọng?
Theo thuật ngữ của giáo dân, TDD khuyên bạn nên viết các bài kiểm tra để kiểm tra chức năng mã của bạn trước khi bạn viết mã thực tế. Chỉ khi bạn hài lòng với các bài kiểm tra của mình và các tính năng mà nó kiểm tra, bạn mới bắt đầu viết mã thực tế để đáp ứng các điều kiện do bài kiểm tra đặt ra để cho phép chúng vượt qua.
Làm theo quy trình này đảm bảo rằng bạn lập kế hoạch cẩn thận cho mã bạn viết để vượt qua các bài kiểm tra này. Điều này cũng ngăn khả năng các bài kiểm tra viết bị hoãn lại sau này, vì chúng có thể không được coi là cần thiết so với các tính năng bổ sung có thể được tạo trong thời gian đó.
Các bài kiểm tra cũng mang lại cho bạn sự tự tin khi bắt đầu cấu trúc lại mã, vì bạn có nhiều khả năng bắt lỗi do phản hồi tức thì khi các bài kiểm tra được thực thi.

Làm thế nào để bắt đầu?
Để bắt đầu viết bài kiểm tra bằng Python, chúng tôi sẽ sử dụng unittest
mô-đun đi kèm với Python. Để làm điều này, chúng tôi tạo một tệp mới mytests.py
sẽ chứa tất cả các bài kiểm tra của chúng tôi.
Hãy bắt đầu với “hello world” thông thường:
import unittest
from mycode import *
class MyFirstTests(unittest.TestCase):
def test_hello(self):
self.assertEqual(hello_world(), 'hello world')
Lưu ý rằng chúng tôi đang nhập khẩu helloworld()
chức năng từ mycode
tập tin. Trong file mycode.py
ban đầu chúng tôi sẽ chỉ bao gồm mã bên dưới, mã này tạo hàm nhưng không trả về bất kỳ thứ gì ở giai đoạn này:
def hello_world():
pass
Đang chạy python mytests.py
sẽ tạo đầu ra sau trong dòng lệnh:
F
====================================================================
FAIL: test_hello (__main__.MyFirstTests)
--------------------------------------------------------------------
Traceback (most recent call last):
File "mytests.py", line 7, in test_hello
self.assertEqual(hello_world(), 'hello world')
AssertionError: None != 'hello world'
--------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (failures=1)
Điều này chỉ ra rõ ràng rằng thử nghiệm đã thất bại, điều đã được mong đợi. May mắn thay, chúng tôi đã viết các bài kiểm tra, vì vậy chúng tôi biết rằng nó sẽ luôn ở đó để kiểm tra chức năng này, giúp chúng tôi tự tin hơn trong việc phát hiện các lỗi tiềm ẩn trong tương lai.
Để đảm bảo mã vượt qua, hãy thay đổi mycode.py
theo sau:
def hello_world():
return 'hello world'
Đang chạy python mytests.py
một lần nữa, chúng tôi nhận được đầu ra sau trong dòng lệnh:
.
--------------------------------------------------------------------
Ran 1 test in 0.000s
OK
Chúc mừng! Bạn vừa mới viết bài kiểm tra đầu tiên của mình. Bây giờ chúng ta hãy chuyển sang một thử thách khó khăn hơn một chút. Chúng ta sẽ tạo một hàm cho phép chúng ta tạo khả năng hiểu danh sách số tùy chỉnh trong Python.
Hãy bắt đầu bằng cách viết một bài kiểm tra cho một chức năng sẽ tạo ra một danh sách có độ dài cụ thể.
Trong file mytests.py
đây sẽ là một phương pháp test_custom_num_list
:
import unittest
from mycode import *
class MyFirstTests(unittest.TestCase):
def test_hello(self):
self.assertEqual(hello_world(), 'hello world')
def test_custom_num_list(self):
self.assertEqual(len(create_num_list(10)), 10)
Điều này sẽ kiểm tra chức năng create_num_list
trả về một danh sách có độ dài 10. Hãy tạo hàm create_num_list
Trong mycode.py
:
def hello_world():
return 'hello world'
def create_num_list(length):
pass
Đang chạy python mytests.py
sẽ tạo đầu ra sau trong dòng lệnh:
E.
====================================================================
ERROR: test_custom_num_list (__main__.MyFirstTests)
--------------------------------------------------------------------
Traceback (most recent call last):
File "mytests.py", line 14, in test_custom_num_list
self.assertEqual(len(create_num_list(10)), 10)
TypeError: object of type 'NoneType' has no len()
--------------------------------------------------------------------
Ran 2 tests in 0.000s
FAILED (errors=1)
Điều này đúng như mong đợi, vì vậy hãy tiếp tục và thay đổi chức năng create_num_list
Trong mytest.py
để vượt qua bài kiểm tra:
def hello_world():
return 'hello world'
def create_num_list(length):
return [x for x in range(length)]
thi hành python mytests.py
trên dòng lệnh chứng tỏ rằng bài kiểm tra thứ hai cũng đã được thông qua:
..
--------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
Bây giờ, hãy tạo một hàm tùy chỉnh để biến đổi từng giá trị trong danh sách như sau: const * ( X ) ^ power
. Trước tiên, hãy viết bài kiểm tra cho điều này, sử dụng phương pháp test_custom_func_
sẽ lấy giá trị 3 làm X, lũy thừa 3 và nhân với hằng số 2, kết quả là giá trị 54:
import unittest
from mycode import *
class MyFirstTests(unittest.TestCase):
def test_hello(self):
self.assertEqual(hello_world(), 'hello world')
def test_custom_num_list(self):
self.assertEqual(len(create_num_list(10)), 10)
def test_custom_func_x(self):
self.assertEqual(custom_func_x(3,2,3), 54)
Hãy tạo chức năng custom_func_x
trong file mycode.py
:
def hello_world():
return 'hello world'
def create_num_list(length):
return [x for x in range(length)]
def custom_func_x(x, const, power):
pass
Như mong đợi, chúng tôi nhận được một thất bại:
F..
====================================================================
FAIL: test_custom_func_x (__main__.MyFirstTests)
--------------------------------------------------------------------
Traceback (most recent call last):
File "mytests.py", line 17, in test_custom_func_x
self.assertEqual(custom_func_x(3,2,3), 54)
AssertionError: None != 54
--------------------------------------------------------------------
Ran 3 tests in 0.000s
FAILED (failures=1)
cập nhật chức năng custom_func_x
để vượt qua bài kiểm tra, chúng tôi có những điều sau đây:
def hello_world():
return 'hello world'
def create_num_list(length):
return [x for x in range(length)]
def custom_func_x(x, const, power):
return const * (x) ** power
Chạy lại các bài kiểm tra, chúng tôi nhận được thông báo:
...
--------------------------------------------------------------------
Ran 3 tests in 0.000s
OK
Cuối cùng, hãy tạo một chức năng mới sẽ kết hợp custom_func_x
chức năng vào việc hiểu danh sách. Như thường lệ, hãy bắt đầu bằng cách viết bài kiểm tra. Lưu ý rằng để chắc chắn, chúng tôi bao gồm hai trường hợp khác nhau:
import unittest
from mycode import *
class MyFirstTests(unittest.TestCase):
def test_hello(self):
self.assertEqual(hello_world(), 'hello world')
def test_custom_num_list(self):
self.assertEqual(len(create_num_list(10)), 10)
def test_custom_func_x(self):
self.assertEqual(custom_func_x(3,2,3), 54)
def test_custom_non_lin_num_list(self):
self.assertEqual(custom_non_lin_num_list(5,2,3)[2], 16)
self.assertEqual(custom_non_lin_num_list(5,3,2)[4], 48)
Bây giờ hãy tạo chức năng custom_non_lin_num_list
Trong mycode.py
:
def hello_world():
return 'hello world'
def create_num_list(length):
return [x for x in range(length)]
def custom_func_x(x, const, power):
return const * (x) ** power
def custom_non_lin_num_list(length, const, power):
pass
Như trước đây, chúng tôi gặp lỗi:
.E..
====================================================================
ERROR: test_custom_non_lin_num_list (__main__.MyFirstTests)
--------------------------------------------------------------------
Traceback (most recent call last):
File "mytests.py", line 20, in test_custom_non_lin_num_list
self.assertEqual(custom_non_lin_num_list(5,2,3)[2], 16)
TypeError: 'NoneType' object has no attribute '__getitem__'
--------------------------------------------------------------------
Ran 4 tests in 0.000s
FAILED (errors=1)
Để vượt qua bài kiểm tra, hãy cập nhật mycode.py
tập tin như sau:
def hello_world():
return 'hello world'
def create_num_list(length):
return [x for x in range(length)]
def custom_func_x(x, const, power):
return const * (x) ** power
def custom_non_lin_num_list(length, const, power):
return [custom_func_x(x, const, power) for x in range(length)]
Chạy các bài kiểm tra lần cuối, chúng tôi vượt qua tất cả chúng!
....
--------------------------------------------------------------------
Ran 4 tests in 0.000s
OK
Chúc mừng! Điều này kết thúc phần giới thiệu thử nghiệm trong Python này. Hãy chắc chắn rằng bạn kiểm tra các tài nguyên bên dưới để biết thêm thông tin về thử nghiệm nói chung.
Mã có sẵn ở đây trên GitHub.
Tài nguyên hữu ích để học thêm!
tài nguyên web
Dưới đây là các liên kết đến một số thư viện tập trung vào thử nghiệm bằng Python:
video trên YouTube
Nếu bạn không muốn đọc, tôi khuyên bạn nên xem các video sau trên YouTube.