Mục lục bài họcĐang ở d06-b3
← A-Level Computer Science
0/30 bài đã học xong
Chương 6 · Algorithms and Data Structures · Bài 3/3 của chương · bài 18/30 của A-Level Computer Science

Program design, testing and maintenance

Thiết kế chương trình, kiểm thử và bảo trì
← Mục lục bài học
Lý thuyết · English

Decomposition and modularity

Break a problem into subproblems, each solved by a procedure (no return value) or function (returns a value). Parameters may be passed by value — the routine gets a copy and the original is unchanged — or by reference, where the routine can change the caller's variable. Local variables exist only inside the routine, which is what makes modules independent and reusable.

Structured English and pseudocode

Use IF … THEN … ELSE … ENDIF, FOR … NEXT, WHILE … ENDWHILE, REPEAT … UNTIL. A WHILE loop may run zero times because the condition is tested first; a REPEAT loop always runs at least once. Choosing the wrong one is a standard exam trap.

Test data, in three kinds

Normal data should be accepted; abnormal (erroneous) data should be rejected; boundary data sits exactly on the edge of the acceptable range and is where most defects hide. For a value that must be $1$–$100$, the boundary tests are $0$, $1$, $100$ and $101$ — and giving both sides of each edge is what earns the marks.

Kinds of testing

Unit or module testing checks one routine; integration testing checks they work together; alpha testing is in-house; beta testing uses real users; acceptance testing checks the requirements are met.

Maintenance

Corrective fixes faults found after release; adaptive changes the program for a new environment or new law; perfective improves performance or usability. Most of a system's lifetime cost is maintenance, not writing it — which is the real argument for clear naming, comments and modular design.

Giải thích tiếng Việt

Phân rã và mô-đun hoá

Chia bài toán thành các bài toán con, mỗi cái do một thủ tục (không trả về giá trị) hoặc một hàm (có trả về giá trị) giải quyết. Tham số có thể truyền theo giá trị — chương trình con nhận một bản sao và biến gốc không đổi — hoặc theo tham chiếu, khi chương trình con thay đổi được biến của nơi gọi. Biến cục bộ chỉ tồn tại bên trong chương trình con, và chính điều đó làm các mô-đun độc lập và dùng lại được.

Mã giả

Dùng IF … THEN … ELSE … ENDIF, FOR … NEXT, WHILE … ENDWHILE, REPEAT … UNTIL. Vòng WHILE có thể chạy $0$ lần vì điều kiện được kiểm TRƯỚC; vòng REPEAT luôn chạy ít nhất một lần. Chọn nhầm loại vòng lặp là một cái bẫy quen thuộc của đề thi.

Dữ liệu kiểm thử, ba loại

Dữ liệu bình thường phải được chấp nhận; dữ liệu bất thường (sai) phải bị từ chối; dữ liệu biên nằm đúng ở mép của khoảng hợp lệ và đó là nơi phần lớn lỗi ẩn nấp. Với một giá trị bắt buộc trong khoảng $1$–$100$, các trường hợp biên là $0$, $1$, $100$ và $101$ — và nêu đủ cả HAI phía của mỗi mép mới được điểm.

Các loại kiểm thử

Kiểm thử đơn vị hoặc mô-đun kiểm một chương trình con; kiểm thử tích hợp kiểm chúng phối hợp với nhau; kiểm thử alpha làm nội bộ; kiểm thử beta dùng người dùng thật; kiểm thử nghiệm thu kiểm xem yêu cầu đã được đáp ứng chưa.

Bảo trì

Sửa lỗi khắc phục sai sót phát hiện sau khi phát hành; thích nghi sửa chương trình cho môi trường mới hoặc quy định mới; hoàn thiện cải thiện hiệu năng hoặc tính dễ dùng. Phần lớn chi phí trong vòng đời một hệ thống nằm ở bảo trì chứ không ở lúc viết — và đó mới là lý lẽ thực sự cho việc đặt tên rõ ràng, viết chú thích và thiết kế mô-đun.

Ví dụ — chọn vòng lặp và thiết kế dữ liệu kiểm thử

Viết mã giả cho một chương trình yêu cầu người dùng nhập điểm từ $0$ đến $100$, lặp lại cho tới khi nhập hợp lệ, rồi in xếp loại: $\ge80$ Giỏi, $\ge65$ Khá, $\ge50$ Đạt, còn lại Chưa đạt.

Sau đó lập bảng dữ liệu kiểm thử.

Giải.

Mã giả

REPEAT
  OUTPUT "Nhập điểm (0-100): "
  INPUT Diem
  IF Diem < 0 OR Diem > 100 THEN
    OUTPUT "Điểm không hợp lệ"
  ENDIF
UNTIL Diem >= 0 AND Diem <= 100

IF Diem >= 80 THEN
  OUTPUT "Giỏi"
ELSE IF Diem >= 65 THEN
  OUTPUT "Khá"
ELSE IF Diem >= 50 THEN
  OUTPUT "Đạt"
ELSE
  OUTPUT "Chưa đạt"
ENDIF

Vì sao dùng REPEAT chứ không WHILE: phải nhập ít nhất một lần trước khi có gì để kiểm tra. Dùng WHILE ở đây sẽ phải khởi tạo Diem bằng một giá trị giả trước vòng lặp — dài hơn và dễ sai hơn.

Vì sao thứ tự IF phải từ CAO xuống THẤP: nếu kiểm $\ge50$ trước thì điểm $90$ sẽ rơi vào nhánh ‘Đạt’ và không bao giờ tới được nhánh ‘Giỏi’.

Bảng dữ liệu kiểm thử

Bình thường: $72$ ⇒ Khá; $55$ ⇒ Đạt; $91$ ⇒ Giỏi. (Chọn giá trị nằm giữa mỗi khoảng để kiểm từng nhánh.)

Bất thường: $-5$ ⇒ báo lỗi và hỏi lại; $150$ ⇒ báo lỗi và hỏi lại; "abc" ⇒ phải bị từ chối (kiểm kiểu dữ liệu).

Biên — quan trọng nhất và phải đi theo CẶP:

$-1$ và $0$ (mép dưới của khoảng hợp lệ)
$100$ và $101$ (mép trên)
$49$ và $50$ (mép Chưa đạt / Đạt)
$64$ và $65$ (mép Đạt / Khá)
$79$ và $80$ (mép Khá / Giỏi)

Vì sao phải đi theo cặp: chỉ thử $80$ thì không phát hiện được lỗi lập trình viên viết > thay vì >=. Cặp $79$–$80$ mới phân biệt được hai trường hợp đó, và đây chính là loại lỗi mà kiểm thử biên sinh ra để bắt.

Bẫy hay mất điểm — Chỉ nêu MỘT giá trị cho mỗi biên. Kiểm thử biên phải cho cả giá trị ngay trong và ngay ngoài mép — $49$ và $50$, $100$ và $101$ — vì lỗi phổ biến nhất ở đây là nhầm > với >=, và một giá trị đơn lẻ không phát hiện được.
Phải nhớ — WHILE kiểm điều kiện trước nên có thể chạy $0$ lần; REPEAT luôn chạy ít nhất một lần. Dữ liệu kiểm thử phải đủ ba loại, và biên phải đi theo cặp. Nhớ ba loại bảo trì và nhớ rằng bảo trì mới chiếm phần lớn chi phí vòng đời.

Đọc xong rồi — làm thử ngay

Bài tập của chương Algorithms and Data Structures gồm 14 câu trắc nghiệm và 3 đề tự luận. Đáp án hiện ngay khi chọn, miễn phí.

Làm bài tập chương →