0

Kiểm Thử Hộp Trắng

1. Thế nào là kiểm thử hộp trắng

  • Kiểm thử hộp trắng: Là kỹ thuật kiểm thử dựa trên đặc tả bên trong của chương trình, dựa vào mã nguồn, cấu trúc chương trình.
  • Kiểm thử hộp trắng thường phát hiện các lỗi lập trình, khó thực hiện, chi phí cao.
  • Với các module quan trọng, thực thi việc tính toán chính của hệ thống, phương pháp này là cần thiết.

2. Một số kĩ thuật kiểm thử hộp trắng phổ biến

2.1 Kiểm thử luồng dữ liệu

  • Mục tiêu của chương trình là xử lý dữ liệu. Dữ liệu của chương trình là tập nhiều biến độc lập.
  • Phương pháp kiểm thử dòng dữ liệu là 1 công cụ mạnh để phát hiện việc dùng không hợp lý các biến do lỗi coding phần mềm gây ra: * Phát biểu gán hay nhập dữ liệu vào biến không đúng. * Thiếu định nghĩa biến trước khi dùng. * Tiên đề sai (do thi hành sai luồng thi hành). * ...
  • Mỗi biến nên có chu kỳ sống tốt lành thông qua trình tự 3 bước : được tạo ra, ₫ược dùng và được xóa đi.
  • Chỉ có những lệnh nằm trong tầm vực truy xuất biến mới có thể truy xuất/xử lý được biến.

