Hướng dẫn viết unit test python
Các bạn có bao giờ tái cấu trúc code không ? Sau mỗi lần refactor, bạn có bao giờ nín thở khi deploy lại sản phẩm lên PRODUCTION hay không? Làm thế nào để không phải trải qua cảm giác kinh hoàng ấy? Trong quy trình phát triển phần mềm, có một giai đoạn mà các lập trình có thể tự cứu được "sự nghiệp" của mình mà không phải chờ đợi kết quả test của các tester hay báo cáo vận hành sản phẩm trên PRODUCTION, giai đoạn đó là viết unit-test. Show Vậy unit-test là gì ? Và áp dụng nó trong các bài toán giải quyết trong Python như thế nào? Mời các bạn theo dõi trong bài viết tiếp theo của tôi. 1. Unit-test là gì ?Unit là một khái niệm trong hệ thống phần mềm và mỗi unit được định nghĩa là các thành phần độc lập với nhau theo "định cỡ": Function -> Class -> Module -> Package (với Python). Chúng ta có thể hiểu unit-test như một black-box-testing với tập dữ liệu đầu vào sau khi chạy qua một unit và tập dữ liệu đầu ra phải khớp với một tập dữ liệu đã được tính toán trước. 2. Ai là người viết unit-test?Thông thường thì các lập trình viên là người sẽ phải chịu trách nhiệm viết unit-test. Vì unit-test là công cụ bảo đảm tính "đúng đắn" của mỗi thành phần sản phẩm mà họ làm ra. Để có thể viết được các unit-test, các lập trình viên sẽ phải hiểu rõ về yêu cầu cần thực hiện trong các unit. 3. Khi nào thì viết unit-test?Tùy vào đặc thù của từng dự án hoặc yêu cầu tiến độ của dự án mà lập trình viên sẽ thực hiện viết prototype cho unit-test trước cùng với các unit có thể xuất hiện trong hệ thống. Sau đó, trong lúc lập trình hoặc thậm chí là sau khi sản phẩm chạy ổn định rồi họ mới thực hiện viết unit-test (lúc này đã có các tập hợp dữ liệu input-output hoàn chỉnh). 4. Một số yêu cầu với unit-test.
5. Lợi ích của unit-test.
Cách sử dụng unit test trong Python.Với mỗi ngôn ngữ lập trình lại có các công cụ, thư viện khác nhau để thực hiện viết unit-test. Trong Python, có thể sử dụng pytest và unittest để viết các unit-test. Do unittest có độ thông dụng nhiều hơn nên bài viết sau đây của tôi sẽ tập trung vào module unittest trong Python. 1. Giới thiệu về unittest.Trong lập trình thì cách giới thiệu nhanh nhất cho một module/thư viện chính là ... lập trình dựa trên các đặc tính của module/thư viên đó. Sau đây là một ví dụ nhỏ về unitest. Các bạn hãy tạo một file có tên simple_unittest.py và gõ vào đoạn code như dưới đây.
Từ màn hình terminal, thực hiện chạy file trên, chúng ta thu được kết quả:
Bây giờ chúng ta cùng nhau phân tích một chút về ví dụ trên.
Trong trường kết quả test không chính xác, sẽ hiển thị ra bài test không pass được bằng cách trỏ đến dòng code và nguyên nhân gây ra lỗi. 2. Một số function trong unit-test thường dùng.2.1. Các function trong unit-test trả về True/False
Trả về True: Nếu trong các expressions phát sinh ra lỗi TypeException 2.2. Các function khác
2.3. Các function so sánh các kiểu dữ liệu khác nhau.
3. Cách chạy unittest.Ở ví dụ phía trên, ngoài cách gọi trực tiếp vào module/file để thực thi, chúng ta có thể gọi unittest từng đơn vị như sau: Test cả module: > ====================================================================== FAIL: test_islower (test_simple_unittest.TestStringMethods) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14, in test_islower self.assertTrue('PYTHON'.islower()) AssertionError: False is not true ---------------------------------------------------------------------- Ran 4 tests in 0.001s FAILED (failures=1) Test từng class/function trong module > ====================================================================== FAIL: test_islower (test_simple_unittest.TestStringMethods) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14, in test_islower self.assertTrue('PYTHON'.islower()) AssertionError: False is not true ---------------------------------------------------------------------- Ran 4 tests in 0.001s FAILED (failures=1) Test từng function trong module > ---------------------------------------------------------------------- Ran 1 test in 0.000s OK > ====================================================================== FAIL: test_islower (test_simple_unittest.TestStringMethods) ---------------------------------------------------------------------- Traceback (most recent call last): File "E:\code_learn\Projects\20201206_python-unitest\python-unittest\source_code\test_simple_unittest.py", line 14, in test_islower self.assertTrue('PYTHON'.islower()) AssertionError: False is not true ---------------------------------------------------------------------- Ran 1 test in 0.000s FAILED (failures=1) 4. Một số ví dụ về unittestVí dụ 1: Viết chương trình tìm nghiệm của phương trình bậc 1: aX + b = 0 Viết unit test cho chương trình trên Giải thuật: Nếu a == 0 và b == 0 -> phương trình vô số nghiệm, trả về ALL Nếu a == 0 và b != 0 -> Phương trình vô nghiệm, trả về NONE Kết quả: X = -b / a Sau khi giải bài toàn và lưu vào file first_equation.py
Thực hiện viết unittest của function trên.
Thực hiện chạy thử, ta thu được kết quả: OK Ví dụ 2: Cho 1 chuỗi cho trước, thực hiện tách chuỗi theo các khoảng trắng và trả về một list của các tuple dạng [(số thứ tự, giá trị),…] Input: Output: [(1, 'Python'), (2, 'is'), (3, 'a'), (4, 'best'), (5, 'language')]
Viết unit-test cho bài toán:
Kết quả thực hiện: OK Ví dụ 3: Xử lý chuỗi palindrome Dữ liệu mẫu: Input: test_str = ”Civic” Input: test_str = ”Noon”
Code của bài toán:
Unitest của bài toán:
Thực hiện test bài test: > python -m unittest
test_palindrome OK Tiếp theo, các bạn hãy sửa lại các function thực hiện xử lý bài toán để ra kết quả... sai. Sau đó thực hiện chạy các test case, chắc chắn kết quả sẽ bị FAIL --> Đó là lý do tại sao chúng ta cần phải viết unitest. Kết quả fail có nghĩa là chúng ta sẽ phải xem lại phần code chương trình, có thể đã có chỗ nào đó đã bị thay đổi để đưa so với ban đầu khiến cho chương trình hoạt động không được chuẩn xác. KếtTrên đây là một số vấn đề cơ bản khi thực hiện viết unittest cho lập trình Python. Hẹn gặp lại các bạn vào một bài viết chuyên sâu hơn, phân tích kỹ hơn các chiến thuật viết unittest và unittest-mock. Tài liệu tham khảo: https://docs.python.org/3/library/unittest.html. |