5.3.1 Tổng quan về phân tích giá trị điểm biên
Phân tích giá trị biên là một kỹ thuật thiết kế ca kiểm thử và được sử dụng để chỉ ra dữ liệu kiểm tra từ đó xây dựng các ca kiểm thử. Theo kinh nghiệm, đa phần các sai sót về lập trình thường xảy ra đối với các dữ liệu biên, những nơi diễn ra tính toán cơ học hoặc sự thao tác dữ liệu phải thay đổi cho hợp lý để chương trình xuất ra kết quả chính xác. Ý tưởng của phân tích giá trị biên là sử dụng giá trị biến đầu vào ở các vị trí : giá trị nhỏ nhất, giá trị lớn nhất, giá trị ngay bên trong biên, giá trị ngay bên ngoài biên, giá trị đại điện thông thường, và các giá trị lỗi. Kết quả mong đợi là khi chương trình làm việc chính xác với các giá trị đặc biệt này thì nó sẽ làm việc chính xác với các giá trị thông thường bên trong miền giá trị. Để kiểm tra một phương thức nào đó việc đầu tiên ta phải xác định dải dữ liệu hợp lệ và không hợp lệ đầu vào cùng với các điều kiện cho chức năng được xét[10].
5.3.2 Lựa chọn các ca kiểm thử sử dụng phân tích giá trị điểm biên
Thiết lập các ca kiểm thử được chỉ ra bởi phân tích giá trị điểm biên phụ thuộc vào cả sự yêu cầu về tính tin cậy của phần mềm và cả những giả thuyết có thể xảy ra trong quá trình kiểm soát lỗi. Tiếp theo sau đây chúng ta sẽ thảo luận về phân tích giá trị điểm biên của đơn biến (single-variable) và đa biến (multi-variable) dựa trên phân loại phân tích giá trị biên.
Xem xét giá trị đầu vào để chỉ ra giá trị biên. Tất cả các giá trị biên này sẽ được kết hợp chặt chẽ trong việc thiết lập các ca kiểm thử. Những giá trị gần biên sẽ được thêm vào và sẽ được sử dụng để kiểm tra. Giá trị gần biên sẽ trợ giúp kiểm soát logic các đường biên của chương trình. Ví dụ khi kiểm tra dải giá trị trong một nhánh hoặc câu lệnh lặp người phát triển có thể sử dụng toán tử nhỏ hơn (<), toán tử nhỏ hơn hoặc bằng (≤), toán tử lớn hơn (>). Các đoạn code được biên dịch nhưng chạy không chính xác với các điều kiện sẽ dẫn đến lỗi. Các giá trị gần giá trị biên phải có trong các ca kiểm thử để kiểm tra các loại lỗi này [4].Trong các ca kiểm thử thêm vào đường biên các giá trị gần biên, quá trình phân tích giá trị biên baseline sẽ gồm một vài giá trị đầu vào tồn tại trên danh nghĩa. Ví dụ sau sẽ minh hoạ cho quá trình phân tích giá trị biên baseline: Xem xét chương trình với một giá trị đầu vào N, dải giá trị của N là : a ≤ N ≤ c. Các ca kiểm thử được chọn trong tập hợp giá trị baseline ={a, a+, b, c-, c}. a+ là giá trị lớn hơn a, c- là giá trị nhỏ hơn c và b là một giá trị tồn tại trên danh nghĩa, b nằm trong khoảng a+ và c-. Trong ví dụ này, quá trình phân tích giá trị biên baseline sẽ chỉ ra năm ca kiểm thử. Minh hoạ bằng hình bên dưới.
baseline
Hình 11 : Tập hợp các giá trị biên baseline cho đơn biến trên một khoảng đầu vào
Nếu như quản lý lỗi là một việc then chốt sau khi kiểm tra phần mềm thì cần phải tăng thêm các ca kiểm thử kiểm tra một cách mạnh mẽ thông qua quá trình phân tích giá trị biên baseline, cần thêm vào các giá trị bên ngoài dải cho phép. Các ca kiểm tra baseline được chỉ ra ở trên sẽ được thêm vào giá trị {a-,c+}, giá trị a- là giá trị bên dưới giá trị chấp nhận a và c+ là giá trị ngay trên giá trị chấp nhận c. Cả hai giá trị {a-,c+} dùng trong các ca kiểm thử cần phải được thực thi để xử lý trường hợp ngoại lệ hoặc để che dấu khuyết điểm code. Quay trở lại với ví dụ trên giá trị đầu vào đơn lúc này sẽ gồm bẩy giá trị hết sức mạnh mẽ: robust={a-, a, a+, b, c-, c, c+}. Minh hoạ bằng hình bên dưới :
baseline robust
Quá trình phân tích giá trị biên baseline hay quá trình phân tích biên rubust đều có thể được áp dụng cho giá trị đầu vào có nhiều dải giá trị. Xem xét biến đầu vào đơn M với hai dải giá trị con liền nhau, dải 1 được là d ≤ M < f và dải 2 là f ≤ M ≤ h. Thiết lập các ca kiểm thử lúc này là kết hợp tất cả các ca kiểm thử được chỉ ra khi cách áp dụng quá trình phân tích giá trị biên đối với từng dải giá trị riêng lẻ. Do vậy kết hợp kết quả tất cả các ca kiểm thử áp dụng cho từng dải riêng rẽ ta được :
Mbaseline= {d, d+, e, f-, f} {f, f+, g, h-, h}∪
= {d, d+, e, f-, f, f+, g, h-, h}
Áp dụng phân tích giá trị biên robust làm M baseline tăng thêm các giá trị {d-, h+} mang lại kết quả Mrobust= {d-, d, d+, e, f-, f, f+, g, h-, h, h+} được minh hoạ bằng hình bên dưới
baseline robust augmentation
Hình 13 : Tập hợp các giá trị baseline và rubust trường hợp đơn biến trên hai khoảng đầu vào
Thêm vào nhiều dải giá trị con hiển nhiên sẽ làm tăng số ca kiểm thử. Đối với hai dải giá trị liền nhau của một biến đầu vào, phân tích giá trị biên baseline chỉ ra 9 ca kiểm thử và phân tích giá trị biên rubust chỉ ra 11 ca kiểm thử.
5.3.4 Phân tích giá trị biên đa biến (Multi – Variable BVA)
Đối với bài toán đa biến quá trình phân tích giá trị biên lựa chọn ca kiểm thử cần phải xem xét lỗi có thể xảy ra, trong bài viết này ta sẽ đề cập đến lỗi tại biên với đa biến đầu vào là một kiểu lỗi (ta sẽ gọi là multiple-fault). Đối với kiểu lỗi multiple-fault [4] được cho rằng nhiều lỗi đồng thời xảy ra, do vậy ta sẽ thêm vào các ca kiểm thử để soát lỗi trên đồng thời nhiều biến.
Lấy ra từ ví dụ đơn biến ở trên, xét bài toán với hai biến đầu vào N và M, với dải giá trị của N: a ≤ N ≤ c và giá trị của M trải dài trên hai dải, dải #1:d ≤ M < f , dải #2: f ≤ M ≤ h. Như dã thảo luận ở trên, các ca kiểm thử đơn biến đã chỉ ra đối với N và M là :
Nbaseline= {a, a+, b, c-, c}
Mbaseline= {d, d+, e, f-, f, f+, g, h-, h}
Các ca kiểm thử phân tích giá trị biên đa biến sử dụng cách phân tích các đường biên của một biến trong khi các biến khác được giữ là một giá trị danh nghĩa. Hợp tất cả
các ca kiểm thử áp dụng cho từng biến đầu vào ta được tập các ca kiểm thử áp dụng cho đa biến đầu vào. Trong ví dụ trên ta sẽ áp dụng cho từng biến đầu vào trên từng dải giá trị con. Bài toán có hai giá trị đầu vào, các ca kiểm thử sẽ gồm các cặp giá trị đầu vào (m,n) trong đó n là thành phần của Nbaseline và m sẽ là thành phần của Mbaseline .
Quan sát sơ đồ dưới đây :
Hình 14 : Tập giá trị baseline và robust của biến N trong trường hợp hai biến đầu vào
Trong hình biểu diễn trên ta biểu diễn giá trị m thay đổi(m thay đổi trong miền Mbaseline), tại dải thứ nhất (d≤ m <f) m được biểu diễn bằng giá trị e, tại dải thứ hai (f ≤ m
≤ h) m được biểu diễn bằng g, giữ nguyên giá trị n, n được biểu diễn bằng giá trị b. Quan sát sơ đồ ta nhận thấy có 9 ca kiểm thử được chỉ ra, tương ứng với các giá trị giao điểm của đường thẳng qua b và giao với các đường trong miền giá trị thay đổi của m.
Tiếp theo cố định giá trị m tại hai dải giá trị, cho n thay đổi trong miền Nbaseline, biểu diễn n bằng giá trị b, (a≤ b ≤ c). Quan sát sơ đồ biểu diễn dưới đây :
Hình 15 : Tập hợp giá trị baseline và rubust trên hai khoảng của biến M trong trường hợp hai biến đầu vào
Trong trường hợp này ta nhận được 10 ca kiểm thử.
Tổng hợp cả 2 trường hợp ta nhận được sơ đồ sau :
Hình 16 : Tổng hợp tất cả các giá trị của hai biến N và M trên hai khoảng đầu vào
Trường hợp 1 cho ta 9 ca, trường hợp 2 cho ta 10 ca, tổng hợp cả 2 trường hợp cho ta 19 ca, nhưng tại các vị trí (e,b) và (g,b) được lặp lại 2 lần, nên tổng cả 2 trường hợp ta có 17 ca kiểm thử.
Đối với việc kiểm tra mạnh mẽ (rubustness), áp dụng cách thức như ta đã làm với từng biến trước đó, kết quả đã được chỉ ra trong Mrubust và Nrubust. Lưu ý rằng trong quá trình phân tích baseline với từng biến thì đồng thời 6 giá trị rubust cũng đã được chỉ ra (quan sát trên hình vẽ). Như vậy đến thời điểm này ta đã có tổng số 23 ca kiểm thử tất cả. Các ca kiểm thử trên dải giá trị không hợp lệ cần phải được lựa chọn để kiểm soát đồng thời với cả hai biến. Quá trình phân tích giá trị biên multiple-fault sẽ được bắt đầu với tập hợp giá trị trong Mbaseline và Nbaseline trong trường hợp các đường biên không được kiểm tra, còn trong trường hợp việc kiểm tra các đường biên được ưu tiên cao thì ta sẽ sử dụng với tập giá trị Mrubust và Nrubust . Tương ứng với hai trường hợp vừa nêu ta có ước lượng tích đề-các (cartesian) Mbaselien x Nbaselien xác định số ca kiểm thử cho baseline multiple-fault, và tích đề các Mrubust x Nrubust xác định số ca kiểm thử cho rubust multiple-fault.
Với hai tập giá trị M và N, tích đề-các của M và N được định nghĩa là :
M x N = {(m,n) | m ε M^n ε N}
M x N là tập tất cả các cặp phần tử (m,n) được lấy ra từ tập M và tập N. Do đó, nếu tập M có x phần tử và tập N có y phần tử, kết quả của tập M x N sẽ gồm x * y phần tử.
Trở lại bài toán ví dụ, hình dưới đây sẽ biểu diễn tổng hợp các ca kiểm thử phân tích giá trị biên baseline và rubust được chỉ ra cho kiểu lỗi multiple-fault của bài toán.
Hình 17 : Tổng hợp toán bộ giá trị baseline, robust trường hợp đa biến đầu vào trên hai khoảng
Số lượng các ca kiểm thử tăng lên đáng kể, 45 ca baseline được chỉ ra và trong trường hợp xấu nhất (worst-case) được thêm 32 ca rubust.
Tổng hợp các ca kiểm thử cho bài toán 2 biến với các mức yêu cầu về tính tin cậy ta có bảng như sau :
Bảng 1 : Tổng hợp các ca kiểm thử theo mức tin cậy .
Nhận thấy rằng, giả thuyết tình huống bài toán có nhiều lỗi đồng thời xảy ra cùng một lúc đã dẫn đến khá nhiều ca kiểm thử, đặc biệt nếu như bài toán xét trên nhiều dải giá trị thì số lượng ca kiểm thử tăng lên là đáng kể.
5.3.5 Kết luận
Từ những phân tích đã trình bày rõ ràng phân tích giá trị điểm biên có nhiều ưu điểm quá trình phân tích giá trị điểm biên để chỉ ra các kiểm tra là một việc dễ sử dụng, thậm chí có các giá trị biên đầu vào còn được mô tả một cách rõ ràng trong tài liệu yêu cầu. Với phân tích giá trị biên, ta có thể điều chỉnh số ca kiểm thử do đó tài nguyên được sử dụng cho nghiên cứu còn phụ thuộc vào đòi hỏi về tính chất mạnh của phần mềm. Phân tích giá trị biên có lợi cho sự bắt đầu các kỹ thuật kiểm thử khác. Tài liệu thảo luận về phân tích giá trị biên thường hoà lẫn và có liên hệ với kỹ thuật kiểm thử hộp đen phân hoạch tương đương.
Tuy nhiên phân tích giá trị điểm biên có thể ảnh hưởng tới việc nhận ra các lỗi. So với việc kiểm tra giá trị ngẫu nhiên và giá trị phân hoạch tương đương thì phân tích giá trị biên có số lần kiểm tra nhiều hơn 6 lần so với kiểm tra ngẫu nhiên và gấp 2 lần so với kiểm tra theo phân hoạch tương đương. Giá cả để kiểm tra cũng tăng theo số ca kiểm thử. Kỹ thuật phân tích giá trị biên cung cấp một quá trình có hệ thống cho việc đánh giá mức độ hoàn thành và chất lượng của sản phẩm phần mềm. Đôi khi bằng cách phân tích giá trị biên ta có thể tìm ra các ca kiểm thử dư thừa trong tập hợp ca kiểm thử được chỉ ra. Phân tích giá trị biên cung cấp nền tảng cơ bản cho việc học các kỹ thuật khác, cụ thể là kỹ thuật phân hoạch tương đương, trong việc chỉ ra lỗi phân tích giá trị biên có hiệu quả như một kỹ thuật kiểm tra chức năng.
CHƯƠNG 6. THỰC NGHIỆM
6.1 Ví dụ một chương trình đơn giản
Nếu ta biết cấu trúc của chương trình ta có thể thiết kế các ca kiểm thử đảm bảo bao phủ : câu lệnh, nhánh, đường đi và bao phủ các điều kiện.
Chúng ta sẽ xem xét một chương trình với cấu trúc đơn giản, phân tích chương trình và đề xuất các ca kiểm thử để đảm bảo toàn bộ câu lệnh, toàn bộ nhánh, toàn bộ luồng đi qua chương trình đều được bao phủ. Chương trình có hai điều kiện, theo sau điều kiện một sẽ có hai nhánh rẽ. Nếu điều kiện một là “true” sẽ thi hành khối lệnh A thực hiện công việc A. Nếu điều kiện một là “false” sẽ thi hành khối lệnh B thực hiện công việc B. Xét đến điều kiện hai, nếu điều kiện hai “true” sẽ thực hiện khối lệnh C, còn nếu điều kiện hai “false” sẽ kết thúc chương trình Mô tả ví dụ bằng sơ đồ dưới đây.
Hình 18 : Ví dụ cấu trúc một chương trình đơn giản
Khi chạy các unit test ta mong muốn kiểm tra được tất cả các công việc trong các khối lệnh trong chương trình. Cụ thể trong ví dụ đang xét cần phải kiểm tra việc thực hiện của các khối lệnh A, B, C xảy ra theo đúng điều kiện, khối lệnh trong từng công việc phải hoạt động đúng. Hình vẽ sau mô tả nổi bật các công việc cần phải kiểm tra.
Hình 19 : Các công việc cần thực hiện (tô đậm)
6.1.1 Xây dựng các ca kiểm thử cho chương trình trên
Dựa vào cấu trúc của chương trình nguồn như trên đề xuất các ca kiểm thử kiểm tra code trong từng nhánh có được thực thi hay không.
Test case 1 :Công việc A được thực hiện khi điều kiện một “true” do đó để kiểm tra việc thực thi công việc A chúng ta cần gán sao cho điều kiện một “true”.
Hình 20 : Test case 1 kiểm tra công việc A
Test case 2 :Khi điều kiện một “false” câu lệnh rẽ nhánh sẽ thực hiện công việc trong khối lệnh B. Để kiểm tra việc thực thi công việc B ta cần gán cho điều kiện một là “false”
Testcase #1: Condition-1 là “true”. Testcase #2: Condition-1 là “false“
Test case 3 :Xét đến điều kiện hai.Khi điều kiện hai là “true” thì khối lệnh C sẽ được thực hiện. Do đó kiểm tra việc thực thi công việc C ta sẽ gán cho điều kiện 2 là “true”.
Hình 22 : Test case 3 kiểm tra công việc C
Testcase #3: condition-2 là “true”.
Để kiểm tra các công việc A, B, C ba test case đã được đề xuất. Tuy nhiên có thể dễ dàng nhận thấy điều kiện 1 và là 2 bộ phận độc lập nhau.
Hình 23 : Hai điều kiện một và hai là độc lập nhau
Do đó bao phủ toàn bộ 3 công việc này ta chỉ cần dùng đến 2 test case là 100% câu lệnh được bao phủ. Test case 1 kiểm tra đồng thời công việc A và công việc C
Hình 24 : Kiểm tra đồng thời công việc A và công việc C trong cùng 1 test case