Phân tích đời sống của 1 biến

  • Các lệnh truy xuất 1 biến thông qua 1 trong 3 hành động sau :
    • d (define): định nghĩa biến, gán giá trị xác định cho biến (nhập dữ liệu vào biến cũng là hoạt động gán trị cho biến
    • r(reference) : tham khảo giá trị của biến (thường thông qua biểu thức).
    • u(undefine) : hủy (xóa bỏ) biến đi.
  • Như vậy nếu ký hiệu ~ là miêu tả trạng thái mà ở đó biến chưa tồn tại, ta có 3 khả năng xử lý đầu tiên trên1 biến:
    • ~d : biến chưa tồn tại rồi được định nghĩa với giá trị xác định.
    • ~r : biến chưa tồn tại rồi được dùng ngay (trị nào ?)
    • ~u : biến chưa tồn tại rồi bị hủy (không bình thường).
  • 3 hoạt động xử lý biến khác nhau kết hợp lại tạo ra 9 cặp đôi :
    • dd : biến được định nghĩa rồi định nghĩa nữa : hơi lạ, có thể đúng và chấp nhậnđược, nhưng cũng có thể có lỗi lập trình.
    • dr : biến được định nghĩa rồi được dùng : trình tự đúng và bình thường.
    • du : biến được định nghĩa rồi bị xóa bỏ : hơi lạ, có thể đúng và chấp nhận được, nhưng cũng có thể có lỗi lập trình.
    • rd : biến được dùng rồi định nghĩa giá trị mới : hợp lý.
    • rr : biến được dùng rồi dùng tiếp : hợp lý.
    • ru : biến được dùng rồi bị hủy : hợp lý.
    • ud : biến bị xóa bỏ rồi được định nghĩa lại : chấp nhận được.
    • ur : biến bị xóa bỏ rồi được dùng : lỗi.
    • uu : biến bị xóa bỏ rồi bị xóa nữa : có lẽ là lỗi lập trình.
  • Đồ thị dòng dữ liệu
    • Là một trong nhiều phương pháp miêu tả các kịch bản đời sống khác nhau của các biến.
    • Qui trình xây dựng đồ thị dòng dữ liệu dựa trên qui trình xây dựng đồ thị dòng điều khiển của module cần kiểm thử.

Qui trình kiểm thử dòng dữ liệu của 1 module gồm các bước:

  • Từ TPPM cần kiểm thử, xây dựng đồ thị dòng điều khiển tương ứng, rồi chuyển thành đồ thị dòng điều khiển nhị phân, rồi chuyển thành đồ thị dòng dữ liệu.
  • Tính độ phức tạp Cyclomatic của đồ thị (C = P +1).
  • Xác định C đường thi hành tuyến tính độc lập cơ bản cần kiểm thử
  • Lặp kiểm thử đời sống từng biến dữ liệu : mỗi biến có thể có tối đa C kịch bản đời sống khác nhau. trong từng kịch bản đời sống của 1 biến, kiểm thử xem có tồn tại cặp đôi hoạt ộng không bình thường nào không ? Nếu có hãy ghi nhận để lập báo cáo kết quả và phản hồi. VD: Như đồ thị trên ta có 2 điểm rẽ nhánh nên: C= 2+1=3.

2.2 Kiểm thử luồng điều khiển

  • Đường thi hành (Execution path) : là 1 kịch bản thi hành đơn vị phần mềm tương ứng : danh sách có thứ tự các lệnh được thi hành ứng với 1 lần chạy cụ thể của đơn vị phần mềm, bắt đầu từ điểm nhập của đơn vị phần mềm đến điểm kết thúc của đơn vị phần mềm.
  • Mục tiêu của phương pháp kiểm thử luồng điều khiển là đảm bảo mọi đường thi hành của đơn vị phần mềm cần kiểm thử đều chạy đúng.
  • Rất tiếc trong thực tế, công sức và thời gian để đạt mục tiêu trên đây là rất lớn, ngay cả trên những đơn vị phần mềm nhỏ.
  • Ví dụ: cho đoạn code sau for (i=1; i<=1000; i++) for (j=1; j<=1000; j++) for (k=1; k<=1000; k++) doSomethingWith(i,j,k); Có 1 đường thi hành dài 1000 * 1000 * 1000 = 1 tỉ lệnh gọi doSomethingWith(i,j,k) khác nhau. Thí dụ đoạn code gồm 32 lệnh if else sau: if (c1) s11 else s12; if (c2) s21 else s22; if (c3) s31 else s32; ... if (c32) s321 else s322; Có 2^32 = 4 tỉ đường thi hành khác nhau.
  • Mà cho dù có kiểm thử hết được toàn bộ các đường thi hành thì vẫn không thể phát hiện những đường thi hành cần có nhưng không (chưa) được hiện thực. VD: if (a>0) doIsGreater(); if (a==0) dolsEqual(); //thiếu việc xử lý trường hợp a < 0 - if (a<0) dolsLess(); Một đường thi hành đã kiểm tra là đúng nhưng vẫn có thể bị lỗi khi dùng thiệt (trong 1 vài trường hợp đặc biệt) : int blech (int a, int b) { return a/b; } Khi kiểm tra, ta chọn b <> 0 thì chạy đúng, nhưng khi dùng thật trong trường hợp b = 0 thì hàm blech bị lỗi.
  • Do đó, ta nên kiểm thử số test case tối thiểu mà kết quả độ tin cậy tối đa.
  • Phủ kiểm thử (Coverage) : là tỉ lệ các thành phần thực sự được kiểm thử so với tổng thể sau khi đã kiểm thử các test case được chọn. Phủ càng lớn thì độ tin cậy càng cao.
  • Thành phần liên quan có thể là lệnh, điểm quyết định, điều kiện con, đường thi hành hay là sự kết hợp của chúng.
    • Phủ cấp 0 : kiểm thử những gì có thể kiểm thử được, phần còn lại để người dùng phát hiện và báo lại sau. Đây là mức độ kiểm thử không thực sự có trách nhiệm.
    • Phủ cấp 1 : kiểm thử sao cho mỗi lệnh được thực thi ít nhất 1 lần. Với hàm foo bện cạnh, ta chỉ cần 2 test case sau đây là đạt 100% phủ cấp 1 :
  • Ta có 2 test case của phủ cấp 1: 1.foo(0,0,0,0) trả về 0 và 2. foo(1,1,1,1) trả về 1 => Nhưng không phát hiện lỗi chia 0 ở hàng lệnh 8.
    • Phủ cấp 2 : kiểm thử sao cho mỗi điểm quyết định đều được thực hiện ít nhất 1 lần cho trường hợp TRUE lẫn FALSE. Ta gọi mức kiểm thử này là phủ các nhánh (Branch coverage).Phủ các nhánh đảm bảo phủ các lệnh. Với 2 test case xác định trong slide trước, ta chỉ đạt được 75% phủ các nhánh. Nếu thêm test case 3 : 3.foo(1,2,1,2), thì mới đạt 100% phủ các nhánh.
    • Phủ cấp 3 : kiểm thử sao cho mỗi điều kiện luận lý con (subcondition) của từng điểm quyết định đều được thực hiện ít nhất 1 lần cho trường hợp TRUE lẫn FALSE. Ta gọi mức kiểm thử này là phủ các điều kiện con (subcondition coverage). Phủ các điều kiện con chưa chắc đảm bảo phủ các nhánh -
    • Phủ cấp 4 : kiểm thử sao cho mỗi điều kiện luận lý con (subcondition) của từng điểm quyết định đều được thực hiện ít nhất 1 lần cho trường hợp TRUE lẫn FALSE & điểm quyết định cũng được kiểm thử cho cả 2 nhánh. Ta gọi mức kiểm thử này là phủ các nhánh & điều kiện con (branch & subcondition coverage).
  • Kết luận: Phương pháp này rất hữu hiệu trong việc xây dựng test case để phủ được hết các trường hợp Nguồn: http://www.cse.hcmut.edu.vn/~hiep/KiemthuPhanmem/LyThuyetViet/Chuong03.pdf http://www.cse.hcmut.edu.vn/~hiep/KiemthuPhanmem/LyThuyetViet/Chuong04.pdf

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí