Tin Học KHMT
Ôn tập Tin học THPT › Tin học 11 - Khoa học máy tính › Bài 29
Tin học 11 - Khoa học máy tính

Bài 29. Kiểm thử và gỡ lỗi chương trình (nâng cao)

Ở mức cơ bản, ta đã biết ba loại lỗi thường gặp và vài cách dò lỗi đơn giản. Bài học này đi xa hơn: xây dựng một bộ kiểm thử thật sự có hệ thống - so kết quả chương trình với đáp án đã biết trước cho nhiều bộ dữ liệu, đặc biệt ở những trường hợp biên dễ bị bỏ sót - để không còn phải chạy thử một lần rồi vội yên tâm.

Chủ đề F · Lập trình, Thuật toán & CTDL (KHMT) - đọc khoảng 13 phút · 24 câu luyện tập trong ứng dụng

Tương ứng sách giáo khoa
  • Cánh DiềuTin học 11 (Khoa học máy tính) - Chủ đề F(CS) · Bài 6. Kiểm thử và sửa lỗi chương trìnhtr. 113
  • Kết nối tri thứcTin học 11 (Khoa học máy tính) - Bài 23. Kiểm thử và đánh giá chương trìnhtr. 106–110
Xem bảng đối chiếu cả bộ →

Bắt đầu bằng một hình dung

Giả sử bạn vừa học được một dạng bài tập mới và đem ra thử với một đề khá dễ trong sách - làm xong, so đáp số thì khớp ngay lập tức. Cảm giác đó rất dễ khiến ta tin rằng mình đã nắm chắc cách giải, và yên tâm dừng lại ở đó. Nhưng đến khi gặp một đề “khó nhằn” hơn - số liệu đặc biệt, hoặc rơi vào một tình huống mà đề dễ chưa từng có - cách giải tưởng như đã vững bỗng cho ra một kết quả vô lí. Hoá ra ta mới chỉ thử qua những trường hợp “đẹp”, còn những trường hợp ít gặp hơn thì chưa hề động tới.

Một chương trình máy tính cũng vận hành y hệt như vậy: chạy đúng với một bộ dữ liệu duy nhất không có nghĩa là chương trình đúng trong MỌI tình huống. Muốn thật sự tin tưởng vào một chương trình, ta cần một cách kiểm tra có hệ thống hơn nhiều - chuẩn bị sẵn nhiều bộ dữ liệu khác nhau, đặc biệt những bộ “khó nhằn” nhất, rồi so kết quả với đáp án đã biết trước cho từng bộ, thay vì chỉ dừng lại ở một hai lần chạy thử suôn sẻ.

Nội dung bài học

  1. Vì sao chạy đúng một lần chưa chắc đã đúng
  2. Bộ kiểm thử: đầu vào và kết quả mong đợi
  3. Những trường hợp biên cần đặc biệt lưu ý

Tóm tắt lý thuyết cần nhớ

  • Chạy đúng với một bộ dữ liệu, hay chỉ một lần, không đủ để khẳng định chương trình đúng - lỗi logic có thể ẩn và chỉ lộ ra ở một số bộ dữ liệu nhất định, nên cần kiểm thử với NHIỀU bộ dữ liệu khác nhau.
  • Một bộ dữ liệu kiểm thử gồm hai phần: dữ liệu đầu vào và kết quả MONG ĐỢI đã biết trước (tính tay hoặc suy luận từ đề bài); kiểm thử là so kết quả chương trình chạy ra với kết quả mong đợi đó.
  • Cần đặc biệt chú ý các trường hợp biên khi chuẩn bị bộ kiểm thử: dãy rỗng, chỉ một phần tử, giá trị 0, số âm, giá trị lớn/nhỏ nhất có thể có, và trường hợp không tìm thấy - đây là nơi lỗi logic dễ ẩn náu nhất.
  • Khi một bộ kiểm thử báo sai, nên đọc kĩ thông báo lỗi (nếu có), in giá trị trung gian để xem chương trình đang tính đến đâu, thu hẹp dần vùng nghi ngờ, sửa lại rồi chạy thử lại TOÀN BỘ bộ kiểm thử, không chỉ riêng bộ vừa báo sai.

Thuật ngữ tiếng Anh trong bài

Tiếng AnhĐọc làNghĩa
testtétkiểm thử
Chạy thử chương trình xem có đúng như em muốn không - giống kiểm tra lại bài làm trước khi nộp cho cô.
debugđi-BẤCgỡ lỗi
Đi tìm con bọ (lỗi) đang trốn trong chương trình rồi sửa cho code chạy đúng - như tìm chỗ sai trong bài toán rồi sửa lại.
bugbấclỗi (bug)
Chỗ chương trình bị sai hoặc chạy không đúng ý em.

Câu hỏi trắc nghiệm có đáp án

Mấy câu mẫu để bạn tự kiểm tra ngay. Trong ứng dụng, bài này có đủ 24 câu, chấm điểm tự động và giải thích từng câu sai.

Câu 1 · Nhận biết
Vì sao một chương trình chạy đúng với một bộ dữ liệu duy nhất vẫn chưa đủ để khẳng định chương trình hoàn toàn đúng?
  1. Vì mỗi lần chạy, Python sẽ cho ra một kết quả ngẫu nhiên khác nhau, nên phải chạy nhiều lần rồi lấy kết quả hay gặp nhất
  2. Vì lỗi logic có thể chỉ lộ ra ở một số bộ dữ liệu nhất định, còn những bộ khác vẫn cho kết quả đúng bình thường
  3. Vì chương trình luôn báo lỗi cú pháp ngay nếu có chỗ nào đó sai, nên chạy trót lọt một lần là đã chắc chắn đúng
  4. Vì một chương trình chỉ được phép chạy đúng một lần duy nhất với mỗi bộ dữ liệu, muốn thử bộ khác phải viết lại
