Kiểm Thử Điều Kiện – Condition Testing Là Gì?
Kiểm thử điều kiện – Condition testing (còn gọi là condition coverage) là một phương pháp kiểm thử phần mềm nhằm đảm bảo rằng tất cả các điều kiện logic trong source code đã được kiểm tra và đánh giá ít nhất một lần trong quá trình kiểm thử. Mục tiêu của kiểm thử điều kiện là đảm bảo rằng các điều kiện logic trong chương trình hoạt động đúng cách và không gặp phải lỗi do các điều kiện không hoạt động như mong đợi.
Condition testing thường đánh giá các điều kiện logic, cụ thể là các biểu thức điều kiện, để đảm bảo rằng tất cả các khả năng của chúng đã được kiểm tra. Các khả năng này thường liên quan đến các toán tử logic như AND, OR, NOT và các so sánh (ví dụ: bằng, khác, lớn hơn, nhỏ hơn).
Phương pháp này đo lường bằng cách xác định các điểm trong source code mà chứa các điều kiện logic, sau đó kiểm tra xem các điều kiện đó đã được thực hiện với tất cả các giá trị có thể của biến đầu vào hay chưa. Điều này đảm bảo rằng các điều kiện không chỉ được kiểm tra với các giá trị đầu vào thỏa mãn điều kiện (TRUE) mà còn với các giá trị đầu vào không thỏa mãn điều kiện (FALSE).
Condition testing giúp tìm ra các lỗi trong logic của chương trình, chẳng hạn như việc thiếu sót một số trường hợp trong quyết định logic, làm tăng độ tin cậy và chất lượng của phần mềm. Nó thường được sử dụng trong quá trình kiểm thử đơn vị (unit testing) và kiểm thử tích hợp (integration testing).
Tại Sao Cần Kiểm Thử Điều Kiện
Ở bài viết trước, mình đã giới thiệu về kiểm thử quyết định. Trong đó quyết định được kiểm thử theo cả hai cách TRUE và FALSE. Nhưng chúng ta vẫn chưa thảo luận về cách đưa ra quyết định. Các quyết định có thể đơn giản – chẳng hạn như (a > b) hoặc phức tạp tùy ý như sau:
(a>b) || (x+y==-1) && (d) != TRUE
Giả thuyết đặt ra là sai sót có thể ẩn giấu trong các điều kiện nguyên tử chưa được kiểm tra, mặc dù toàn bộ quyết định đã được kiểm tra theo cả hai cách. Như mọi khi, dữ liệu kiểm tra phải được chọn để đảm bảo rằng mỗi điều kiện nguyên tử thực sự bị buộc phải TRUE và FALSE lúc này hay lúc khác. Rõ ràng, biểu thức quyết định càng phức tạp thì chúng ta càng cần thực hiện nhiều trường hợp thử nghiệm hơn để đạt được mức độ bao phủ này.
Ví Dụ Về Kiểm Thử Điều Kiện
Bao phủ quyết định và điều kiện sẽ luôn giống hệt nhau khi tất cả các quyết định được thực hiện bằng các biểu thức nguyên tử đơn giản. Ví dụ: đối với điều kiện if (a == 1) {}, phạm vi điều kiện sẽ giống với phạm vi quyết định. Ở đây, chúng ta sẽ xem xét một số ví dụ về các biểu thức phức tạp, tất cả đều có giá trị TRUE hoặc FALSE.
x
Đầu tiên, được hiển thị ở trên, có một biến Boolean duy nhất, x, có thể đánh giá là TRUE hoặc FALSE. Lưu ý rằng trong một số ngôn ngữ, nó thậm chí không nhất thiết phải là biến Boolean. Ví dụ: nếu đây là ngôn ngữ C thì nó có thể là một số nguyên, vì bất kỳ giá trị nào khác 0 đều tạo thành giá trị TRUE và số 0 được coi là FALSE. Điều quan trọng cần lưu ý là nó là một nguyên tử và nó cũng là toàn bộ biểu thức.
D && F
Điều kiện thứ hai, được hiển thị ở trên, có hai điều kiện nguyên tử, D và F, được kết hợp với nhau bằng toán tử AND để xác định giá trị của toàn bộ biểu thức.
(A || B) && (C == D)
Thứ ba là một chút khó khăn. Trong trường hợp này, A và B đều là các điều kiện nguyên tử được kết hợp với nhau bằng toán tử OR để tính giá trị cho biểu thức con (A || B). Vì A và B đều là điều kiện nguyên tử nên biểu thức con (A || B) không thể là điều kiện nguyên tử. Tuy nhiên, (C == D) là một điều kiện nguyên tử vì nó không thể bị chia nhỏ thêm nữa. Điều đó tạo nên tổng cộng ba điều kiện nguyên tử.
(a>b)||(x+y==-1)&&((d)!=TRUE)
Trong biểu thức phức hợp này, nó có ba điều kiện nguyên tử. Điều kiện thứ nhất, (a>b), là điều kiện nguyên tử không thể chia nhỏ hơn nữa. Thứ hai, (x+y == -1), là một nguyên tử tuân theo quy tắc tương tự. Trong biểu thức phụ cuối cùng, (d!=TRUE) là điều kiện nguyên tử.
Trong mỗi ví dụ trước, chúng ta cần đưa ra đủ các trường hợp thử nghiệm để mỗi điều kiện nguyên tử này đều được thử nghiệm trong đó nó đánh giá cả TRUE và FALSE. Nếu chúng ta kiểm tra ở mức độ đó, chúng ta sẽ đạt được phạm vi điều kiện 100%. Điều đó có nghĩa như sau:
- x, D, F, A và B sẽ cần một trường hợp kiểm thử được đánh giá là TRUE và một trường hợp kiểm thử được đánh giá là FALSE.
- (C==D) cần hai trường hợp kiểm thử.
- (a>b) cần hai trường hợp kiểm thử.
- (x+y==-1) cần hai trường hợp kiểm thử.
- ((d)!=TRUE) cần hai trường hợp kiểm thử.
Liệu kiểm thử vậy đã đủ chưa? Có lẽ không! Hãy xem xét mã giả sau:
A && B
Để đạt được phạm vi bao phủ điều kiện, chúng ta cần đảm bảo rằng mỗi điều kiện nguyên tử đều có cả TRUE và FALSE trong ít nhất một trường hợp kiểm thử. Test 1: A == FALSE, B == TRUE ⇒ FALSE Test 2: A == TRUE, B == FALSE ⇒ FALSE Giả sử rằng trường hợp thử nghiệm đầu tiên của chúng ta có các giá trị được nhập vào để làm cho A bằng FALSE và B bằng TRUE. Điều đó làm cho toàn bộ biểu thức có giá trị FALSE, vì vậy chúng ta thực thi mệnh đề else. Đối với thử nghiệm thứ hai, chúng ta đảo ngược điều đó để A được đặt thành TRUE và B được đặt thành FALSE. Điều đó đánh giá là FALSE, vì vậy chúng ta lại thực hiện mệnh đề else.
Chúng ta đã đạt được phạm vi bao phủ điều kiện hay chưa? A được đặt cả TRUE và FALSE, B cũng vậy. Chắc chắn, chúng ta đã đạt được phạm vi điều kiện. Nhưng hãy tự hỏi, chúng đã đạt được phạm vi bao phủ quyết định chưa? Câu trả lời là không! Với hai trường hợp kiểm thử trên chúng ta đều đưa ra quyết định là FALSE. Để đạt được phạm vi bao phủ quyết định, chúng ta cần kiểm thử trường hợp TRUE. Rõ ràng, bao phủ điều kiện không tự động đảm bảo bao phủ quyết định.
Để giải quyết những nhược điểm của kỹ thuật kiểm thử điều kiện nêu ở trên, hãy cùng mình tìm hiểu thêm hai cấp độ kiểm thử mang lại phạm vi bao phủ mạnh hơn trong các bài viết tiếp theo nhé.
Happy Testing!