Phát triển dựa trên kiểm thử (TDD) với Python: Hướng dẫn cho người mới bắt đầu
Tìm hiểu phát triển dựa trên kiểm thử (TDD) với hướng dẫn Python toàn diện. Học cách viết các bài kiểm thử vững chắc trước khi viết mã với các ví dụ thực tiễn.
Kiểm thử giúp bạn tự tin rằng mã của bạn hoạt động đúng như mong đợi. Trong hướng dẫn này, chúng ta sẽ học những điều cơ bản về phát triển dựa trên kiểm thử (TTD) bằng Python. Trước tiên, chúng ta sẽ điểm qua một số kiến thức nền tảng về phát triển dựa trên kiểm thử – đó là gì và vì sao viết kiểm thử trước lại hữu ích khi viết mã. Chúng ta sẽ áp dụng phương pháp kiểm thử trước: trước hết viết các ca kiểm thử thất bại cho chức năng muốn triển khai, rồi mới viết các hàm thực sự.
Cách tiếp cận kiểm thử trước giúp chúng ta suy nghĩ thấu đáo về hành vi mong muốn và đầu ra kỳ vọng. Bạn có thể dùng nhiều thư viện để kiểm thử trong Python như pytest và unnitest. Tuy nhiên, hiện tại chúng ta sẽ tập trung vào cách viết các ca kiểm thử đơn giản bằng Python thuần để xác nhận rằng chức năng mong muốn tạo ra đầu ra như kỳ vọng.
Chúng ta sẽ bắt đầu với một ca kiểm thử đơn giản và mở rộng dần để bao phủ các kịch bản khác nhau. Khi mở rộng ca kiểm thử, có thể chúng ta sẽ phát hiện lỗi hoặc những thiếu sót trong logic triển khai ban đầu cần cải thiện. Quy trình tổng thể viết các ca kiểm thử nâng cao dần, thấy chúng thất bại, rồi quay lại cải thiện phần triển khai chính là cốt lõi của phát triển dựa trên kiểm thử với Python.
Trong hướng dẫn này, chúng ta sẽ sử dụng DataLab, sổ tay dữ liệu trên đám mây của DataCamp cho phép bạn viết và chạy mã Python mà không cần cài đặt cục bộ. Bắt đầu thôi!
Bắt đầu với DataLab
Trước khi bắt tay vào phát triển dựa trên kiểm thử, chúng ta cần khám phá DataLab và hiểu cách sử dụng để hỗ trợ hành trình học tập. Khi mở DataLab, bạn sẽ thấy có nhiều tùy chọn. Trước mắt, chúng ta sẽ tập trung vào việc viết Python trong DataLab.
Nếu chọn Python, sổ làm việc sẽ mở một ô mã để bạn viết Python. Trông sẽ giống như sau:
Bạn có một số tùy chọn hữu ích ở đây. Chẳng hạn, bạn có thể chạy ô để tạo đầu ra, thêm bình luận hoặc ghi chú để hỗ trợ việc học, và sử dụng AI để bắt đầu hoặc gỡ rối. Bạn cũng có thể thêm hoặc xóa bao nhiêu ô tùy ý. Chúng ta sẽ tập trung vào chạy ô bằng tùy chọn "Run". Như bạn thấy trong đoạn mã bên dưới, bất kỳ đầu ra nào mã của bạn tạo ra sẽ được ghi bên dưới khi bạn chạy ô.
Lưu ý nhanh: Nếu bạn dùng nhiều ô và đã định nghĩa một biến trong một ô nhưng lại cố truy cập nó ở ô khác, bạn cần chạy từng ô riêng lẻ hoặc chạy toàn bộ sổ làm việc (từ nút "Run" ở góc trên bên phải của sổ làm việc).
Giờ chúng ta đã nắm các điều cơ bản về DataLab, hãy bắt đầu với phát triển dựa trên kiểm thử.
Phát triển dựa trên kiểm thử
Phát triển dựa trên kiểm thử có nghĩa là viết kiểm thử cho mã của bạn trước khi bạn viết mã. Để giải thích TTD, hãy bắt đầu với một ví dụ đơn giản: viết một script Python để cộng các số lại với nhau. Tuy nhiên, trước khi viết hàm, chúng ta sẽ viết một kiểm thử để kiểm tra xem 1 + 1 có bằng 2 không. Bạn có thể thực hiện điều này bằng Python thuần như dưới đây.
Từ khóa assert trong Python được dùng để viết các ca kiểm thử và xác nhận rằng các điều kiện trong chương trình đánh giá là True. Nó cho phép bạn xác thực hành vi và đầu ra của mã. Khi một câu lệnh assert thất bại, nó sẽ phát sinh AssertionError, báo hiệu có vấn đề với mã. Trong sổ làm việc DataLab, nó sẽ trông như thế này:
Ví dụ 1: Kiểm thử một hàm đơn giản
Bắt đầu với hàm kiểm thử. Trước tiên, mở một tệp Python trong DataLab. Phát triển dựa trên kiểm thử bắt đầu bằng việc viết một kiểm thử thất bại. Vậy hãy viết một kiểm thử thất bại bằng cách gọi hàm add() vốn chưa được định nghĩa.
Điều này sẽ dẫn đến NameError, cho thấy chưa có phần triển khai, còn gọi là bước "đỏ". Bạn sẽ gặp NameError khi cố gọi một hàm hoặc biến chưa được định nghĩa.
Giờ là lúc triển khai hàm. Chúng ta có thể làm điều này bằng cách định nghĩa hàm:
Chúng ta đã định nghĩa hàm add, nhận hai tham số num1 và num2. Hiện tại hàm chưa trả về gì. Hãy xem phần triển khai này có vượt qua kiểm thử không nhé!
Chúng ta không còn thấy NameError nữa. Tuy nhiên, chạy ô vẫn báo lỗi! Lần này là AssertionError. Vậy kiểm thử vẫn thất bại! Tại sao có thể có lỗi này? Bởi vì chúng ta đã định nghĩa một hàm nhưng chưa trả về bất cứ thứ gì.
Khi chạy kiểm thử, ta nhận AssertionError vì 1 + 1 không bằng 2 với phần triển khai rỗng. Cuối cùng, chúng ta có thể làm cho nó vượt qua kiểm thử bằng cách triển khai đúng logic trong hàm.
Bạn sẽ thấy dấu chấm màu xanh ở góc ô. Điều này cho biết mã của bạn hợp lệ và đã vượt qua khi chạy ô. Trước đó, bạn sẽ thấy nó màu đỏ với lỗi chạy và hiển thị loại lỗi bên dưới ô. Tính năng này hữu ích để gỡ lỗi trong DataLab.
Bạn vừa viết bài kiểm thử đầu tiên trong Python theo phương pháp phát triển dựa trên kiểm thử. Tốt lắm! Bây giờ, chúng ta sẽ mở rộng các kiểm thử và cân nhắc việc bắt các lỗi tiềm ẩn có thể khiến hàm thất bại hoặc không tạo ra đầu ra như mong đợi.
Ví dụ 2: Nhiều ca kiểm thử
Chỉ kiểm thử với một giá trị đầu vào thường không phát hiện được các lỗi tiềm ẩn. Lỗi có thể dễ dàng ẩn mình, đặc biệt nếu hàm của bạn phụ thuộc vào đầu vào biến đổi của người dùng hoặc logic bên ngoài. Vậy làm sao kiểm thử kỹ một hàm với nhiều giá trị?
Ví dụ, nếu một kiểu dữ liệu không đúng được truyền vào hàm thì sao? Bạn có thể dùng các framework kiểm thử Python, nhưng hãy dùng Python cơ bản thay thế. Trước hết, tôi sẽ định nghĩa một danh sách các từ điển đầu vào để mô phỏng những kịch bản sử dụng khác nhau:
test_cases =[{"num1":1,"num2":3,"expected":4},{"num1":1,"num2":"invalid","expected":"Error: num2 must be a number"},{"num1":[1,2,3],"num2":2,"expected":"Error: num1 must be a number"},{"num1":-1,"num2":1,"expected":0},{"num1":3.5,"num2":2.5,"expected":6.0},{"num1":100,"num2":200,"expected":300}]Được hỗ trợ bởi
Đoạn mã trên thể hiện các đầu vào cho hàm cùng với đầu ra kỳ vọng. Tuy nhiên, chúng ta phải cập nhật kiểm thử để lặp qua các ca kiểm thử này. Ta có thể xác thực từng từ điển trong danh sách bằng cách lồng assert trong một vòng lặp for.
for test in test_cases:
assert add(test["num1"], test["num2"]) == test["expected"]Được hỗ trợ bởi
Vì hàm chưa thay đổi, liệu chúng ta kỳ vọng kiểm thử này vượt qua hay thất bại? Và có thể xảy ra lỗi gì?
Kiểm thử phát sinh lỗi TypeError vì chúng ta chưa xử lý đầu vào không phải số; nếu một chuỗi hoặc boolean được truyền vào thay vì int thì sao? Chúng ta có thể cập nhật hàm để bắt các trường hợp này! Bằng cách kiểm tra biến đầu vào là số nguyên hoặc số thực, chúng ta có thể trả về thông báo tùy chỉnh cho kiểu không hợp lệ.
defadd(num1, num2):iftype(num1)isnotintandtype(num1)isnotfloat:return"Error: num1 must be a number"eliftype(num2)isnotintandtype(num2)isnotfloat:return"Error: num2 must be a number"else:return num1 + num2Được hỗ trợ bởi
Khi chạy lại kiểm thử, chúng ta không còn gặp lỗi nào nữa, nghĩa là kiểm thử đã vượt qua. Bây giờ bạn sẽ thấy vòng tròn màu xanh cho biết chúng ta đã triển khai các kiểm thử đạt yêu cầu. Làm tốt lắm!
Tổng kết
Trong hướng dẫn này, chúng ta đã tìm hiểu những điều cơ bản về phát triển dựa trên kiểm thử trong Python bằng DataLab. DataLab cung cấp một IDE đám mây cho phép bạn viết và chạy mã Python mà không cần cài đặt cục bộ. Kiểm thử xác thực hành vi của mã và phát hiện lỗi sớm. Các câu lệnh assert kiểm tra điều kiện và ném ngoại lệ khi thất bại.
Bạn có thể khám phá thêm các ca kiểm thử và bắt đầu tự viết kiểm thử trong DataLab! Nếu muốn tìm hiểu thêm về kiểm thử trong Python, hãy xem khóa học DataCamp - Introduction to Testing in Python.
Amina là thực tập sinh phát triển nội dung tại Datacamp. Với nền tảng Kiến trúc và Giáo dục, cô đã chuyển hướng sự nghiệp sang phát triển phần mềm, bắt đầu với JavaScript; hiện cô tập trung vào Python.
Kiểm thử giúp bạn tự tin rằng mã của bạn hoạt động đúng như mong đợi. Trong hướng dẫn này, chúng ta sẽ học những điều cơ bản về phát triển dựa trên kiểm thử (TTD) bằng Python. Trước tiên, chúng ta sẽ điểm qua một số kiến thức nền tảng về phát triển dựa trên kiểm thử – đó là gì và vì sao viết kiểm thử trước lại hữu ích khi viết mã. Chúng ta sẽ áp dụng phương pháp kiểm thử trước: trước hết viết các ca kiểm thử thất bại cho chức năng muốn triển khai, rồi mới viết các hàm thực sự.
Yêu cầu tiên quyết cho hướng dẫn
Bạn cần có hiểu biết cơ bản về Python; nếu muốn ôn lại kiến thức Python, bạn có thể xem khóa học này: Introduction to Python for Developers.
Cách tiếp cận kiểm thử trước giúp chúng ta suy nghĩ thấu đáo về hành vi mong muốn và đầu ra kỳ vọng. Bạn có thể dùng nhiều thư viện để kiểm thử trong Python như pytest và unnitest. Tuy nhiên, hiện tại chúng ta sẽ tập trung vào cách viết các ca kiểm thử đơn giản bằng Python thuần để xác nhận rằng chức năng mong muốn tạo ra đầu ra như kỳ vọng.
Chúng ta sẽ bắt đầu với một ca kiểm thử đơn giản và mở rộng dần để bao phủ các kịch bản khác nhau. Khi mở rộng ca kiểm thử, có thể chúng ta sẽ phát hiện lỗi hoặc những thiếu sót trong logic triển khai ban đầu cần cải thiện. Quy trình tổng thể viết các ca kiểm thử nâng cao dần, thấy chúng thất bại, rồi quay lại cải thiện phần triển khai chính là cốt lõi của phát triển dựa trên kiểm thử với Python.
Trong hướng dẫn này, chúng ta sẽ sử dụng DataLab, sổ tay dữ liệu trên đám mây của DataCamp cho phép bạn viết và chạy mã Python mà không cần cài đặt cục bộ. Bắt đầu thôi!
Bắt đầu với DataLab
Trước khi bắt tay vào phát triển dựa trên kiểm thử, chúng ta cần khám phá DataLab và hiểu cách sử dụng để hỗ trợ hành trình học tập. Khi mở DataLab, bạn sẽ thấy có nhiều tùy chọn. Trước mắt, chúng ta sẽ tập trung vào việc viết Python trong DataLab.
Nếu chọn Python, sổ làm việc sẽ mở một ô mã để bạn viết Python. Trông sẽ giống như sau:
Bạn có một số tùy chọn hữu ích ở đây. Chẳng hạn, bạn có thể chạy ô để tạo đầu ra, thêm bình luận hoặc ghi chú để hỗ trợ việc học, và sử dụng AI để bắt đầu hoặc gỡ rối. Bạn cũng có thể thêm hoặc xóa bao nhiêu ô tùy ý. Chúng ta sẽ tập trung vào chạy ô bằng tùy chọn "Run". Như bạn thấy trong đoạn mã bên dưới, bất kỳ đầu ra nào mã của bạn tạo ra sẽ được ghi bên dưới khi bạn chạy ô.
Lưu ý nhanh: Nếu bạn dùng nhiều ô và đã định nghĩa một biến trong một ô nhưng lại cố truy cập nó ở ô khác, bạn cần chạy từng ô riêng lẻ hoặc chạy toàn bộ sổ làm việc (từ nút "Run" ở góc trên bên phải của sổ làm việc).
Giờ chúng ta đã nắm các điều cơ bản về DataLab, hãy bắt đầu với phát triển dựa trên kiểm thử.
Phát triển dựa trên kiểm thử
Phát triển dựa trên kiểm thử có nghĩa là viết kiểm thử cho mã của bạn trước khi bạn viết mã. Để giải thích TTD, hãy bắt đầu với một ví dụ đơn giản: viết một script Python để cộng các số lại với nhau. Tuy nhiên, trước khi viết hàm, chúng ta sẽ viết một kiểm thử để kiểm tra xem 1 + 1 có bằng 2 không. Bạn có thể thực hiện điều này bằng Python thuần như dưới đây.
Từ khóa
asserttrong Python được dùng để viết các ca kiểm thử và xác nhận rằng các điều kiện trong chương trình đánh giá là True. Nó cho phép bạn xác thực hành vi và đầu ra của mã. Khi một câu lệnhassertthất bại, nó sẽ phát sinhAssertionError, báo hiệu có vấn đề với mã. Trong sổ làm việc DataLab, nó sẽ trông như thế này:Ví dụ 1: Kiểm thử một hàm đơn giản
Bắt đầu với hàm kiểm thử. Trước tiên, mở một tệp Python trong DataLab. Phát triển dựa trên kiểm thử bắt đầu bằng việc viết một kiểm thử thất bại. Vậy hãy viết một kiểm thử thất bại bằng cách gọi hàm add() vốn chưa được định nghĩa.
Điều này sẽ dẫn đến
NameError, cho thấy chưa có phần triển khai, còn gọi là bước "đỏ". Bạn sẽ gặpNameErrorkhi cố gọi một hàm hoặc biến chưa được định nghĩa.Giờ là lúc triển khai hàm. Chúng ta có thể làm điều này bằng cách định nghĩa hàm:
Chúng ta đã định nghĩa hàm
add, nhận hai tham sốnum1vànum2. Hiện tại hàm chưa trả về gì. Hãy xem phần triển khai này có vượt qua kiểm thử không nhé!Chúng ta không còn thấy
NameErrornữa. Tuy nhiên, chạy ô vẫn báo lỗi! Lần này làAssertionError. Vậy kiểm thử vẫn thất bại! Tại sao có thể có lỗi này? Bởi vì chúng ta đã định nghĩa một hàm nhưng chưa trả về bất cứ thứ gì.Khi chạy kiểm thử, ta nhận
AssertionErrorvì 1 + 1 không bằng 2 với phần triển khai rỗng. Cuối cùng, chúng ta có thể làm cho nó vượt qua kiểm thử bằng cách triển khai đúng logic trong hàm.Bạn sẽ thấy dấu chấm màu xanh ở góc ô. Điều này cho biết mã của bạn hợp lệ và đã vượt qua khi chạy ô. Trước đó, bạn sẽ thấy nó màu đỏ với lỗi chạy và hiển thị loại lỗi bên dưới ô. Tính năng này hữu ích để gỡ lỗi trong DataLab.
Bạn vừa viết bài kiểm thử đầu tiên trong Python theo phương pháp phát triển dựa trên kiểm thử. Tốt lắm! Bây giờ, chúng ta sẽ mở rộng các kiểm thử và cân nhắc việc bắt các lỗi tiềm ẩn có thể khiến hàm thất bại hoặc không tạo ra đầu ra như mong đợi.
Ví dụ 2: Nhiều ca kiểm thử
Chỉ kiểm thử với một giá trị đầu vào thường không phát hiện được các lỗi tiềm ẩn. Lỗi có thể dễ dàng ẩn mình, đặc biệt nếu hàm của bạn phụ thuộc vào đầu vào biến đổi của người dùng hoặc logic bên ngoài. Vậy làm sao kiểm thử kỹ một hàm với nhiều giá trị?
Ví dụ, nếu một kiểu dữ liệu không đúng được truyền vào hàm thì sao? Bạn có thể dùng các framework kiểm thử Python, nhưng hãy dùng Python cơ bản thay thế. Trước hết, tôi sẽ định nghĩa một danh sách các từ điển đầu vào để mô phỏng những kịch bản sử dụng khác nhau:
Đoạn mã trên thể hiện các đầu vào cho hàm cùng với đầu ra kỳ vọng. Tuy nhiên, chúng ta phải cập nhật kiểm thử để lặp qua các ca kiểm thử này. Ta có thể xác thực từng từ điển trong danh sách bằng cách lồng assert trong một vòng lặp for.
Vì hàm chưa thay đổi, liệu chúng ta kỳ vọng kiểm thử này vượt qua hay thất bại? Và có thể xảy ra lỗi gì?
Kiểm thử phát sinh lỗi
TypeErrorvì chúng ta chưa xử lý đầu vào không phải số; nếu một chuỗi hoặc boolean được truyền vào thay vì int thì sao? Chúng ta có thể cập nhật hàm để bắt các trường hợp này! Bằng cách kiểm tra biến đầu vào là số nguyên hoặc số thực, chúng ta có thể trả về thông báo tùy chỉnh cho kiểu không hợp lệ.Khi chạy lại kiểm thử, chúng ta không còn gặp lỗi nào nữa, nghĩa là kiểm thử đã vượt qua. Bây giờ bạn sẽ thấy vòng tròn màu xanh cho biết chúng ta đã triển khai các kiểm thử đạt yêu cầu. Làm tốt lắm!
Tổng kết
Trong hướng dẫn này, chúng ta đã tìm hiểu những điều cơ bản về phát triển dựa trên kiểm thử trong Python bằng DataLab. DataLab cung cấp một IDE đám mây cho phép bạn viết và chạy mã Python mà không cần cài đặt cục bộ. Kiểm thử xác thực hành vi của mã và phát hiện lỗi sớm. Các câu lệnh assert kiểm tra điều kiện và ném ngoại lệ khi thất bại.
Bạn có thể khám phá thêm các ca kiểm thử và bắt đầu tự viết kiểm thử trong DataLab! Nếu muốn tìm hiểu thêm về kiểm thử trong Python, hãy xem khóa học DataCamp - Introduction to Testing in Python.