Công cụ sinh ca kiểm thử tự động có giao diện được mô tả như Hình 3.4. Cửa sổ bên trái là CFG của mã nguồn. Cửa sổ trên phải hiển thị danh sách các đường kiểm thử và các ca kiểm thử tương ứng. Cửa số dưới phải hiển thị mã nguồn, chi tiết đường kiểm thử và các nghiệm của hệ ràng buộc ứng với đường kiểm thử trên CFG.
3.4.2. Đồ thị dòng điều khiển
Hình 3.5 là đồ thị dòng điều khiển ứng với tiêu chí phủ câu lệnh và phủ nhánh của hàm laNamNhuan sau khi công cụ phân tích mã nguồn và thực hiện sinh CFG. Hình 3.6 là đồ thị dòng điều khiển ứng với tiêu chí phủ điều kiện con của hàm
laNamNhuan khi nhấp vào nút "phủ điều kiện con" trên giao diện.
Hình 3.5.CFG ứng với tiêu chí phủ câu lệnh và phủ nhánh của hàm laNamNhuan
Hình 3.6. CFG ứng với tiêu chí phủ điều kiện con của hàm laNamNhuan
Mỗi câu lệnh trên mã nguồn tương ứng với một đỉnh trên CFG. Đồ thị bắt đầu bằng đỉnh "Begin", kết thúc bằng đỉnh "End". Các đường đi trên đồ thị được kết nối theo thứ tự thực hiện câu lệnh. Các đỉnh quyết định chia đường đi trên đồ thị theo hai nhánh đúng và sai. Nhánh đúng tương ứng với đường đi màu xanh dương, nhánh sai tương ứng với đường đi màu xanh lá. Ở CFG của tiêu chí phủ câu lệnh và phủ nhánh điều kiện phức hợp được biểu diễn trên cùng một đỉnh (year%400==0)||(year%4=0)&& (year%100!=0)). Còn ở CFG của tiêu chí phủ điều kiện con, điều kiện phức hợp được tách ra thành các đỉnh quyết định đơn là
(year%400==0);(year%4==0) và (year%100!=0).
3.4.3. Tập các đƣờng kiểm thử
Với mỗi loại đồ thị, công cụ sinh ra một tập đường đi kiểm thử tương ứng. Khi người dùng bấm vào nút "Sinh Test" trên công cụ, cửa sổ bên phải sẽ hiển thị các đường kiểm thử của đồ thị CFG tương ứng. Trên mỗi đường kiểm thử này có hiện thứ tự các đỉnh mà đường kiểm thử đi qua. Nhấp chuột vào một đường kiểm thử ở mục
"Đường dẫn", ta có thể quan sát được đường đi đó trên CFG như Hình 3.7.
Hình 3.7.Chi tiết các đƣờng kiểm thử cho tiêu chí phủ nhánh của hàm laNamNhuan
3.4.4. Tập các ca kiểm thử
Trên mỗi đường kiểm thử, SMT solver Z3 thực hiện sinh ra một ca kiểm thử tương ứng. Mỗi ca kiểm thử là một bộ giá trị gồm hai thành phần: Dữ liệu kiểm thử (Tescases) và giá trị đầu ra mong muốn (EO) của ca kiểm thử đó. Chi tiết ba ca kiểm thử cho tiêu chí phủ câu lệnh của hàm laNamNhuan được sinh bởi công cụ thể hiện ở Hình 3.8.
Hình 3.8.Chi tiết các ca kiểm thử cho tiêu chí phủ câu lệnh của hàm laNamNhuan
Ca kiểm thử thứ nhất (dòng 1), dữ liệu kiểm thử là year = 1 thỏa mãn các điểm quyết định trên đường đi thứ nhất, giá trị đầu ra mong muốn của ca kiểm thử là EO = 0. Ca kiểm thử thứ hai (dòng 2), dữ liệu kiểm thử là một giá trị sinh ngẫu nhiên year =15204 thỏa mãn các điểm quyết định trên đường đi thứ hai, giá trị đầu ra mong muốn của ca kiểm thử là EO = 1. Ca kiểm thử thứ ba (dòng 3), dữ liệu kiểm thử là year = -1 thỏa mãn các điểm quyết định trên đường đi thứ ba, giá trị đầu ra mong muốn của ca kiểm thử là EO = -1.
Sau khi sinh được các ca kiểm thử, công cụ cho phép xuất các ca kiểm thử ra dạng MS. Excel để có khả năng sử dụng lại và quản lý các ca kiểm thử sau này. Kết quả kiểm thử xuất ra MS. Excel được lưu tại đường dẫn C:\Users\PC\eclipse- workspace\JavaTesting. Hình 3.9 mô tả kết quả kiểm thử của hàm laNamNhuan được xuất dưới dạng MS Excel.
Hình 3.9.Kết quả kiểm thử đƣợc xuất dƣới dạng MS. Excel của hàm laNamNhuan
3.5 Kết quả thực nghiệm
Để chứng minh tính hiệu quả của phương pháp nghiên cứu, luận văn sử dụng công cụ để sinh các ca kiểm thử cho một số bài toán với mã nguồn do giáo viên cung cấp. Các ca kiểm thử này sẽ được sử dụng để thực hiện các kiểm thử (chấm bài) với bài tập lập trình của học sinh. Ngoài ra, luận văn cũng sẽ đề cập đến sinh thêm các ca kiểm thử sử dụng phương pháp phân tích giá trị biên để minh chứng rằng các ca kiểm thử sinh ra bằng phương pháp nghiên cứu là chưa đủ để phát hiện các lỗi của chương trình. Dưới đây là ba thực nghiệm ứng với ba bài toán đã được áp dụng.
Bài toán 1: Bài toán kiểm tra năm nhuận
Hình 3.10 là mã nguồn chuẩn của hàm laNamNhuan sử dụng để sinh các ca kiểm thử cho bài toán kiểm tra năm nhuận. Hàm nhận giá trị đầu vào là một số nguyên dương year ghi nhận năm. Đầu ra của hàm là giá trị 1 nếu year thỏa mãn điều kiện là năm nhuận, ngược lại hàm trả về giá trị 0. Biết rằng, năm nhuận là năm chia hết cho 400 hoặc chia hết cho 4 nhưng không chia hết cho 100.
Để kiểm tra được hết các trường hợp xảy ra trên mã nguồn, ta sẽ sinh các ca kiểm thử ứng với tiêu chí phủ cao nhất của mã nguồn chuẩn. Các ca kiểm thử này sẽ là tiêu chí đánh giá chất lượng bài tập của học sinh. Ngoài ra, để có một bộ ca kiểm thử đầy đủ, ta cần phân tích mã nguồn để sinh thêm các ca kiểm thử giá trị biên và vòng lặp (nếu có).
Hình 3.10.Mã nguồn chuẩn của hàm laNamNhuan
Các ca kiểm thử được công cụ sinh cho tiêu chí phủ điều kiện con của hàm
laNamNhuan được thể hiện trong Hình 3.11.
Hình 3.11. Chi tiết ca kiểm thử cho tiêu chí phủ điều kiện con của ham laNamNhuan
public int laNamNhuan(intyear) {
if(year<0)
return -1;
if((year%400==0)||((year%4==0)&&(year%100!=0)))
return 1;
else
return 0;
}
Chúng ta sẽ sử dụng tập ca kiểm thử như Hiình 3.11 để thực hiện kiểm thử trên bài tập của hai học sinh có mã nguồn thể hiện ở Hình 3.12 và Hình 3.13. Với mỗi hàm, chúng ta cần thực hiện năm ca kiểm thử. Dữ liệu kiểm thử được lấy từ cột "Testcase", giá trị đầu ra mong muốn của mỗi ca kiểm thử được so sánh với giá trị "EO".
Hình 3.12.Mã nguồn hàm laNamNhuan1 của học sinh thứ nhất
Hình 3.13.Mã nguồn hàm laNamNhuan2 của học sinh thứ hai
Sau khi thực hiện kiểm thử trên mã nguồn của hai học sinh, kết quả kiểm thử được ghi lại trong Bảng 3.3. Với mã nguồn của học sinh thứ nhất, phát hiện một ca kiểm thử lỗi (xảy ra ở ca kiểm thử số 5 trên Hình 3.11). Với mã nguồn của học sinh thứ hai, phát hiện hai ca kiểm thử lỗi (xảy ra ở ca kiểm thử số 5 và số 4).
Bảng 3.3. Kết quả kiểm thử bài tập kiểm tra năm nhuận của hai học sinh Hàm kiểm thử Số Test Số lỗi phát hiện Hàm kiểm thử Số Test Số lỗi phát hiện
laNamNhuan1(int year) 5 1
laNamNhuan2(int year) 5 2 Kiểm thử giá trị biên cho hàm laNamNhuan
Việc sinh các ca kiểm thử từ công cụ chỉ đảm bảo phủ các nhánh trên đồ thị, và thường sinh dữ liệu từ giữa miền xác định của biến, do vậy phương pháp này không kiểm tra đến các giá trị biên và cận biên của các biến. Lỗi có thể xảy ra khi các học sinh viết sai biểu thức điều khiện hoặc không kiểm tra giá trị hợp lệ của biến đầu vào. Do vậy, chúng ta cần sinh thêm các ca kiểm thử giá trị biên cho mã nguồn chuẩn để
public int laNamNhuan2(int year) {
if((year%4==0)&&(year%100!=0)) {
return 1;
else
return 0;
}
public int laNamNhuan1(int year) {
if((year%400==0)||((year%4==0)&&(year%100!=0)))
return 1;
else
return 0;
}
tập ca kiểm thử đạt độ phủ cao hơn. Bảng 3.4 là các ca kiểm thử giá chị biên cần thực hiện cho hàm laNamNhuan. Phương pháp sinh các ca kiểm thử biên cho hàm
laNamNhuan đã trình bày trong ví dụ ở Chương 2.
Bảng 3.4. Các ca kiểm thử giá trị biên cho hàm laNamNhuan
STT Input EO RO 1 -1 -1 2 0 0 3 1 0 4 500 0 5 1995 0 6 1996 1 7 1997 0 8 1999 0 9 2000 1 10 2001 0 11 9998 0 12 9999 0 13 10000 -1
Chúng ta thực hiện kiểm thử giá trị biên trên hai bài tập của học sinh, kết quả ghi lại trong Bảng 3.5. Với mã nguồn của học sinh thứ nhất, phát hiện ra hai ca kiểm thử lỗi (xảy ra ở ca kiểm thử thứ 1 và thứ 13 trên Bảng 3.4). Với mã nguồn của học sinh thứ hai, phát hiện ba ca kiểm thử lỗi (xảy ra ở ca kiểm thử thứ 1, thứ 2, thứ 9 và thứ 13). So với các ca kiểm thử sinh ra từ công cụ, các ca kiểm thử giá trị biên giúp phát hiện thêm các lỗi trên mã nguồn của học sinh.
Bảng 3.5. Kết quả kiểm thử giá trị biên bài tập kiểm tra năm nhuận của hai học sinh Hàm kiểm thử Số Test Số lỗi phát hiện
laNamNhuan1(int year) 13 2
laNamNhuan2(int year) 13 4
Bài toán 2: Bài toán tính số ngày trong một tháng
Hình 3.14 là mã nguồn chuẩn của hàm songay được sử dụng để sinh các ca kiểm thử cho bài toán tính số ngày của một tháng trong năm. Hàm nhận đầu vào là hai số nguyên dương ghi nhận tháng có miền xác định [1,12] và năm có miền xác định [0,9999]. Đầu ra của hàm là số ngày tương ứng với tháng và năm đó. Biết rằng, các tháng 1, 3, 5, 7, 8, 12 có 31 ngày; các tháng 4, 6, 9, 11 có 30 ngày; tháng 2 có 28 ngày (riêng tháng 2 của năm nhuận có 29 ngày).
Hình 3.14. Mã nguồn chuẩn của hàm songay
Chúng ta sử dụng công cụ để sinh các ca kiểm thử với độ phủ cao nhất cho hàm songay
(phủ điều kiện con). Chi tiết các ca kiểm thử được hiển thị ở Hình 3.15. Tập các ca kiểm thử này sẽ được dùng để kiểm thử trên bài tập của học sinh có mã nguồn như Hình 3.16 và Hình 3.17.
Hình 3.15. Chi tiết ca kiểm thử cho tiêu chí phủ điều kiện con của hàm songay
1. int ngay=0;
2. if(((thang<0)||(thang>12))||(nam<0)||(nam>9999)){ 3. return -1; 4. }else { 5. swiTch (thang) { 6. case 1: 7. case 3: 8. case 5: 9. case 7: 10 case 8: 11. case 10: 12. case 12:{ 13. ngay=31; 14. break; } 15. case 4: 16. case 6: 17. case 9: 18. case 11:{ 19. ngay=30; 20 break; } 21 case 2:{
22. if((nam%400==0)||((nam%4==0)&&(nam%100!=0))){ 23 ngay=29;
24. }else {
25. ngay=28; }
26. break; }}} 27. return ngay ; }}
Hình 3.16. Mã nguồn hàm songayhs_1 của học sinh thứ nhất
Hình 3.17. Mã nguồn hàm songayhs_2 của học sinh thứ hai
public int songayhs_2(intthang, intnam) {
intngay=0; swiTch (thang) { case 1: case 3: case 5: case 7: case 8: case 10: case12:{ ngay=31; break; } case 4: case 6: case 9: case11:{ ngay=30; break; } case2:{
if((nam%400==0)||((nam%4==0)&&(nam%100!=0))){
ngay=29;
}else {
ngay=28; }
break; } }
returnngay ;}}
public int songayhs_1(intthang, intnam) { 1. int ngay=0;
2. if(((thang<0)||(thang>12))||(nam<0)||(nam>9999)){ 3. return -1; 4. }else { 5. switch (thang) { 6 case 1: 7. case 3: 8. case 5: 9. case 7: 10. case 8: 11. case 10: 12. case12:{ 13. ngay=31; 14. break; } 15. case 4: 16. case 6: 17. case 9: 18. case11:{ 19. ngay=30; 20. break; } 21. case 2: ngay=28; 22. break; } } 23. return ngay ;}}
Sau khi thực hiện kiểm thử trên bài tập của hai học sinh, kết quả được ghi lại trong Bảng 3.6. Với mỗi hàm, chúng ta thực hiện 19 ca kiểm thử như ở Hình 3.15. Trên mã nguồn của học sinh thứ nhất phát hiện hai ca kiểm thử lỗi (xảy ra ở các ca kiểm thử số 4 và số 5). Trên mã nguồn của học sinh thứ hai, phát hiện ba ca kiểm thử (xảy ra ở ca kiểm thử thứ 1, thứ 17 và thứ 19)
Bảng 3.6. Kết quả kiểm thử bài tập tính số ngày trong thángcủa hai học sinh
Hàm kiểm thử Số Test Số lỗi phát hiện
songay_1(int thang, int nam) 19 2
songay_2(int thang, int nam) 19 3 Kiểm thử giá trị biên cho hàm songay
Ta tiếp tục phân tích hàm songay để sinh các ca kiểm thử giá trị biên. Hàm nhận hai biến đầu vào là thang có miền xác định [1,12] và nam có miền xác định là [0,9999]. Với biến thang, ta chọn các giá trị biên và cận biên để thực hiện kiểm thử là 0, 1, 2, 11, 12, 13 và một giá trị ở giữa là 6 dại diện cho giá trị thông thường của
thang. Với biến nam, ta chọn các giá trị biên và cận biên để thực hiện kiểm thử là -1, 0, 1, 9998, 9999, 10000 và một giá trị ở giữa là 5000 đại diện cho giá trị thông thường của nam.
Đầu ra của hàm là hai giá trị thang, nam thỏa mãn các biểu thức điều kiện trên mã nguồn. Các ca kiểm thử thỏa mãn nhánh case kiểm tra các tháng 1 và từ tháng 3 đến tháng 12 đã được sinh bởi công cụ nên ta không thực hiện lại. Ta quan tâm đến biểu thức điều kiện case kiểm tra tháng 2 của hàm. Tại dòng 22, biến đầu ra của hàm là giá trị year thỏa mãn biểu thức(year%400==0)||((year%4==0) &&(year%100!=0). Toán tử liên kết giữa biểu thức (year%400==0) và ((year%4==0)&&(year%100!=0) là toán tử "||" nên câu lệnh 22 đúng khi một trong hai biểu thức là đúng. Ta chọn giá trị biên để kiểm thử cho biểu thức (year %400==0) là year=2000, các giá trị cận biên là 1999 và 2001. Với biểu thức
((year%4==0)&&(year%100!=0)), ta chọn giá trị kiểm thử là year = 1996 làm giá trị biên, các giá trị cận biên là 1995, 1997. Bảng 3.7 mô tả các ca kiểm thử giá trị biên cho hàm songay. Các dữ liệu kiểm thử sẽ được sử dụng để kiểm thử giá trị biên cho các bài tập của học sinh.
Kết quả kiểm thử giá trị biên trên hai bài tập của học sinh được ghi lại trong Bảng 3.8. Với mã nguồn của của học sinh thứ nhất, phát hiện được bảy ca kiểm thử lỗi trên biên. Trên mã nguồn của học sinh thứ hai, phát hiện được mười ba ca kiểm thử lỗi trên biên. So với các ca kiểm thử sinh ra từ công cụ, bộ ca kiểm thử giá trị biên đã giúp phát hiện thêm các lỗi xảy ra trên các bài làm của học sinh.
Bảng 3.7. Các ca kiểm thử giá trị biên cho hàm songay
Bảng 3.8. Kết quả kiểm thử giá trị biên bài tập tính số ngày trong tháng của hai học sinh
Hàm kiểm thử Số ca kiểm thử biên Số lỗi phát hiện
songay_1(int thang, int nam) 55 7
songay_2 (int thang, int nam) 55 33
STT Input EO RO STT Input EO
thang Nam Thang nam
1 0 -1 -1 29 11 -1 -1 2 0 0 -1 30 11 0 30 3 0 1 -1 31 11 1 30 4 0 500 -1 32 11 500 30 5 0 9998 -1 33 11 9998 30 6 0 9999 -1 34 11 9999 30 7 0 100000 -1 35 11 100000 -1 8 1 -1 -1 36 12 -1 -1 9 1 0 31 37 12 0 31 10 1 1 31 38 12 1 31 11 1 500 31 39 12 500 31 12 1 9998 31 40 12 9998 31 13 1 9999 31 41 12 9999 31 14 1 100000 -1 42 12 10000 -1 15 2 -1 -1 43 13 -1 -1 16 2 0 0 44 13 0 -1 17 2 1 19 45 13 1 -1 18 2 500 0 46 13 500 -1 19 2 9998 0 47 13 9998 -1 20 2 9999 0 48 13 9999 -1 21 2 100000 -1 49 13 10000 -1 22 6 -1 -1 50 2 1995 28 23 6 0 31 51 2 1996 29 24 6 1 31 52 2 1997 28 25 6 500 31 53 2 1999 28 26 6 9998 31 54 2 2000 29 27 6 9999 31 55 2 2001 28 28 6 100000 -1
Bài toán 3: Tìm ước số chung lớn nhất
Hình 3.18 là mã nguồn chuẩn của hàm timuscln mà ta dùng để sinh các ca kiểm thử cho bài toán tìm ước số chung lớn nhất của hai số nguyên. Hàm nhận giá trị đầu vào là hai số nguyên x và y, đầu ra là ước số chung lớn nhất của x và y.
Hình 3.18. Mã nguồn chuẩn của hàm timuscln
Ta sử dụng công cụ, để sinh ca kiểm thử với độ phủ cao nhất của hàm timuscln. Sinh ca kiểm thử phủ điều kiện con, kết quả cho ta sáu ca kiểm thử được mô tả trong