TRƯỜNG ĐẠI HỌC BÁCH KHOA HÀ NỘI
VIỆN CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG
BÀI TẬP 2 – CÁC KỸ THUẬT KIỂM THỬ VÀ
GỠ RỐI CHƯƠNG TRÌNH ÁP DỤNG CHO JAVA
VÀ PYTHON
BÀI TẬP NHÓM MÔN HỌC
IT3040 – KỸ THUẬT LẬP TRÌNH 2018-2019
Giảngviênhướngdẫn
Lớp
: PGS. TS. Huỳnh Quyết Thắng
: KSTN_CNTT_K62
HÀ NỘI 2019
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
II.2.1.A: Mô tả thuật toán:
1/ Bubble Sort:
- Bubble sort là 1 thuật toán so sánh đơn giản. Thuật toán này so sánh mỗi cặp 2 phần tử
liền kề nhau và sau đó đổi chỗ giữa chúng nếu chúng không theo thứ tự.
- Thuật toán này không phù hợp để sử dụng cho dữ liệu lớn vì thời gian tính toán trung
bình và trong tình huống tồi nhất của nó là O(n¿ ¿2)¿.
- Cách thức thuật toán làm việc:
Giả sử chúng ta có 1 mảng gồm các phần tử chưa sắp xếp và ta muốn sắp xếp tăng dần:
A = [2, 5, 1, 10, 29]
Chúng ta sẽ bắt đầu với cặp phần tử đầu tiên là (2, 5), thứ tự của cặp này đã đúng với yêu
cầu. Ta chuyển qua cặp (5, 1) sau khi sắp xếp đổi chỗ 2 phần tử được (1, 5), cứ như vậy
đến hết các phần tử của mảng.
Kết quả sau vòng lặp đầu tiên là:
A = [2, 1, 5, 10, 29]
Và khi không còn cặp giá trị nào cần sắp xếp thì thuật toán kết thúc.
2/ Insertion Sort:
- Đây là 1 thuật toán sắp xếp dựa vào vị trí so sánh. Giả sử đã có 1 phần thấp nhất của
mảng đã được sắp xếp bây giờ ta xét phần tử tiếp theo trong mảng thì cần biết vị trí phù
hợp để chèn phần tử đó vào dãy phụ đã được sắp xếp ở trước.
- Thuật toán không phù hợp với dữ liệu lớn, vì thời gian tính trung bình và trường hợp tồi
nhất là O(n¿ ¿2) ¿.
- Cách thức làm việc của thuật toán:
Giả sử ta có 1 mảng chưa được sắp xếp:
B = [10, 29, 21, 5, 50]
Ban đầu ta xét phần tử B[1] (29) thấy rằng nó đã theo thứ tự ta được dãy đã sắp xếp là (10,
29).
Ta chuyển lên phần tử B[2] = 21. So sánh với phần tử B[1] = 29, ta tiến hành đổi
B[2] = 29, B[1] = 21. Dãy đã sắp xếp là (10, 21, 29).
Tiếp tục với phần tử B[3] = 5. Đầu tiên ta sẽ đổi chỗ B[3] và B[2], B[2] lúc này là 5, ta lại
tiếp tục đổi B[2] và A[1], và cuối cùng là B[1] và B[0]. Ta thu được dãy đã sắp xếp là (5,
10, 21, 29)
Tiếp tục phần tử cuối cùng ta được:
2
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
B = [5, 10, 21, 29, 50]
3/ Selection Sort:
- Đây là 1 thuật toán sắp xếp đơn giản. Thuật toán này sắp xếp dựa vào so sánh vị trí hiện
tại. Thuật taons này sẽ chia mảng thành 2 phần phần bên trái sẽ là dãy đã được sắp xếp
phần bên phải là phần chưa được sắp xếp.
- Thuật toán này cũng không phù hợp với bộ dữ liệu lớn vì thời gian tính toán trung bình
và trong trường hợp xấu nhất là O(n¿ ¿2) ¿.
- Cách thức làm việc của thuật toán:
Giả sử có 1 mảng số chưa được sắp xếp và muốn sắp xếp tăng dần:
C = [12, 10, 5, 29, 21]
Đầu tiên ta tìm được phần tử nhỏ nhất trong mảng và tiến hành đổi vị trí của nó với phần
tử ngoài cùng bên trái. Lúc này chia làm 2 dãy: dãy bên trái là C1 = [5], dãy bên phải là
C2 = [12, 10, 29, 21]
C = [5, 12, 10, 29, 21]
Tiếp tục tìm kiếm phần tử nhỏ nhất của phần bên phải và đổi chỗ cho phần tử ngoài cùng
bên trái của C2. Lúc này phần tử nhỏ nhất này sẽ được thêm vào C1 ta được:C1 = [5, 10],
C2 = [12, 29, 21].
Cứ như vậy tiếp tục thuật toán ta sẽ thu được:
C = [5, 10, 12, 21, 29]
4/ Merge sort:
-Merge sort là một thuật toán chia để trị. Thuật toán này chia mảng cần sắp xếp
thành 2 nửa. Tiếp tục lặp lại việc này ở các nửa mảng đã chia. Sau cùng gộp các nửa đó
thành mảng đã sắp xếp. Hàm merge() được sử dụng để gộp hai nửa mảng. Hàm merge(arr,
l, m, r) là tiến trình quan trọng nhất sẽ gộp hai nửa mảng thành 1 mảng sắp xếp, các nửa
mảng là arr[l…m] và arr[m+1…r] sau khi gộp sẽ thành một mảng duy nhất đã sắp xếp.
-Hình ảnh dưới đây sẽ hiển thị cho bạn toàn bộ sơ đồ tiến trình của thuật toán merge sort
cho mảng {38, 27, 43, 3, 9, 82, 10}. Nếu nhìn kỹ hơn vào sơ đồ này, chúng ta có thể thấy
mảng ban đầu được lặp lại hành động chia cho tới khi kích thước các mảng sau chia là 1.
Khi kích thước các mảng con là 1, tiến trình gộp sẽ bắt đầu thực hiện gộp lại các mảng
này cho tới khi hoàn thành và chỉ còn một mảng đã sắp xếp.
3
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
-Các thức thuật toán thực hiện:
mergeSort(arr[], l, r)
If r > l
1. Tìm chỉ số nằm giữa mảng để chia mảng thành 2 nửa:
middle m = (l+r)/2
2. Gọi đệ quy hàm mergeSort cho nửa đầu tiên:
mergeSort(arr, l, m)
3. Gọi đệ quy hàm mergeSort cho nửa thứ hai:
mergeSort(arr, m+1, r)
4. Gộp 2 nửa mảng đã sắp xếp ở (2) và (3):
merge(arr, l, m, r)
-Cách hàm merge hoạt động:
Với trường hợp khi 2 mảng con chỉ có 1 phần tử, ta chỉ việc xem phần tử nào nhỏ
hơn và đẩy lên đầu, phần tử còn lại đặt phía sau. Do vậy, các mảng con cần gộp lại có tính
chất luôn được sắp tăng dần.
Giả sử ta có 2 mảng con lần lượt là:
4
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
arr1 = [1 9 10 10] , n1 = 4 // chiều dài của mảng con
arr2 = [3 5 7 9], n2 = 4
sort_arr = [] // Mảng lưu lại tiến trình gộp
Khởi tạo i = 0, j = 0 tương ứng là chỉ số bắt đầu của arr1 và arr2
Xét thấy arr1[i] < arr2[j] => chèn arr1[i] vào cuối mảng sort_arr, tăng i lên 1 đơn vị
=> sort_arr = [1], i = 1
Xét thấy arr1[i] > arr2[j] => chèn arr2[j] vào cuối mảng sort_arr, tăng j lên 1 đơn vị
=> sort_arr = [1, 3], i = 1, j = 1
Xét thấy arr1[i] > arr2[j] => chèn arr2[j] vào cuối mảng sort_arr, tăng j lên 1 đơn vị
=> sort_arr = [1, 3, 5], i = 1, j = 2
Xét thấy arr1[i] > arr2[j] => chèn arr2[j] vào cuối mảng sort_arr, tăng j lên 1 đơn vị
=> sort_arr = [1, 3, 5, 7], i = 1, j = 3
Xét thấy arr1[i] = arr2[j] => chèn arr1[i] hoặc arr2[j] vào cuối mảng sort_arr
Giả sử tôi chọn arr1, tăng i lên 1 đơn vị
=> sort_arr = [1, 3, 5, 7, 9], i = 2, j = 3
Xét thấy arr1[i] > arr2[j] => chèn arr2[j] vào cuối mảng sort_arr, tăng j lên 1 đơn vị
=> sort_arr = [1, 3, 5, 7, 9, 9], i = 1, j = 4
Do j >= n2, tiếp tục tăng i chừng nào i < n1 thi thêm phần tử ở arr1[i] vào sort_arr.
Sau cùng ta được mảng đã sắp xếp là sort_arr = [1, 3, 5, 7, 9, 9, 10, 10]
5/ Shell sort
Shell Sort là một giải thuật sắp xếp mang lại hiệu quả cao dựa trên giải thuật sắp xếp
chèn (Insertion Sort). Giải thuật này tránh các trường hợp phải tráo đổi vị trí của hai
phần tử xa nhau trong giải thuật sắp xếp chọn (nếu như phần tử nhỏ hơn ở vị trí bên phải
khá xa so với phần tử lớn hơn bên trái).
Đầu tiên, giải thuật này sử dụng giải thuật sắp xếp chọn trên các phần tử có khoảng cách
xa nhau, sau đó sắp xếp các phần tử có khoảng cách hẹp hơn. Khoảng cách này còn được
gọi là khoảng (interval) – là số vị trí từ phần tử này tới phần tử khác. Khoảng này được
tính dựa vào công thức Knuth như sau:
h=h*3+1
với h là khoảng (interval) với giá trị ban đầu là 1
Giải thuật này khá hiệu quả với các tập dữ liệu có kích cỡ trung bình khi mà độ phức tạp
5
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
trường hợp xấu nhất và trường hợp trung bình là O(n), với n là số phần tử.
Giải thuật:
Bước 1: Khởi tạo giá trị h
Bước 2: Chia list thành các sublist nhỏ hơn tương ứng với h
Bước 3: Sắp xếp các sublist này bởi sử dụng sắp xếp chèn (Insertion Sort)
Bước 4: Lặp lại cho tới khi list đã được sắp xếp
6/ Quick sort
Sắp xếp nhanh (Quicksort), còn được gọi là sắp xếp kiểu phân chia (part sort) là
một thuật toán sắp xếp phát triển bởi C.A.R. Hoarec sắp thành hai danh sách con. Khác
với sắp xếp trộn, chia danh sách cần sắp xếp thành hai danh sách con có kích thước
tương đối bằng nhau nhờ chỉ số đứng giữa danh sách, sắp xếp nhanh chia nó thành hai
danh sách bằng cách so sánh từng phần tử của danh sách với một phần tử được chọn
được gọi là phần tử chốt. Những phần tử nhỏ hơn hoặc bằng phần tử chốt được đưa về
phía trước và nằm trong danh sách con thứ nhất, các phần tử lớn hơn chốt được đưa về
phía sau và thuộc danh sách đứng sau. Cứ tiếp tục chia như vậy tới khi các danh sách con
đều có độ dài bằng 1.
Kỹ thuật chọn phần tử chốt ảnh hưởng khá nhiều đến khả năng rơi vào các vòng lặp vô
hạn đối với các trường hợp đặc biệt. Tốt nhất là chọn phần tử chốt là trung vị của danh
sách. Khi đó sau log2(n) lần phân chia ta sẽ đạt tới kích thước danh sách bằng 1. Tuy
nhiên điều đó rất khó. Có các cách chọn phần tử chốt như sau:
Chọn phần tử đứng đầu hoặc đứng cuối làm phần tử chốt.
Chọn phần tử đứng giữa danh sách làm phần tử chốt.
Chọn phần tử trung vị trong 3 phần tử đứng đầu, đứng giữa và đứng cuối làm phần
tử chốt.
Chọn phần tử ngẫu nhiên làm phần tử chốt. (Cách này có thể dẫn đến khả năng rơi
vào các trường hợp đặc biệt)
7/ Tìm kiếm tuần tự(Linear Search)
-Đây là một giải thuật tìm kiếm đơn giản, thích hợp với mảng dữ liệu ngắn và các phần tử
của mảng chưa được sắp xếp. Trong thuật toán này, các phần tử của mảng sẽ được duyệt
tuần tự từ đầu mảng cho đến khi tìm được vị trí của giá trị cần tìm.
Thuật toán:
1: Khởi tạo i = 1
6
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
2: Nếu i > array’s length, trả về 0 ( không tìm được)
3: Nếu array[i] == value thì trả về i
4: Nếu array[i] != value thì tăng I, quay lại bước 2
Thời gian thực hiện: Θ (n)
8/ Tìm kiếm nhị phân(Binary Search)
Thuật toán này chỉ thực hiện tìm kiếm trên mảng đã được sắp xếp.
Ý tưởng của thuật toán này là so sánh giá trị cần tìm với phần tử trung tâm, nếu bằng thì
trả về true, nếu khác thì tùy vào lớn hơn hay nhỏ hơn và thứ tự sắp xếp phần tử trong
mảng để gọi đệ quy.
Thuật toán (giả sử mảng array được sắp xếp tăng dần):
1: Đặt mid = array’s length/2
2: Nếu array[mid] = value thì trả vể mid, kết thúc chương trình
Nếu array[mid] > value thì thực hiên Binary Search trên mảng array[1..mid-1]
Nếu array[mid] < value, thực hiên Binary Search trên mảng array[mid+1..array’s length]
8/ Interpolation Search
Interpolation search(Tìm kiếm nội suy) tiến hành việc tìm kiếm một phần tử cụ thể bằng
việc tính toán vị trí dò (Probe Position). Đây là phương pháp tìm kiếm cải tiến từ binary
search đều phải hoạt động trên một list đã được sắp xếp .
Ban đầu thì vị trí dò là vị trí của phần tử nằm ở giữa nhất của tập dữ liệu.
7
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
Nếu phần tử nằm ở giữa nhất đó là phần tử cần tìm thì kết thúc chương trình . Phần tử
giữa nhất được xác đinh theo công thức sau :
mid = Lo + ((Hi - Lo) / (A[Hi] - A[Lo])) * (X - A[Lo])
Trong đó:
A = danh sách
Lo = chỉ mục thấp nhất của danh sách
Hi = chỉ mục cao nhất của danh sách
A[n] = giá trị được lưu giữ tại chỉ mục n trong danh sách
X = phần tử cần tìm
Nếu phần tử cần tìm có giá trị lớn hơn phần tử ở giữa thì phần tử cần tìm sẽ ở mảng con
bên phải phần tử ở giữa và chúng ta lại tiếp tục tính vị trí dò; nếu không phần tử cần tìm
sẽ ở mảng con bên trái phần tử ở giữa. Tiến trình này tiến tụp diễn ra trên các mảng con
cho tới khi kích cỡ của mảng con giảm về 0.
Độ phức tạp thời gian chạy của Interpolation Search là Ο(log (log n)), trong khi của
Binary Search là Ο(log n).
Bởi vì đây là sự cải tiến của giải thuật Binary Search nên chúng ta sẽ chỉ đề cập tới các
bước để tìm kiếm chỉ mục của giá trị cần tìm bởi sử dụng vị trí dò.
Bước 1 : Bắt đầu tìm kiếm dữ liệu từ phần giữa của danh sách
Bước 2 : Nếu đây là một so khớp (một kết nối), thì trả về chỉ mục của phần tử, và
thoát.
Bước 3 : Nếu không phải là một so khớp, thì là vị trí dò.
Bước 4 : Chia danh sách bởi sử dụng phép tính tìm vị trí dò và tìm vị trí giữa mới.
Bước 5 : Nếu dữ liệu cần tìm lớn hơn giá trị tại vị trí giữa, thì tìm kiếm trong mảng
con bên phải.
Bước 6 : Nếu dữ liệu cần tìm nhỏ hơn giá trị tại vị trí giữa, thì tìm kiếm trong
mảng con bên trái
8
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
Bước 7 : Lặp lại cho tới khi tìm thấy so khớp
10/Hash table
Hashing là kĩ thuật chuyển đổi một cặp (key,value) thành một phần tử của 1 array với một
index đặc biệt .
Ở đây hàm hash của chúng ta đơn giản là lấy phần dư :
Như vậy khi tìm kiếm một phần tử ta chỉ cần biết được key của nó là tìm được .
Để tránh collision , thì người ta sử dụng kĩ thuật Linear Probing , đơn giản là khi một
key bị collision với những hàm đi trước thì chúng ta sẽ đẩy cạp (key,value) lên tiếp cho
tới khi tìm được một chỗ mà chưa có cặp (key,value) nào .
II.2.1.B: Mô tả thuật toán sắp xếp Selection Sort Algorithm:
Python:
Java:
II.2.2: White-box testing:
II.2.2.1/ White-box testing:
1/ Khái niệm:
White-box testing còn được gọi là clear box testing, glass box testing, transparent
box testing, or structural testing, thường thiết kế các trường hợp kiểm thử dựa vào
cấu trúc bên trong của phần mềm, dựa vào mã nguồn và cấu trúc chương trình.
Một người sử dụng White-box testing đòi hỏi kĩ thuật lập trình am hiểu cấu trúc
bên trong của phần mềm (các đường, luồng dữ liệu, chức năng, kết quả).
2/ Khi nào cần kiểm thử hộp trắng:
Kỹ thuật này chủ yếu được dùng để kiểm thử đơn vị. Trong lập trình hướng đối
tượng, kiểm thử đơn vị là kiểm thử từng tác vụ của1 class chức năng nào đó.
Kiểm thử hộp trắng không phải là tất vả và cuối cùng để đảm bảo chất lượng của 1
hệ thống, nhưng đây là 1 kỹ thuật quan trọng và không thể thiếu đặc biệt áp dụng
đối với các hệ thống, phần mềm lớn, quan trọng
3/ Ưu điểm và nhược điểm:
*Ưu điểm:
9
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
Kiểm thử hộp trắng rất tỉ mỉ và có thể quét được tất cả các tình huống xảy ra mà
một hệ thống gặp phải bằng cách kiểm tra ở cấp mã nguồn, khi đó có thể tìm ra
các lỗi còn sót và sửa chúng.
*Nhược điểm:
Thời gian kiểm tra dài, khó thực hiện và chi phí cao.
Thường tốn rất nhiều thời gian và công sức nếu mức độ kiểm thử được nâng lên ở
cấp kiểm thử tích hợp hay kiểm thử hệ thống.
4/ Phân loại kiểm thử hộp trắng:
*Có 2 hoạt động kiểm thử hộp trắng:
Kiểm thử dòng dữ liệu: 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, …
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.
II.2.2.2/ Xây dựng kịch White-box testing cho Selection Sort Algorithm:
1/ Step 1: Xác định các tính năng, thành phần, chương trình sẽ thực hiện kiểm
thử
-Chúng ta càng chia nhỏ thành phần của hệ thống càng nhỏ càng tốt, bởi kiểm
thử hộp trắng dành cho các hệ thống quan trọng cần kiểm soát kỹ lưỡng. Kiểm
thử hộp trắng rất tốn thời gian và công sức. Do đó, ta cũng cần chú ý đến việc
cân bằng nỗ lực kiểm thử và nhu cầu kiểm thử.
-Với Selection Sort ta sẽ xem xét về khả năng sắp xếp với các thành phần:
vòng lặp, so sánh các phần tử và hoán đổi vị trí.
2/ Step 2: Xây dựng đồ thị dòng điều khiển tương ứng
10
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
*Xây dựng đồ thị dòng điều khiển:
*Tính độ phức tạp Cyclomatic của đồ thị:
Ở đây, ta thấy có 3 nút quyết định nên độ phức tạp C = 3+1 = 4
*4 đường thi hành tuyến tính cơ bản là:
11
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
C1S6
C1S1C2S3S4S5S6
C1S1C2C3S2
C1S2C2C3
*Thực hiện các test case cho từng đường thi hành:
Khi i = len(alist)-2. Giá trị kỳ vọng của ta là list đã được sắp xếp ở tất
cả các vị trí.
Khi 0= alist[position]. Giá trị
kỳ vọng của ta là list đã sắp xếp được i-1 vị trí đầu tiên và đang duyệt
qua được j-i phần tử kể từ phần tử alist[i+1] đến alist[len(alist)-1]
nhưng bỏ qua bước gán position = j và quay lại tiếp tục tăng j thực hiện
kiểm tra điều kiện alist[j] < alist[position].
*Test thử với từng trường hợp:
Case1: Ở đây ta sử dụng thêm lệnh print(i) để kiểm thử và kết quả là:
Thỏa mãn yêu cầu.
12
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
Case 2: Ở đây với từng vòng lặp ta sẽ tiến hành in ra kết quả của list và giá trị
của i để kiểm thử.
Có thể thấy kết quả in ra hoàn toàn thỏa mãn yêu cầu
Case 3: Ở đây ngoài in ra giá trị của i, ta còn in ra giá trị của j (ở lần đầu tiên
điều kiện thỏa mãn) và kiểm tra xem khi điều kiện thỏa mãn thì lệnh gán
position = j có được thực hiện hay không.
13
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
Ta có thể thấy khi chương trình thực hiện đúng thì sẽ in ra giá trị của i, j và
“yes” cũng như thực hiện đổi vị trí lần đầu tiên.
Thỏa mãn yêu cầu
14
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
Case 4: Ở đây ngoài in ra giá trị của i, ta còn in ra giá trị của j (ở lần đầu tiên
điều kiện thỏa mãn) và kiểm tra xem khi điều kiện thỏa mãn thì lệnh gán
position = j có được thực hiện hay không. Nếu không thực hiện sẽ in ra “no”
tức là không thực hiện lệnh gán tại các vị trí không thỏa mãn điều kiện.
Tức là khi đang xét i = 0 khi j = 1, phần tử này không thỏa mãn điều kiện nên
không thực hiện lệnh gán position = 1.
Thỏa mãn yêu cầu
15
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
II.2.3: Kỹ thuật kiểm thử hộp đen - Black box Testing
1. Khái niệm
Kiểm thử hộp đen: là một phương pháp kiểm thử phần mềm được thực hiện mà không
biết được cấu tạo bên trong của phần mềm, là cách mà các tester kiểm tra xem hệ thống
như một chiếc hộp đen, không có cách nào nhìn thấy bên trong của cái hộp.
Nó còn được gọi là kiểm thử hướng dữ liệu hay là kiểm thử hướng in/out.
Người kiểm thử nên xây dựng các nhóm giá trị đầu vào mà sẽ thực thi đầy đủ tất cả
các yêu cầu chức năng của chương trình.
Cách tiếp cận của các tester đối với hệ thống là không dùng bất kỳ một kiến thức
về cấu trúc lập trình bên trong hệ thống, xem hệ thống là một cấu trúc hoàn chỉnh,
không thể can thiệp vào bên trong.
Black Box Testing chủ yếu là được thực hiện trong Function test và System test.
Phương pháp này được đặt tên như vậy bởi vì các chương trình phần mềm, trong con mắt
của các tester, giống như một hộp đen; bên trong mà người ta không thể nhìn thấy.
Phương pháp này cố gắng tìm ra các lỗi trong các loại sau:
Chức năng không chính xác hoặc thiếu.
Lỗi giao diện.
Lỗi trong cấu trúc dữ liệu hoặc truy cập cơ sở dữ liệu bên ngoài.
Hành vi hoặc hiệu suất lỗi.
Khởi tạo và chấm dứt các lỗi.
Mọi kỹ thuật nào cũng có ưu điểm và nhược điểm của nó. Các hệ thống thường phải được
sử dụng nhiều phương pháp kiểm thử khác nhau để đảm bảo được chất lượng của hệ
thống khi đến tay người dùng.
2. Ưu điểm của kiểm thử hộp đen
Các tester được thực hiện từ quan điểm của người dùng và sẽ giúp đỡ trong việc
sáng tỏ sự chênh lệch về thông số kỹ thuật.
16
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
Các tester theo phương pháp black box không có “mối ràng buộc” nào với code, và
nhận thức của một tester rất đơn giản: một source code có nhiều lỗi. Sử dụng
nguyên tắc, "Hỏi và bạn sẽ nhận" các tester black box tìm được nhiều bug ở nơi mà
các DEV không tìm thấy.
Tester có thể không phải IT chuyên nghiệp, không cần phải biết ngôn ngữ lập trình
hoặc làm thế nào các phần mềm đã được thực hiện.
Các tester có thể được thực hiện bởi một cơ quan độc lập từ các developer, cho
phép một cái nhìn khách quan và tránh sự phát triển thiên vị.
Hệ thống thật sự với toàn bộ yêu cầu của nó được kiểm thử chính xác.
Thiết kế kịch bản kiểm thử khá nhanh, ngay khi mà các yêu cầu chức năng được
xác định.
3. Nhược điểm của kiểm thử hộp đen
Dữ liệu đầu vào yêu cầu một khối lượng mẫu (sample) khá lớn
Nhiều dự án không có thông số rõ ràng thì việc thiết kế test case rất khó và do đó
khó viết kịch bản kiểm thử do cần xác định tất cả các yếu tố đầu vào, và thiếu cả
thời gian cho việc tập hợp này.
Khả năng để bản thân kỹ sư lạc lối trong khi kiểm thử là khá cao.
Chỉ có một số nhỏ các đầu vào có thể được kiểm tra và nhiều đường dẫn chương
trình sẽ được để lại chưa được kiểm tra.
Kiểm thử black box được xem như "là bước đi trong mê cung tối đen mà không
mang đèn pin” bởi vì tester không biết phần mềm đang test đã được xây dựng như
thế nào. Có nhiều trường hợp khi một tester viết rất nhiều trường hợp test để kiểm
tra một số thứ có thể chỉ được test bằng một trường hợp test và/hoặc một vài phần
cuối cùng không được test hết.
4. Nội dung công việc trong công đoạn test
Kế hoạch test: Chỉ ra rõ ràng mục đích và phạm vi của công đoạn test để kiểm tra xem là
test bằng approach như thế nào. Điều chỉnh resource thành viên và quyết định cả
schedule.
Thiết kế test: Quyết định xem là sẽ sử dụng cái gì cho mục đích và loại test càn được thực
hiện trong công đoạn test đó, chức năng đối tượng test, phương pháp test, import và
export test. Ngoài ra cũng quyết định cụ thể hơn nguyên liệu cần thiết để thực hiện test
hay tiêu chuẩn quyết định thành công/ không thành công.
Tạo testcase: Tạo document ghi trạng thái trước khi bắt đầu test và kết quả mong đợi (kết
quả chạy đối tượng test theo điều kiện và trình tự thao tác khi thực hiện test sẽ như thế
17
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
nào) và cột trạng thái (cột ghi lại kết quả thao tác của đối tượng test).
Thực hiện test: Vừa xem testcase vừa cho chạy phần mềm thực tế để tiến hành test, sau đó
đánh dấu kết quả bằng dấu pass hoặc fail vào cột trạng thái testcase. Trường hợp có
testcase khác với kết quả mong đợi thì ghi dấu fail vào cột trạng thái, rồi tạo bản báo cáo
lỗi. Trong bản báo cáo lỗi: trình bày nội dung mô tả hiện tượng khác với kết quả mong đợi
và hiện tượng đó phát sinh trong trường hợp như thế nào (thao tác, giả nhập, điều kiện,...)
Báo cáo test: Tóm tắt kết quả để báo cáo. Căn cứ vào các loại dữ liệu (mục thực hiện, hiệu
quả của việc test, công số thực hiện,...) và dữ liệu lỗi (số lỗi được tìm ra, số lỗi theo mức
độ quan trọng,...) để đánh giá xem có thỏa mãn tiêu chuẩn pass/ fail của test không? Ngoài
ra cũng đề xuất thêm risk có thể sinh ra sau khi release và mục cần bổ sung trong dự án
cho giai đoạn tiếp theo.
Ví dụ:
Bộ test để kiểm thử cho thuật toán selection sort là một chuỗi số thực, nếu chuỗi đó có
phần tử không thuộc kiểu số thực thì code sẽ báo lỗi.
Ví dụ với các bộ test có dưới 5000 số code chạy bình thường
Với các bộ test trên 5000 số và dưới 10000, code chạy rất chậm
Với các bộ test trên 10000 số, code báo lỗi
Nguyên nhân: Thuật toán có độ phức tạp O(n^2), số phép tính quá lớn khiến cho
chương trình chạy rất chậm hoặc máy không chạy được.
18
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
II.2.4: Kiểm thử tích hợp
2.4.1: Lý thuyết kiểm thử tích hợp
- Là kiểm thử mà trong đó mỗi module phần mềm riêng biệt lại được
kết hợp lại và kiểm thử theo nhóm.
- Có thể coi kiểm thử tích hợp là sự kết hợp của kiểm thử hộp trắng và hộp đen. Các tester
có thể can thiệp vào source code ở mức độ các module, còn khi test thì test như là kiểm
thử hộp đen.
Các phương pháp tiếp cận:
a: Big bang integration
b: Bottom-up integration
c: Top-down integration
d: Sanwich testing
a : Big bang integration
Là phương pháp tích hợp tất cả các module lại với nhau để kiểm thử tại cùng một thời
điểm.
Ưu điểm: tất cả mọi thứ đã được tích hợp để test tại một thời điểm.
Nhược điểm: khó xác định lỗi hệ thống
19
Bài tập 2- Các kỹ thuật kiểm thử và gỡ rối áp dụng cho Java và Python
b : Top-down integration
Là kiểm thử theo thứ tự từ trên xuống. Module có level cao nhất sẽ được ưu tiên kiểm thử
đầu. Ở các bước tiếp theo thì các module ở mức thấp hơn sẽ được tích hợp cùng để đưa
vào kiểm thử.
Ví dụ ở hình dưới, các bước kiểm thử sẽ là:
Test U1 Test (U1, U2, U3) Test (U1, U2, U3, U4, U5, U6)
Ưu điểm:
Nhược điểm:
c : Bottom-up integration
Là kĩ thuậ kiểm thử từ dưới lên, các module ở mức thấp sẽ được ưu tiên kiểm thử trước.
Ví dụ ở hình dưới ta có sơ đồ kiểm thử:
Test U4, Test U5, Test U6 Test(U3, U4, U5, U6)
Test(U1, U2, U3, U4, U5, U6)
Ưu điểm:
20
- Xem thêm -