BÀI 30. KIỂM THỬ VÀ GỠ LỖI CHƯƠNG TRÌNH
1. MỘT VÀI PHƯƠNG PHÁP KIỂM THỬ CHƯƠNG TRÌNH
Các công cụ và phương pháp kiểm thử không chỉ nhằm tìm ra lỗi (bug) mà còn có tác dụng phòng ngừa, ngăn chặn các lỗi phát sinh trong tương lai.
a) Quan sát mã lỗi Runtime và bắt lỗi ngoại lệ
Nếu chương trình có lỗi Runtime (đang chạy thì bị dừng lại), cần quan sát các mã lỗi ngoại lệ để kiểm tra vị trí dòng lệnh sinh ra lỗi.
Từ vị trí đó, học sinh tiến hành phân tích, tìm và sửa lỗi.
Ví dụ: Khi học sinh viết lệnh chia một số cho 0, chương trình dừng và báo mã lỗi "ZeroDivisionError" ở dòng lệnh đó. Nhờ quan sát mã lỗi, các em biết ngay lỗi chia cho 0 để sửa.
b) Kiểm thử chương trình với các bộ dữ liệu test
Chương trình cần được chạy thử với các bộ dữ liệu test tiêu biểu mà ta đã biết trước kết quả đầu ra.
- Cần có nhiều bộ test với độ lớn và tính đa dạng khác nhau.
- Ví dụ: Viết chương trình cộng 2 số, học sinh cần test nghiệm với số dương (5, 10), số âm (-2, -5) và nghiệm có số 0.
- Cần có bộ test ngẫu nhiên trong miền xác định để tăng khả năng tìm ra lỗi.
- Ví dụ: Chương trình tính điểm trung bình, ta cho sinh ngẫu nhiên các con số thập phân bất kỳ từ 0 đến 10 để xem chương trình xử lý có đúng không.
- Cần có bộ test dữ liệu ở vùng biên vì thực tế lỗi thường phát sinh tại các vùng biên hoặc lân cận biên.
- Ví dụ: Nếu biến x, y được xác định trên miền 0 ≤ x ≤ 1 và 0 ≤ y ≤ 1, học sinh cần kiểm tra với các bộ dữ liệu biên như (0; 0), (0; 1), (1; 0).
c) In các thông số trung gian
Bổ sung các lệnh print() vào giữa các dòng lệnh để in ra các biến trung gian.
Việc này giúp kiểm tra quy trình, thuật toán chạy có đúng không và dễ dàng tìm ra lỗi nếu kết quả cuối cùng bị sai.
Ví dụ: Trong vòng lặp đếm số, học sinh chèn thêm lệnh in print(i) vào trong vòng lặp để quan sát xem biến đếm i tăng lên từng bước như thế nào.
d) Sử dụng công cụ break point (điểm dừng)
- Công cụ này cho phép tạo ra các "điểm dừng" bên trong chương trình.
- Khi chạy, chương trình sẽ tạm dừng tại đây, cho phép người kiểm thử quan sát thông tin bên trong để kiểm tra tính đúng đắn.
- Phương pháp này thường kết hợp với việc in giá trị trung gian để đạt hiệu quả cao nhất.
- Ví dụ: Học sinh thiết lập điểm dừng ở ngay trước một vòng lặp while để kiểm tra xem các giá trị của biến trước khi bắt đầu vòng lặp đã nhận đúng dữ liệu hay chưa.
2. VÍ DỤ MINH HOẠ: KIỂM THỬ VÀ GỠ LỖI
Bài toán:
Viết chương trình tính tổng 3 số tự nhiên đầu tiên: S = 1 + 2 + 3. (Chúng ta đều biết trước kết quả đúng phải là 6).
Vấn đề:
Khi chạy chương trình, máy tính in ra kết quả là 3 thay vì 6. Chương trình chạy trơn tru, không hề báo dòng chữ đỏ nào (không có lỗi ngoại lệ). Đây chính là lúc chúng ta phải dùng các công cụ gỡ lỗi để tìm ra nguyên nhân.
Cách 1: Bổ sung lệnh print() để in các giá trị trung gian
Giống như việc lắp một chiếc camera quan sát vào bên trong vòng lặp, ta sẽ chèn thêm lệnh print() để xem biến i và biến S đang thay đổi như thế nào sau mỗi vòng quay.
Phân tích để sửa lỗi:
Nhìn vào dòng in ra, ta thấy vòng lặp chỉ chạy với i = 1 và i = 2 rồi dừng hẳn. Nó đã bỏ sót lượt chạy i = 3. Từ đó, ta dễ dàng phát hiện ra lỗi nằm ở điều kiện của lệnh while. Để sửa lỗi, ta chỉ cần thay đổi i < 3 thành i <= 3.
Cách 2: Sử dụng công cụ điểm dừng (Break point)
Thay vì phải tự gõ thêm lệnh print(), các phần mềm lập trình cho phép ta đặt một "Điểm dừng" (Break point). Giống như nút Tạm dừng (Pause) khi xem video, chương trình sẽ tự động dừng lại trước mỗi vòng lặp để ta soi kĩ các giá trị.
Cách thực hiện:
- Bật sẵn chế độ Variables để xem giá trị các biến (View -> Variables).
- Click chuột vào lề bên trái của dòng while i < 3: để tạo một chấm đỏ (Điểm dừng).
- Chạy chương trình ở chế độ Debug (Ctrl + F5).
- Chạy tiếp từng bước để theo dõi (F7).
- Mỗi khi chương trình tạm dừng, ta sẽ ghi chép lại giá trị hiện tại của S và i vào một bảng theo dõi: