Giới thiệu về kiểm thử hộp trắng (Whitebox testing)

Kiểm thử dựa trên source code, thuật toán (algorithm)

7 min read
Bởi Michael vu
Giới thiệu về kiểm thử hộp trắng (Whitebox testing)

Khái niệm

Kiểm thử dựa trên source code, thuật toán (algorithm)

Đặc điểm

  • Người test phải có kiến thức về source code, thuật toán để hiểu
  • Đòi hỏi nhiều effort để thực hiện đầy đủ.
  • Do test case được xây dựng dựa trên source code và thuật toán, những case chưa được xử lý bởi source code tất nhiên cũng sẽ không được kiểm tra. Nghĩa là không phát hiện ra được các case bị lack.
  • Có khả năng bỏ qua những case lỗi do dữ liệu. Ví dụ lỗi chia 0.

Whitebox test sử dụng 2 kỹ thuật chính là Kiểm thử luồng xử lý (Control flow testing) và kiểm thử luồng dữ liệu (Data flow testing)

Kiểm thử luồng điều khiển (Control flow Testing)

Dựa trên việc liệt kê và kiểm thử các luồng thực thi (Execution path) có thể có của đơn vị kiểm thử. 1 Luồng thực thi là một danh sách có thứ tự của các lệnh được thực hiện trong 1 lần chạy của đơn vị kiểm thử, từ lúc bắt đầu cho đến khi kết thúc của đơn vị kiểm thử.

Để xác định các luồng thực thi kỹ thuật Đồ thị luồng thực thi (Control flow Graph) thường được sử dụng.

Tuy nhiên, số lượng luồng thực thi thường rất lớn kể cả với những đơn vị kiểm thử đơn giản, cho nên gần như không bao giờ thực hiện đầy đủ được phương pháp kiểm thử này.
Thay vào đó, mức độ tin cậy của kiểm thử được xác định dựa trên mức độ che phủ của kiểm thử (Test coverage).

Mức độ che phủ (Test coverage) là tỉ lệ giữa số thành phần đã được kiểm thử trên tổng số các thành phần của đơn vị kiểm thử.

Đồ thị luồng thực thi (Control flow Graph)

Đồ thị luồng thực thi được xây dựng bằng cách mô hình hóa source code/thuật toán của đơn vị kiểm thử dưới dạng đồ thị. Trong đó mỗi loại lệnh được mô tả bằng cú pháp riêng, gồm có:

  • Điểm xuất phát (Entry point)
  • Khối xử lý (Process Block)
  • Điểm quyết định (Decision Point)
  • Điểm nối (Junction Point)
  • Điểm kết thúc (End Point)

Biễu diễn các điều khiển cơ bản:
Biễu diễn các điều khiển cơ bản

Biểu diễn 1 đoạn code đơn giản

Mỗi đồ thị luồng thực thi cho phép xác định mức độ phức tạp của đồ thị (Cyclomatic). Độ phức tạp được tính theo công thức sau:

  • V(G) = E - N + 2 với E là số cung, N là số nút
    hoặc
  • V(G) = P + 1, nếu đồ thị chỉ chứa các điểm quyết định (Decision Point), và P là số điểm quyết định.

Về lý thuyết, khi thực hiện kiểm thử luồng điều khiển, cần thực hiện theo các bước:

  • Dựng đồ thị luồng thực thi
  • Xác định độ phức tạp của đồ thị (giả sử là C)
  • Xác định đúng C luồng thực thi độc lập.
  • Xây dựng test case cho C luồng thực thi
  • Kiểm thử

Phương pháp để xác định các luồng thực thi độc lập như sau:

  • Xác định đường cơ bản, thường là đường thực thi thường xuyên nhất
  • Để chọn được đường thứ 2, thay đổi cung xuất phát của nút quyết định đầu tiên và cố gắng giữ lại tối đa phần còn lại.
  • Để chọn được đường thứ 3, thay đổi cung xuất phát của nút quyết định thứ 2 và cố gắng giữa lại tối đa phần còn lại
  • Lặp lại với các nút quyết định tiếp theo cho đến khi không còn nút quyết định nào trong đường cơ bản nữa.
  • Lặp lại các bước 2, 3, 4 với các đường vừa tìm được cho đến khi đạt đủ C luồng thực thi.
Mức độ che phủ của kiểm thử (Test coverage)

