Bạn đã bao giờ nghe về TDD – hay còn gọi là Test-Driven Development (Phát triển dựa trên kiểm thử) chưa? Nếu bạn là một lập trình viên, có lẽ bạn đã từng nghe qua khái niệm này ở đâu đó, nhưng vẫn còn băn khoăn liệu nó có thực sự hữu ích không.
Khi mới bắt đầu sự nghiệp, mình cũng có suy nghĩ tương tự – viết code sao cho đúng còn chẳng đủ thời gian, lấy đâu ra thời gian để viết test trước khi code? Thế nhưng, càng làm việc lâu, mình càng nhận ra tầm quan trọng của việc đảm bảo mã nguồn hoạt động đúng ngay từ đầu. Và đó là lúc TDD thực sự bước vào cuộc sống của mình.
1. Test-Driven Development (TDD) là gì?
Test-Driven Development (TDD) là một phương pháp phát triển phần mềm, trong đó việc viết bài kiểm tra (test) được thực hiện trước khi viết code chính (production code). Thay vì chỉ kiểm tra code sau khi đã viết xong, TDD yêu cầu các lập trình viên viết ra các bài test trước.
Việc viết các bài test trước giúp các lập trình viên hiểu rõ những gì cần phải được triển khai và cách thức code nên hoạt động. Nếu mỗi tính năng được kiểm tra ngay từ đầu, các lỗi thường gặp sẽ được phát hiện và xử lý ngay lập tức.
Các bước trong TDD bao gồm: viết test cho một chức năng cụ thể → thực hiện viết code để bài test đó pass → refactor code để tối ưu mà vẫn đảm bảo test pass.
2. Lợi ích của TDD là gì?
Cá nhân mình thấy việc áp dụng TDD cực kì hiệu quả với những dự án lớn, có business logic phức tạp, việc viết unit test giúp mình hiểu kĩ hơn các chức năng mà mình đang chuẩn bị làm, thay vì lao vào code đầu tiên mình tập được thói quen hiểu business trước rồi hãy code.
Dưới đây là những lợi ích mà TDD sẽ mang lại:
- Cải thiện chất lượng mã nguồn và giảm thiểu lỗi: TDD giúp phát hiện lỗi sớm hơn trong quá trình phát triển, vì mỗi phần nhỏ của code đều được kiểm tra kỹ lưỡng ngay khi được viết ra. Việc phát hiện lỗi sớm giúp tiết kiệm chi phí và thời gian hơn so với việc sửa lỗi sau này.
- thiết kế mã nguồn rõ ràng và dễ bảo trì: TDD khuyến khích lập trình viên chia nhỏ vấn đề thành các unit nhỏ hơn, có thể kiểm thử độc lập. Mỗi unit test trong TDD cũng đóng vai trò như một tài liệu kỹ thuật, giúp người đọc dễ hiểu hơn về chức năng của từng phần code.
- Hỗ trợ quá trình refactor code mà không sợ gây lỗi cho hệ thống: TDD giúp lập trình viên tự tin hơn khi cải tiến mã (refactor), vì có một bộ test tự động để đảm bảo rằng các thay đổi không ảnh hưởng đến chức năng của hệ thống.
- Giúp tăng cường khả năng tự động hóa (CI/CD): TDD là một phần quan trọng trong các quy trình CI/CD hiện đại, giúp duy trì độ tin cậy của các bản build và cải thiện tốc độ phát hành.
2. Hướng dẫn thực hành TDD với Python
Chúng ta cùng đi vào một ví dụ cụ thể nhé. Viết hàm sum_range(start, end)
nhận vào hai số nguyên start
và end
và trả về tổng các số từ start
đến end
(bao gồm cả start
và end
). Ví dụ, sum_range(1, 5)
sẽ trả về 1 + 2 + 3 + 4 + 5 = 15
.
Bước 1: Chuẩn bị môi trường
- Đảm bảo bạn đã cài đặt
unittest
, thư viện tích hợp sẵn của Python cho việc viết unit test. - Tạo file Python cho việc test và file Python chính để chứa hàm.
Bước 2: Viết các Unit Test (Red Stage)
- Theo TDD, chúng ta sẽ viết test trước khi viết hàm
sum_range
. - Tạo file
test_sum_range.py
với các unit test sau:
import unittest
from sum_range import sum_range # Import hàm sum_range từ file sum_range.py
class TestSumRange(unittest.TestCase):
def test_positive_range(self):
# Test với khoảng từ 1 đến 5, kết quả mong đợi là 15
self.assertEqual(sum_range(1, 5), 15)
def test_single_number_range(self):
# Test với khoảng có cùng start và end, ví dụ 5 đến 5, kết quả mong đợi là 5
self.assertEqual(sum_range(5, 5), 5)
def test_negative_range(self):
# Test với khoảng từ -3 đến 3, kết quả mong đợi là -3 + -2 + -1 + 0 + 1 + 2 + 3 = 0
self.assertEqual(sum_range(-3, 3), 0)
if __name__ == '__main__':
unittest.main()
Nếu bạn chạy test ngay bây giờ với lệnh sau, tất cả các test sẽ fail, vì chúng ta chưa có hàm sum_range
:
python -m unittest test_sum_range.py
Bước 3: Viết Code để Test Pass (Green Stage)
- Bây giờ, chúng ta sẽ viết hàm
sum_range
trong filesum_range.py
để các test pass. - Tạo file
sum_range.py
và viết hàm như sau:
def sum_range(start, end):
return sum(range(start, end + 1))
- Tiếp đến, chạy lại các test để kiểm tra xem chúng có pass không:
python -m unittest test_sum_range.py
Nếu các test pass, điều đó nghĩa là hàm sum_range
đã hoạt động đúng với các trường hợp cơ bản. Đây là Green Stagetrong TDD.
Bước 4: Refactor Code (Refactor Stage)
- Hàm
sum_range
hiện tại đã tối ưu và ngắn gọn, nên không cần refactor thêm. Nếu có phần nào chưa tối ưu, chúng ta có thể chỉnh sửa lại và đảm bảo test vẫn pass.
4. Kết luận
TDD giúp mình thay đổi cách suy nghĩ về việc viết code. Thay vì lao vào code ngay lập tức, mình dừng lại, xác định rõ ràng kết quả đầu ra và viết test cho kết quả đó. Sau đó, mình để từng đoạn code nhỏ giải quyết từng yêu cầu. Quy trình nghe có vẻ tốn thời gian, nhưng thực sự TDD đã giúp mình tiết kiệm rất nhiều giờ ngồi sửa lỗi sau này.
Các bài viết liên quan:
Bài viết liên quan
Cách Discord Lưu Trữ Hàng Nghìn Tỷ Tin Nhắn Với ScyllaDB
Dec 06, 2024 • 9 min read
Idempotent Consumer: Xử lý thông điệp trùng lặp trong Microservices
Dec 04, 2024 • 7 min read
Hướng dẫn tích hợp Redux và React Query trong dự án React Vite
Nov 22, 2024 • 8 min read
Giới thiệu Kiến trúc Backend for Frontend (BFF)
Nov 16, 2024 • 10 min read
Flask là gì? Hướng dẫn tạo Ứng dụng Web với Flask
Nov 15, 2024 • 7 min read
Webhook là gì? So sánh Webhook và API
Nov 15, 2024 • 8 min read