Đáp án: B - Lỗi logic là loại lỗi tinh vi: chương trình vẫn chạy và cho kết quả, nhưng có thể chỉ sai ở một số bộ dữ liệu cụ thể, còn những bộ khác vẫn tình cờ cho kết quả đúng. Vì vậy cần thử nhiều bộ dữ liệu khác nhau mới phát hiện được. Các phương án còn lại không đúng: chương trình không cho kết quả ngẫu nhiên nếu logic cố định, lỗi cú pháp là chuyện khác hẳn lỗi logic, và không có giới hạn số lần chạy một chương trình.
Câu 2 · Nhận biết
Theo bài học, một bộ dữ liệu kiểm thử (test case) đầy đủ cần gồm những gì?
  1. Chỉ cần dữ liệu đầu vào, không cần biết trước kết quả, cứ chạy chương trình rồi xem kết quả in ra
  2. Dữ liệu đầu vào và kết quả mà chương trình in ra khi chạy với dữ liệu đó, ghi lại để đối chiếu
  3. Dữ liệu đầu vào và kết quả mong đợi, được xác định từ trước bằng cách tính tay hoặc suy luận
  4. Chỉ cần kết quả mong đợi, không cần dữ liệu đầu vào vì chương trình tự sinh dữ liệu để chạy thử
Đáp án: C - Một bộ dữ liệu kiểm thử gồm đúng hai phần: dữ liệu đầu vào và kết quả mong đợi đã biết trước, độc lập với chương trình đang kiểm tra. So kết quả chương trình chạy ra với kết quả mong đợi này mới cho biết chương trình đúng hay sai; thiếu một trong hai phần, việc kiểm thử sẽ mất hết ý nghĩa.
Câu 3 · Thông hiểu
Ở ví dụ hàm tim_max trong bài, phiên bản gốc khởi tạo lon_nhat = 0 trước khi duyệt toàn bộ danh sách. Bộ dữ liệu kiểm thử nào đã phát hiện ra lỗi này?
  1. [3, 7, 2, 9, 4], mong đợi 9
  2. [5], mong đợi 5
  3. [-3, -1, -8, -2], mong đợi -1
  4. Không bộ nào phát hiện ra, vì hàm gốc luôn cho kết quả đúng
Đáp án: C - Với danh sách toàn số âm, mọi phần tử đều nhỏ hơn 0, nên biến lon_nhat khởi tạo bằng 0 không bao giờ bị thay đổi trong vòng lặp - hàm trả về 0 thay vì -1 như mong đợi. Hai bộ dữ liệu đầu đều chứa số dương lớn hơn 0 nên tình cờ vẫn cho kết quả đúng, không lộ ra lỗi.
Câu Đúng/Sai (Phần II) · Thông hiểu
Cho biết mỗi phát biểu sau đúng hay sai:
  • a)Một chương trình chạy xong, không báo lỗi và có in ra kết quả, chắc chắn là chương trình không còn lỗi logic nào.Sai
  • b)Trong một bộ dữ liệu kiểm thử, kết quả mong đợi cần được xác định từ trước khi chạy chương trình, chẳng hạn bằng cách tính tay hoặc suy luận từ đề bài.Đúng
  • c)Danh sách rỗng, danh sách chỉ có một phần tử, hay các giá trị bằng 0 hoặc số âm đều là những trường hợp biên nên được đưa vào bộ kiểm thử.Đúng
  • d)Khi một bộ kiểm thử báo sai, cách làm hiệu quả nhất là xoá toàn bộ chương trình và viết lại từ đầu, không cần tìm xem chỗ nào sai.Sai
Vì sao:
  • (a) Sai - chạy xong và có kết quả không đồng nghĩa với không còn lỗi logic; đây chính là lí do phải kiểm thử với nhiều bộ dữ liệu, đặc biệt các trường hợp biên.
  • (b) Đúng - kết quả mong đợi phải được biết trước, độc lập với chương trình đang kiểm tra, thì việc so sánh mới có ý nghĩa.
  • (c) Đúng - đây đều là những trường hợp biên được nêu trong bài, nơi lỗi logic dễ ẩn náu nhất.
  • (d) Sai - cách làm hiệu quả là in giá trị trung gian, thu hẹp dần vùng nghi ngờ để tìm đúng chỗ sai trước khi sửa, không phải xoá hết viết lại từ đầu.

Thử ngay: minh hoạ từng bước

Bấm từng bước để tự xem cơ chế hoạt động, hoặc bấm “Tự chạy” cho nó tiến mỗi giây một lần. Đổi được dữ liệu đầu vào - không cần đăng nhập.

Học trọn bài này trong ứng dụng

Bài giảng đầy đủ, 24 câu luyện tập chấm tự động, thi thử đúng cấu trúc đề tốt nghiệp (24 trắc nghiệm + 4 Đúng/Sai), bài thực hành máy tự chấm và gia sư AI giải thích chỗ sai.

Mở bài 29 trong ứng dụng

Phần học miễn phí, không cần tạo tài khoản.