Nếu nhìn kỹ hơn vào sơ đồ này, chúng ta có thể thấymả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
Trang 1BÀ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
Trang 2II.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êucầ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à:
- 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:
Trang 3B = [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ệntạ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ếpphầ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ùngbê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ếpthà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ửamả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 sortcho 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ấymả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ảngnày cho tới khi hoàn thành và chỉ còn một mảng đã sắp xếp
Trang 4-Các thức thuật toán thực hiện:
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ínhchất luôn được sắp tăng dần
Giả sử ta có 2 mảng con lần lượt là:
Trang 5arr1 = [1 9 10 10] , n1 = 4 // chiều dài của mảng con
=> sort_arr = [1, 3], i = 1, j = 1Xé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 = 2Xé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 = 3Xé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 = 3Xé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]
Đầ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
Trang 6trườ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ácvớ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ướctương đối bằng nhau nhờ chỉ số đứng giữa danh sách, sắp xếp nhanh chia nó thành haidanh 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 danhsá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 Tuynhiê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
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ệttuầ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
Trang 72: 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ử trongmả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ằngviệ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ừ binarysearch đề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
Trang 8Nế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
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
Trang 9Bướ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ộtindex đặ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 chotớ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:
Trang 10 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ểmthử
-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ểmthử 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ểmthử 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ệccâ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
Trang 11*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à:
Trang 12 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
Khi 0<i<len(alist)-1, i<j<len(alist)-1, alist[j] >= 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
Trang 13Case 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ánposition = j có được thực hiện hay không
Trang 14Ta 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
Trang 15Case 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ánposition = 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ênkhông thực hiện lệnh gán position = 1
Thỏa mãn yêu cầu
Trang 16II.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ôngbiế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ốngnhư 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ắtcủ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
Trang 17 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ìnhhoặ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ựchiệ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 testhay 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ếtquả 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ế