Có các mức độ như sau:

  • Method coverage: Tỉ lệ method được gọi trong quá trình test trên tổng số method

  • Statement coverage: Tỉ lệ dòng lệnh được thực thi trong quá trình test trên tổng số dòng lệnh

  • Branch coverage: tỉ lệ số điểm quyết định được kiểm tra với cả 2 trường hợp (true/false) trên tổng số khả năng của tất cả các điểm quyết định.

  • Condition coverage: tỉ lệ số biểu thức logic được kiểm tra (với cả 2 trường hợp và với cả những biểu thức logic con) trên tổng số khả năng của tất cả các biểu thức logic.

Kiểm thử luồng dữ liệu (Data flow testing)

Tương tự như kiểm thử luồng điều khiển, nhưng thay vì dựa trên đồ thị luồng xử lý, kiểm thử luồng dữ liệu dựa trên đồ thị luồng dữ liệu (Data flow Graph). Luồng dữ liệu được xây dựng dựa trên việc các sự kiện liên quan đến biến trong phạm vi của nó (scope). có 3 sự kiện liên quan đến 1 biến là:

  • Khai báo hoặc gán giá trị cho biến (declare - d)
  • Sử dụng biến (use - u)
  • Hủy biến (kill - k)

Nếu kí hiệu trạng thái chưa khởi tạo biến là ~, có thể mô tả 3 khả năng xử lý đầu tiên với 1 biến:

  • ~d: biến chưa khởi tạo và thực hiện khai báo biến => Đúng
  • ~u: biến chưa khởi tạo và sử dụng biến => sai
  • ~k: biến chưa khởi tạo và hủy biến => có thể đúng có thể sai.

Đồng thời, với 3 sự kiện, có thể tạo ra 9 khả năng như sau:

  • dd: khai báo và khai báo lại => không hợp lý, có khả năng sai
  • du: khai báo rồi sử dụng => Đúng
  • dk: khai báo rồi hủy biến => có khả năng sai
  • ud: sử dụng rồi khai báo/gán giá trị mới => Đúng
  • uu: sử dụng rồi tiếp tục sử dụng => Đúng
  • uk: sử dụng rồi hủy biến => đúng
  • kd: hủy rồi khai báo/gán giá trị mới => Đúng
  • ku: hủy rồi sử dụng biến => sai
  • kk: hủy rồi tiếp tục hủy => sai.

Dựa trên 3 sự kiện (d-u-k) kết hợp với đồ thị luồng xử lý (Control flow Graph) của đơn vị kiểm thử, chúng ta có thể xây dựng được các đồ thị luồng dữ liệu (Data flow Graph) cho từng biến trong đơn vị kiểm thử.

Với luồng dữ liệu của 1 biến, chúng ta thực hiện 2 bước kiểm thử: Kiểm thử tĩnh (static) và kiểm thử động (dynamic).

  • Kiểm thử tĩnh (static) là thực hiện kiểm tra trên đồ thị luồng dữ liệu được dựng lên, có cạnh (xử lý) nào có khả năng sai hoặc gây lỗi. Ví dụ: kk, ku,...

Kiểm thử tĩnh (static) có hạn chế là không phát hiện ra được một số lỗi:

  • Lỗi Index Out of Bound
  • Một số xử lý không hợp lệ thực tế không bao giờ xảy ra khi thực thi.
  • Kiểm thử động (dynamic) là dựa trên luồng xử lý để xây dựng testcase và kiểm thử. Phương pháp xây dựng testcase cũng dựa trên độ phức tạp của đồ thị tương tự như kỹ thuật kiểm thử luồng điều khiển.

Tổng kết

  • Kiểm thử hộp trắng (Whitebox Test) là phương pháp phù hợp cho Developer thực hiện Unit Test và Self check chức năng.

  • Mức độ tin cậy của kiểm thử xác định bởi độ che phủ (Test coverage) của kiểm thử.

  • Test case được xác định nhờ sử dụng Control flow GraphData flow Graph. Số Test case tối thiểu bằng độ phức tạp Cyclomatic của đồ thị

Bài viết liên quan

Unit Testing trong project Ionic2

Việc UnitTest trong project Ionic2 sử dung karma và framework jasmine để thực hiện. Chúng ta sẽ tìm hiểu 1 số khái niệm cũng nhưng từng bước xây dựng môi trường UnitTest.