SlideShare une entreprise Scribd logo
1  sur  59
ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
Nguyễn Đức Anh
XÂY DỰNG CÔNG CỤ KIỂM THỬ TỰ ĐỘNG CHO
CÁC CHƯƠNG TRÌNH C
KHÓA LUẬN TỐT NGHIỆP ĐẠI HỌC HỆ CHÍNH QUY
Ngành: Công nghệ thông tin
HÀ NỘI – 2015
ĐẠI HỌC QUỐC GIA HÀ NỘI
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ
Nguyễn Đức Anh
XÂY DỰNG CÔNG CỤ KIỂM THỬ TỰ ĐỘNG CHO
CÁC CHƯƠNG TRÌNH C
KHÓA LUẬN TỐT NGHIỆP ĐẠI HỌC HỆ CHÍNH QUY
Ngành: Công Nghệ Thông Tin
Cán bộ hướng dẫn: TS. Phạm Ngọc Hùng
(ký tên)
HÀ NỘI - 2015
LỜI CẢM ƠN
VIETNAM NATIONAL UNIVERSITY, HANOI
UNIVERSITY OF ENGINEERING AND TECHNOLOGY
Nguyen Duc Anh
A METHOD AND TOOL SUPPORTING FOR
AUTOMATED TESTING OF C PROGRAMS
THE BS THESIS
Major: Information Technology
Supervisor: Dr. Pham Ngoc Hung
HA NOI - 2015
LỜI CẢM ƠN
Đầu tiên, tôi xin gửi lời cám ơn chân thành tới Tiến sĩ Phạm Ngọc Hùng – giảng
viên bộ môn Công Nghệ Phần Mềm – người đã hướng dẫn tận tình, tỉ mỉ, chu đáo tôi
trong suốt hai năm làm khóa luận tốt nghiệp. Quãng thời gian được thầy hướng dẫn đã
giúp tôi học hỏi, đúc kết được nhiều kinh nghiệm về phương pháp nghiên cứu, kĩ năng
giao tiếp, kĩ năng làm việc nhóm, kĩ năng trình bày. Thầy còn truyền cho tôi ngọn lửa yêu
nghiên cứu khoa học, niềm tin vượt qua những khó khăn trong cuộc sống và dạy tôi cách
vượt qua những khó khăn đó. Tôi cảm thấy tự hào và may mắn khi là một sinh viên được
thầy hướng dẫn trong những năm tháng đại học.
Ngoài ra, tôi xin gửi lời cám ơn chân thành đến tập thể lớp K56 đã giúp đỡ tôi nhiệt
tình để hoàn thành khóa luận sao cho đạt hiệu quả cao nhất. Các bạn đã giúp đỡ tôi bằng
hành động, bằng lời nói mỗi khi tôi gặp khó khăn, thất bại. Bốn năm bên nhau không phải
là dài nhưng đối với tôi, đây là quãng thời gian tuyệt vời nhất và không thể nào quên.
Tiếp theo, tôi xin gửi lời cảm ơn đến các thầy cô giảng viên Trường Đại học Công
Nghệ - Đại học Quốc Gia Hà Nội – những người đã tận tâm truyền đạt những kiến thức
quý báu làm nền tảng để tôi tiếp tục đi xa hơn nữa trong lĩnh vực công nghệ thông tin.
Cuối cùng, tôi xin được cảm ơn gia đình đã nuôi tôi khôn lớn để trở thành người có
ích cho xã hội, giúp tôi có một điểm tựa vững chắc để yên tâm học hành trong suốt bao
năm qua. Tôi xin gửi lời cám ơn chân thành tới cha, mẹ, em gái đã luôn động viên và cổ
vũ tôi mỗi khi tôi gặp khó khăn và thử thách.
Hà Nội, ngày 03 tháng 05 năm 2014
Sinh viên
Nguyễn Đức Anh
TÓM TẮT
Ngày nay, ngôn ngữ C là một trong những ngôn ngữ lập trình phổ biến để phát triển phần
mềm, đặc biệt là các phần mềm hệ thống. Một trong những kĩ thuật kiểm thử hiệu quả hay được
sử dụng là sinh ca kiểm thử trong kiểm thử hộp trắng dòng điều khiển. Để tiết kiệm chi phí kiểm
thử phần mềm, quá trình sinh ca kiểm thử nên được tự động hóa hết mức có thể. Trong khi đó,
các công cụ kiểm thử hiện nay chỉ tập trung vào thực thi các ca kiểm thử mà ít quan tâm đến sinh
ca kiểm thử tự động. Một vài công cụ kiểm thử sinh ca kiểm thử tự động nhưng số lượng ca kiểm
thử không xác định hoặc khá lớn gây khó khăn cho quản lý, ngoài ra còn hạn chế về thời gian
sinh ca kiểm thử.
Vì thế, khóa luận đề xuất một phương pháp sinh ca kiểm thử tự động cho một hàm C chứa
các biến số nguyên, số thực và biến mảng sử dụng kĩ thuật kiểm thử hộp trắng dòng điều khiển
theo hướng tĩnh và cài đặt công cụ hỗ trợ CFT4CUnit. Đầu vào gồm một hàm C và tiêu chí phủ
kiểm thử phủ. Đầu ra gồm tập ca kiểm thử thỏa mãn tiêu chí phủ kiểm thử và tập ca kiểm thử để
kiểm thử vòng lặp (nếu hàm C có vòng lặp). Cụ thể bước đầu tiên, mã nguồn được phân tích để
sinh đồ thị dòng điều khiển thỏa mãn tiêu chí phủ kiểm thử. Sau đó, đồ thị dòng điều khiển được
phân tích để xây dựng tập đường kiểm thử. Tiếp theo, các đường kiểm thử chứa vòng lặp được
cấu trúc lại để sinh thêm các đường kiểm thử mới dùng kiểm thử tính đúng đắn vòng lặp. Kế tiếp,
các đường kiểm thử được phân tích bằng kĩ thuật SE để xây dựng hệ ràng buộc tương ứng. Cuối
cùng, hệ ràng buộc được giải để sinh ca kiểm thử bằng cách kết hợp kĩ thuật sinh ngẫu nhiên và
tận dụng thế mạnh các công cụ SMT-Solver. Kết quả thực nghiệm cho thấy khả năng phát hiện
được lỗi khá tốt trong hàm C với số bộ ca kiểm thử tối thiểu mà vẫn đảm bảo tính đúng đắn cao
của mã nguồn. Ngoài ra, thời gian sinh ca kiểm thử được cải thiện đáng kể và giải được nhiều hệ
ràng buộc khác nhau vì kết hợp kĩ thuật sinh ngẫu nhiên và sử dụng công cụ SMT-Solver.
Từ khóa: Kiểm thử tự động, hàm C, đồ thị dòng điều khiển, ca kiểm thử, Symbolic Execution,
SMT-Solver
ABSTRACT
Nowadays, C programming language has been known as one of the most popular
programming languages to develope applications, especially system applications. Because of
high demand in quality, testing phase is performed quite rigorously and strictly. As a result, the
cost of the testing phase can be up to 40% - 60% the total cost of application development
process.
Test case generation in white-box testing is an effective technique and used widely to
ensure the high quality of applications. To reduce the cost of the testing phase, the test case
generation process should be automated as much as possible. However, some testing tools focus
on executing test cases and output the testing report instead of generating test cases
automatically. Other testing tools assist to generate test cases automatically but the number of test
cases may be a lot or un-known which cause many difficult and challenging problems such as
management, time limit, etc.
The thesis proposes an approach how to generate test cases automatically for C Unit
containing integer variables, float variables, array variables. The proposed approach is based on
white-box testing and implements in CFT4CUnit tool to demonstrate the effectiveness of the
approach. Firstly, source code is analysed to generate corresponding Control Flow Graph (CFG).
Then I traverse the CFG to obtain the independent paths. After that, paths containing loop is re-
constructed to create some new paths used to test the loop. Next, each path is analysed by using
symbolic execution technique to generate corresponding constraints. Finally, the process of
solving the constraints is performed to find solution as fast as possible by combining random
technique and SMT-Solvers. The experimental result shows the effectiveness of the approach
with the minimum number of test cases but ensures the high quality of source code.
Keywords: automated testing, C Unit, control flow testing, test case, symbolic execution, SMT-
Solver
LỜI CAM ĐOAN
Tôi xin cam đoan rằng những nghiên cứu về kiểm thử tự động cho hàm C được trình
bày trong luận án này là của tôi và chưa từng được nộp như một báo cáo khóa luận tại
trường Đại học Công Nghệ - Đại học Quốc Gia Hà Nội hoặc bất kỳ trường đại học khác.
Những gì tôi viết ra không sao chép từ các tài liệu, không sử dụng các kết quả của người
khác mà không trích dẫn cụ thể.
Tôi xin cam đoan công cụ kiểm thử tự động tôi trình bày trong khoá luận là do tôi tự
phát triển, không sao chép mã nguồn của người khác. Nếu sai tôi hoàn toàn chịu trách
nhiệm theo quy định của trường Đại học Công Nghệ - Đại học Quốc Gia Hà Nội.
Hà Nội, ngày 03 tháng 05 năm 2015
Sinh viên
Nguyễn Đức Anh
MỤC LỤC
Đặt vấn đề.................................................................................................................1Chương 1.
Tổng quan kĩ thuật kiểm thử hộp trắng dòng điều khiển....................................4Chương 2.
2.1. Tổng quan kĩ thuật kiểm thử hộp trắng dòng điều khiển.........................................4
2.2. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng động ..........4
2.3. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh............6
2.3.1. Các tiêu chí phủ kiểm thử..................................................................................7
2.3.2. Đồ thị dòng điều khiển ......................................................................................8
2.3.3. Đường kiểm thử.................................................................................................9
2.4. So sánh kĩ thuật kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh và động ...10
2.5. Tầm quan trọng của tự động hóa quy trình kiểm thử hộp trắng dòng điều khiển .11
Phương pháp kiểm thử tự động hàm C sử dụng kĩ thuật kiểm thử hộp trắngChương 3.
dòng điều khiển theo hướng tĩnh................................................................................................12
3.1. Tổng quan phương pháp kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh.....12
3.2. Sinh đồ thị dòng điều khiển từ mã nguồn ..............................................................13
3.3. Xây dựng tập đường kiểm thử từ đồ thị dòng điều khiển......................................16
3.3.1. Xây dựng tập đường đi độc lập........................................................................16
3.3.2. Xây dựng đường kiểm thử vòng lặp................................................................17
3.3.2.1. Kiểm thử đường đi chứa vòng lặp đơn.....................................................18
3.3.2.2. Kiểm thử đường đi chứa hai vòng lặp lồng nhau....................................19
3.4. Sinh tập dữ liệu kiểm thử từ tập đường kiểm thử ..................................................20
3.4.1. Xây dựng hệ ràng buộc....................................................................................20
3.4.2. Tìm nghiệm thỏa mãn hệ ràng buộc ................................................................22
3.4.2.1. Giải hệ sử dụng kĩ thuật sinh ngẫu nhiên ................................................22
3.4.2.2. Giải hệ sử dụng SMT-Solver...................................................................23
3.4.2.3. So sánh ưu điểm, nhược điểm của hai hướng sinh ca kiểm thử..............29
Thực nghiệm ..........................................................................................................31Chương 4.
4.1. Các thư viện hỗ trợ.................................................................................................31
4.1.1. Giới thiệu về thư viện SMT-Solver SmtInterpol.............................................31
4.1.2. Giới thiệu về thư viện CDT .............................................................................31
4.1.3. Giới thiệu về thư viện Jeval.............................................................................32
4.2. Giới thiệu công cụ kiểm thử tự động hàm C..........................................................32
4.2.1. Tổng quan về công cụ CFT4CUnit..................................................................32
4.2.1. Đầu vào công cụ ..............................................................................................33
4.2.2. Đầu ra công cụ..................................................................................................34
4.2.2.1. Đồ thị dòng điều khiển ............................................................................34
4.2.2.2. Tập đường kiểm thử ................................................................................35
4.2.2.3. Tập ca kiểm thử.......................................................................................36
4.2.2.4. Biểu thức chuẩn SMT-Lib.......................................................................37
4.2.2.5. Kiểm thử vòng lặp đơn............................................................................37
4.2.2.6. Kiểm thử vòng lặp lồng nhau ..................................................................38
4.2.3. Thực nghiệm.....................................................................................................39
4.2.4. Ý nghĩa thực nghiệm .......................................................................................43
Kết luận ..................................................................................................................45Chương 5.
DANH SÁCH BẢNG
Bảng 1. Độ ưu tiên các toán tử ......................................................................................................26
Bảng 2. So sánh CFT4CUnit, công cụ đề xuất trong [5] và PathCrawler.....................................40
Bảng 3. Kiểm thử vòng lặp đơn sử dụng công cụ CFT4CUnit .....................................................40
Bảng 4. Kiểm thử hai vòng lặp lồng nhau hàm SelectionSort sử dụng công cụ CFT4CUnit.......42
DANH SÁCH KÝ HIỆU, CHỮ VIẾT TẮT
AST Abstract Syntax Tree
CFG Control Flow Graph
CDT C/C++ Development Tooling
CVC Cooperating Validity Checker
DIMACS Center for Discrete Mathematics and Theoretical Computer Science
SMT-Solver Satisfiability Modulo Theories Solver
SAT Boolean Satisfiability Problem
T-Solver Theory-specific Solvers
SE Symbolic Execution
DANH SÁCH HÌNH VẼ
Hình 2.1. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng động..................5
Hình 2.2: Ví dụ một luật chèn mã nguồn trong DMS/SRT.............................................................6
Hình 2.3. Mã nguồn hàm triangle sau khi thêm khối mã nguồn mới..............................................6
Hình 2.4. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh....................7
Hình 2.5: Các cấu trúc điều khiển phổ biến. ...................................................................................9
Hình 3.1. Quy trình kiểm thử một hàm C theo phương pháp đề xuất...........................................12
Hình 3.2. Thuật toán sinh CFG từ mã nguồn ................................................................................13
Hình 3.3. Mã nguồn hàm average. ................................................................................................14
Hình 3.4. CFG hàm average tiêu chuẩn phủ câu lệnh, phủ nhánh. ...............................................15
Hình 3.5. CFG điều kiện kép (a>=0 || ((b>=0 && c>=0) || b+c>=0) || a+b+c>=0).......................16
Hình 3.6. Thuật toán sinh tập đường đi độc lập từ CFG. ..............................................................17
Hình 3.7. Thuật toán sinh đường kiểm thử vòng lặp.....................................................................18
Hình 3.8. Thuật toán sinh đường kiểm thử vòng lặp trong. ..........................................................19
Hình 3.9. Thuật toán sinh đường kiểm thử vòng lặp ngoài...........................................................20
Hình 3.10. Ví dụ một hệ ràng buộc. ..............................................................................................21
Hình 3.11. Thuật toán sinh hệ ràng buộc từ đường kiểm thử........................................................21
Hình 3.12. Quá trình rút gọn câu lệnh...........................................................................................22
Hình 3.13. Mô tả đầu vào, đầu ra SMT-Solver. ............................................................................24
Hình 3.14. Ví dụ hệ ràng buộc tuân theo chuẩn SMT-Lib. ...........................................................25
Hình 3.15. Quá trình chuyển một biểu thức trung tố về chuẩn SMT-Lib. ....................................25
Hình 3.16. Thuật toán xây dựng biểu thức hậu tố. ........................................................................27
Hình 3.17. Thuật toán xây dựng cây biểu thức từ biểu thức hậu tố. .............................................28
Hình 3.18. Thuật toán duyệt cây biểu thức....................................................................................29
Hình 4.1. Minh họa cây AST ứng với mã nguồn return x*3 ........................................................32
Hình 4.2. Giao diện công cụ đề xuất. ............................................................................................33
Hình 4.3. Ví dụ đầu vào công cụ CFT4CUnit...............................................................................33
Hình 4.4. Đồ thị CFG tiêu chí phủ câu lệnh và phủ nhánh. ..........................................................34
Hình 4.5. Đồ thị CFG tiêu chí phủ điều kiện con..........................................................................34
Hình 4.6. Đường đi tương ứng trên CFG được bôi đỏ khi click vào một đường kiểm thử bất kì.35
Hình 4.7. Tập đường kiểm thử thỏa mãn phủ câu lệnh hàm foo...................................................35
Hình 4.8. Tập đường kiểm thử thỏa mãn phủ nhánh hàm foo.......................................................35
Hình 4.9. Tập đường kiểm thử thỏa mãn phủ điều kiện con hàm foo...........................................36
Hình 4.10. Tập đường đi độc lập để sinh tập đường kiểm thử phủ nhánh và phủ câu lệnh..........36
Hình 4.11. Ca kiểm thử thỏa mãn đường đi màu đỏ sinh theo kĩ thuật ngẫu nhiên và dùng SMT-
Solver.............................................................................................................................................36
Hình 4.12. Hệ ràng buộc chuẩn SMT-Lib tương ứng với đường kiểm thử màu đỏ......................37
Hình 4.13. Kiểm thử vòng lặp đơn hàm tinh_tong........................................................................38
Hình 4.14. Kiểm thử một đường kiểm thử chứa hai vòng lặp lồng nhau trong hàm SelectionSort.
.......................................................................................................................................................38
1
Đặt vấn đềChương 1.
Ngày nay, ngôn ngữ C là một trong những ngôn ngữ lập trình phổ biến để phát triển
các hệ thống nhúng nói riêng, các phần mềm hệ thống nói chung và các phần mềm ứng
dụng. Các thống kê trên githut1
và TIOBE2
cho thấy ngôn ngữ C là một trong mười ngôn
ngữ lập trình phổ biến nhất năm 2014.
Thực tế, các phần mềm (đặc biệt là phần mềm hệ thống) thường yêu cầu cao về chất
lượng nên đòi hỏi quá trình kiểm thử thực hiện khắt khe và nghiêm ngặt. Vì thế, kiểm thử
hộp trắng được coi là một kĩ thuật an toàn và hiệu quả nhằm đảm bảo độ tin cậy cao của
phần mềm. Ưu điểm của kiểm thử hộp trắng là tìm lỗi bằng cách xem xét trực tiếp trên
mã nguồn trong khi kiểm thử hộp đen chỉ phát hiện được những lỗi dựa trên tài liệu đặc tả
phần mềm. Rõ ràng, dù tài liệu đặc tả tốt đến đâu, nếu kiểm thử viên chỉ tìm kiếm lỗi dựa
trên đặc tả sẽ không thể phát hiện được những lỗi lập trình tiềm ẩn gây nên lỗi khi chạy
phần mềm, vì thế chỉ sử dụng kiểm thử hộp đen là chưa đủ để thỏa mãn tiêu chí độ tin cậy
cao.
Trong bối cảnh ngành công nghiệp phần mềm hiện nay, kiểm thử hộp trắng cần
được tự động hóa hết mức có thể [1]. Nói chung, kiểm thử là một quá trình rất tốn thời
gian, công sức và chi phí có thể chiếm 40% – 60% tổng chi phí trong toàn bộ quá trình
phát triển phần mềm [2]. Thêm nữa, độ phức tạp mã nguồn của các phần mềm ngày càng
tăng khiến khối lượng mã nguồn cần kiểm thử hộp trắng không chỉ tăng lên mà còn khó
phân tích hơn rất nhiều. Vì thế, kiểm thử tự động là một giải pháp hiệu quả nhằm giúp
kiểm thử viên bớt nhàm chán, giảm thiểu thời gian, công sức và chi phí trong khi vẫn đảm
bảo độ tin cậy cao của phần mềm. Ngoài ra, kiểm thử tự động không chỉ có ý nghĩa khi dự
án không đủ tài nguyên mà còn trong kiểm thử hồi quy khi phần mềm cần sửa đổi hoặc
nâng cấp.
Trong phương pháp kiểm thử hộp trắng, kiểm thử viên không chỉ cần hiểu rõ giải
thuật mà còn cần có các kỹ năng và kiến thức tốt về ngôn ngữ lập trình viết mã nguồn,
nhằm hiểu rõ mã nguồn cần kiểm thử. Hơn nữa, việc áp dụng các kĩ thuật kiểm thử hộp
1
github là nơi lưu trữ mã nguồn trực tuyến rất phổ biến và mạnh mẽ
2
Tiêu chí đánh giá tính phổ biến ngôn ngữ lập trình dựa trên số kết quả tìm kiếm trả về khi truy vấn tên ngôn ngữ lập
trình trên các trên mạng nổi tiếng gồm Google, Google Blogs, MSN, Yahoo, Baidu, Wikipedia và Youtube
2
trắng thường tốn thời gian và công sức nhất là khi mã nguồn cần kiểm thử có độ phức tạp
cao. Vì vậy, các kĩ thuật kiểm thử hộp trắng chủ yếu được sử dụng cho kiểm thử đơn vị.
Kiểm thử hộp trắng có hai kĩ thuật phổ biến là kiểm thử hộp trắng dòng điều khiển
và kiểm thử hộp trắng dòng dữ liệu. Kiểm thử hộp trắng dòng dữ liệu là kĩ thuật tìm kiếm
lỗi thường hay xuất hiện liên quan đến phép gán và sử dụng các biến trong chương trình.
Trong khi đó, kiểm thử hộp trắng dòng điều khiển tập trung kiểm thử tính đúng đắn của
các giải thuật sử dụng trong chương trình. Mỗi một kĩ thuật kiểm thử nêu trên đều có thế
mạnh riêng và không thể thay thế cho nhau được.
Hai kĩ thuật phổ biến trong kiểm thử hộp trắng dòng điều khiển là theo hướng tĩnh
và hướng động. Dù là hướng tĩnh hay hướng động, mục đích cuối cùng là làm sao sinh tập
ca kiểm thử đủ tốt để kiểm tra tính đúng đắn mã nguồn. Các công cụ kiểm thử hướng
động khá phổ biến gồm PathCrawler[11], CAUT3
, CREST4
. Theo cách tiếp cận này, mã
nguồn sẽ được bổ sung thêm các câu lệnh mới để lưu vết đường đi khi thực thi một bộ
đầu vào. Mỗi một đường đi tương ứng với một hệ ràng buộc, ca kiểm thử tiếp theo được
sinh ra bằng cách phủ định hệ ràng buộc đó. Hạn chế thứ nhất, nếu không tìm được ca
kiểm thử đầu tiên, hay hệ ràng buộc đầu tiên, quá trình kiểm thử không thể tiếp tục. Hạn
chế thứ hai, số bộ kiểm thử sinh ra tương đối lớn (hoặc không xác định) do số lượng hệ
ràng buộc phủ định không ít, đặc biệt với vòng lặp có biến lặp lớn hoặc số lần lặp không
xác định. Hạn chế thứ ba, thời gian sinh ca kiểm thử lâu hơn do phải thực thi lại mã
nguồn nhiều lần trong môi trường chạy. Hạn chế thứ tư, số lượng hệ ràng buộc cần giải
khá lớn (đặc biệt mã nguồn có vòng lặp) và tính đa dạng hệ ràng buộc nên chỉ dùng kĩ
thuật sinh ngẫu nhiên là không khả thi mà phải sử dụng thêm SMT-Solver. Tuy các công
cụ này tận dụng thế mạnh SMT-Solver, tổng chi phí thời gian sinh ca kiểm thử vẫn hơn
đáng kể so với kiểm thử tĩnh.
Khóa luận này đề xuất cách sinh ca kiểm thử cho một hàm C sử dụng kĩ thuật kiểm
thử hộp trắng dòng điều khiển theo hướng tĩnh để giải quyết những hạn chế nêu trên. Tư
tưởng chính của phương pháp đề xuất là tập trung phân tích cấu trúc mã nguồn để sinh ca
kiểm thử thay vì thực thi mã nguồn lặp lại nhiều lần. Kết quả là thời gian sinh tập ca kiểm
thử nhanh hơn do giảm bớt số lần thực thi mã nguồn. Hơn nữa, số lượng ca kiểm thử tối
3
http://www.lab205.org/caut/
4
https://code.google.com/p/crest/
3
thiểu thay vì khá lớn mà vẫn đảm bảo tính đúng đắn cao của mã nguồn. Ngoài ra, thời
gian sinh một ca kiểm thử nhanh hơn do tận dụng thế mạnh công cụ SMT-Solver. Cuối
cùng, bởi vì có sự kết hợp kĩ thuật sinh ngẫu nhiên và tận dụng thế mạnh công cụ SMT-
Solver nên giải được nhiều dạng hệ ràng buộc khác nhau.
Phần còn lại khóa luận được trình bày như sau. Đầu tiên, chương 2 giới thiệu tổng
quan và đưa ra sự so sánh về kĩ thuật kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh
và hướng động. Tiếp theo, phương pháp đề xuất dựa trên kĩ thuật kiểm thử hộp trắng
dòng điều khiển theo hướng tĩnh được trình bày trong chương 3. Sau đó, chương 4 mô tả
công cụ triển khai phương pháp đề xuất và thực nghiệm. Cuối cùng, chương 5 trình bày
tóm tắt các kết quả đã đạt được, kết luận, những hạn chế và hướng nghiên cứu phát triển
trong tương lai.
4
Tổng quan kĩ thuật kiểm thử hộp trắng dòng điều khiểnChương 2.
Ở phần này, khóa luận trình bày các kiến thức tổng quan về kiểm thử hộp trắng dòng
điều khiển gồm hai kĩ thuật kiểm thử hướng tĩnh và hướng động, đồng thời đưa ra sự so
sánh về ưu điểm và nhược điểm của từng kĩ thuật.
2.1. Tổng quan kĩ thuật kiểm thử hộp trắng dòng điều khiển
Kiểm thử hộp trắng dòng điều khiển chia ra gồm kiểm thử hướng tĩnh và kiểm thử
hướng động. Đầu vào của hai kĩ thuật này đều là mã nguồn và tiêu chí phủ kiểm thử. Sau
một loạt quá trình phân tích, đầu ra tương ứng là tập ca kiểm thử. Mỗi một kĩ thuật đều có
những ưu điểm và hạn chế riêng. Mục tiêu của kiểm thử hộp trắng dòng điều khiển là tìm
tập ca kiểm thử tối thiểu nhưng đạt được độ phủ tối đa.
2.2. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng động
Theo kĩ thuật này, mã nguồn sẽ được thêm các đoạn chương trình con trước khi thực
thi trong môi trường chạy. Hình 2.1 trình bày quy trình chung của kiểm thử động. Nhìn
chung, kĩ thuật này gồm 6 bước cơ bản được diễn giải theo thứ tự dưới đây:
Bước 1. Chèn thêm các đoạn mã nguồn mới vào mã nguồn cần kiểm thử.
Bước 2. Chọn ngẫu nhiên một tập giá trị đầu vào hợp lệ làm ca kiểm thử đầu tiên.
Bước 3. Thực thi chương trình với bộ giá trị vừa tìm được. Nếu không thực thi
được, quay lại bước 2 để sinh bộ giá trị khác.
Bước 4. Tìm tập các câu lệnh đã được đi qua với bộ giá trị ở bước 3 để xây dựng
được hệ ràng buộc tương ứng.
Bước 5. Phủ định hệ ràng buộc thu được ở bước 4 để sinh các hệ ràng buộc mới
có tác dụng sinh các ca kiểm thử kế tiếp. Nếu không thể sinh hệ phủ định nào
khác, thuật toán kết thúc.
Bước 6. Giải hệ ràng buộc thu được ở bước 5 để sinh ca kiểm thử kế tiếp. Nếu
không có ca kiểm thử nào thỏa mãn, quay về bước 5 để tìm hệ ràng buộc phủ
định mới sao cho khác hệ ràng buộc hiện tại. Ngược lại, quay lại bước 3 để
sinh ca kiểm thử kế tiếp.
5
Hình 2.1. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng động.
Trong bước 1, quá trình chèn thêm khối mã nguồn mới vào mã nguồn cần kiểm thử
được tiến hành một cách tự động. Công cụ DMS/SRT5
được đánh giá khá mạnh mẽ để
thực hiện pha này. Đoạn mã nguồn thêm vào có chức năng đánh dấu, thoát chương trình
hoặc ghi thông tin về quá trình thực thi ra tệp, v.v. Để làm được điều này, chúng tôi cần
xây dựng các luật chèn thêm mã nguồn mới vào mã nguồn cần kiểm thử.
Với công cụ DMS/SRT, mỗi một luật bắt đầu với từ khóa rule và theo sau là tên đặt
cho luật. Từ khóa rewrite to nêu cách biến đổi đoạn mã nguồn gốc về đoạn mã nguồn
mới. Kiểu dữ liệu có thể là expression (ứng với biểu thức), statement (ứng với câu lệnh
gán hoặc khởi tạo), type (ứng với kiểu dữ liệu), identifier (ứng với định danh như tên
biến, tên hàm), v.v. Hình 2.2 mô tả một luật chèn thêm câu lệnh đánh dấu vào khối lệnh
điều khiển rẽ nhánh. Cụ thể, biến mảng visited đánh dấu vị trí câu lệnh đi qua được bổ
5
http://www.semanticdesigns.com/Products/DMS/DMSToolkit.html
Source
code
Tiêu chí
phủ
Pha chèn thêm khối
lệnh mới
Tìm ca kiểm thử
khởi đầu ngẫu nhiên
Thực thi ca kiểm
thử vừa tìm được
Tái tạo đường thực thi
Tạo đường thực thi mới
Tìm được ca
kiểm thử mới
TrueFalseKết
thúc
6
sung vào mã nguồn ban đầu ngay sau mỗi khối lệnh điều khiển rẽ nhánh. Hình 2.3 đưa ra
mã nguồn triangle sau khi áp dụng luật.
Hình 2.2: Ví dụ một luật chèn mã nguồn trong DMS/SRT.
Hình 2.3. Mã nguồn hàm triangle sau khi thêm khối mã nguồn mới.
2.3. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh
Trong kiểm thử tĩnh, mã nguồn không được thực thi trong môi trường chạy để sinh
ca kiểm thử. Trong kiểm thử tĩnh, quá trình chạy ca kiểm thử chỉ thực hiện duy nhất một
7
lần với từng ca kiểm thử để tính toán giá trị trả về và đảm bảo ca kiểm thử thực thi không
có vấn đề. Các bước tổng quát trong kĩ thuật này được trình bày ở Hình 2.4. Đầu tiên, đồ
thị dòng điều khiển được xây dựng dựa trên mã nguồn và tiêu chí phủ kiểm thử. Bước
tiếp theo, từ đồ thị dòng điều khiển chúng tôi xây dựng được tập đường kiểm thử. Mỗi
một đường kiểm thử trong tập đường kiểm thử mô tả hành vi chương trình với một miền
bộ đầu vào nào đó. Sau đó, pha tìm ca kiểm thử thỏa mãn đường kiểm thử được tiến hành.
Cuối cùng, ca kiểm thử được thực thi trong môi trường chạy.
Hình 2.4. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh.
2.3.1. Các tiêu chí phủ kiểm thử
Tiêu chí phủ kiểm thử là một thước đo để đánh giá tính đúng đắn của mã nguồn cần
kiểm thử với một tập ca kiểm thử nào đó. Tập ca kiểm thử khiến mã nguồn có độ phủ cao
được đánh giá là tốt hơn so với tập ca kiểm thử khác khiến mã nguồn có độ phủ thấp hơn.
Chất lượng mã nguồn được đánh giá tỉ lệ thuận với độ phủ.
Độ phủ được đánh giá dựa trên hai thông số gồm tiêu chí phủ kiểm thử và tập ca
kiểm thử. Công thức tính độ phủ là tỉ lệ các thành phần được kiểm thử trên tổng số các
thành phần cần kiểm thử sau khi đã thực hiện tập ca kiểm thử. Thành phần có thể là câu
lệnh, điểm quyết định, điều kiện con, đường thi hành hoặc là sự kết hợp của chúng.
Source code
Tiêu chí phủ
Xây dựng đồ thị
dòng điều khiển
Xây dựng tập
đường kiểm thử
Tìm tập ca kiểm thử
Thực thi tập ca
kiểm thử
Kết thúc
8
Tiêu chí phủ kiểm thử được giới thiệu lần đầu tiên vào 1963 trong tạp chí hàng
tháng “Communications of the ACM”. Cho tới nay, nhiều tiêu chí phủ kiểm thử được đưa
ra. Khóa luận sử dụng ba tiêu chí phủ kiểm thử phổ biến để đánh giá chất lượng mã nguồn
gồm:
 Phủ câu lệnh: Mỗi một câu lệnh được thực thi ít nhất một lần sau khi chạy tập ca
kiểm thử.
 Phủ nhánh: Mỗi một nhánh đều được đi qua ít nhất một lần sau khi chạy tập ca
kiểm thử.
 Phủ điều kiện con: Mọi nhánh đúng-sai đều được đi qua với một tập ca kiểm thử
nào đó, trong đó các câu lệnh điều kiện kép được phân tách thành các câu lệnh điều
kiện đơn.
2.3.2. Đồ thị dòng điều khiển
Sinh ca kiểm thử dựa trên mã nguồn phức tạp và khó khăn hơn so với sinh ca kiểm
thử dựa trên đồ thị dòng điều khiển (Control Flow Graph – CFG). CFG là một đồ thị có
hướng mô tả cấu trúc lôgic của chương trình một cách trực quan và đơn giản hơn, gồm có
các đỉnh tương ứng với các câu lệnh/nhóm câu lệnh và các cạnh là các dòng điều khiển
giữa các câu lệnh/nhóm câu lệnh. Đỉnh đầu tiên của CFG là trạng thái đầu tiên của hàm,
đỉnh cuối cùng của CFG là trạng thái kết thúc của hàm. Đỉnh i nối đến đỉnh j thì câu lệnh
tương ứng đỉnh j có thể được thực thi sau khi thực hiện câu lệnh tương ứng ở đỉnh i.
Trong ngôn ngữ C, các cấu trúc điều khiển trong CFG gồm tuần tự, rẽ nhánh,
while...do, do...while, for. Hình 2.5 minh họa các cấu trúc điều khiển nêu trên. Trong đó
đỉnh có nhãn c tượng trưng cho câu lệnh điều kiện. Các đỉnh còn lại tượng trưng câu lệnh
gán, khai báo, v.v. Các thành phần cơ bản của đồ thị dòng điều khiển gồm đỉnh xuất phát,
đỉnh xử lí, đỉnh quyết định, đỉnh kết nối và đỉnh kết thúc.
 Đỉnh xuất phát và đỉnh kết thúc: Hai đỉnh này là duy nhất, trong đó đỉnh xuất phát
đại diện cho tên hàm.
 Đỉnh quyết định: Là đỉnh tương ứng với câu lệnh điều kiện trong khối lệnh điều
khiển rẽ nhánh, do...while, while..do. Ví dụ cụ thể, với khối lệnh điều khiển “if (a
> b) { ... }” thì đỉnh quyết định tương ứng với “a > b”.
 Đỉnh kết nối: Là đỉnh có nhiều hơn hai đỉnh khác trỏ đến mà không phải đỉnh quyết
định.
9
 Đỉnh xử lí: Là đỉnh tương ứng với câu lệnh gán, câu lệnh khởi tạo hoặc câu lệnh
khai báo và không phải đỉnh kết nối. Các khối lệnh điều khiển cũng chứa các loại
câu lệnh này. Ví dụ, khối lệnh “for (i = 0; i < 10; i++)” chứa hai đỉnh xử lí gồm
câu lệnh gán “i = 0” và câu lệnh tăng giá trị biến i là “i++”.
Hình 2.5: Các cấu trúc điều khiển phổ biến.
2.3.3. Đường kiểm thử
Với một bộ giá trị đầu vào, một tập các câu lệnh gán, câu lệnh khai báo và câu lệnh
điều kiện được đi qua. Danh sách các câu lệnh này được sắp theo thứ tự thực hiện chính là
một đường đi. Trong số tất cả các đường đi có thể, một tập đường đi được chọn sao cho
thỏa mãn tiêu chí phủ kiểm thử được gọi là tập đường kiểm thử.
Đường kiểm thử là một đường đi từ đỉnh đầu tiên đến đỉnh cuối cùng của CFG được
biểu diễn dưới một tập các đỉnh từ đỉnh v1 đến đỉnh vn, trong đó hai đỉnh liền kề có cạnh
nối với nhau. Nếu cạnh (vi ,vj) (i j) là nhánh false, câu lệnh lưu ở đỉnh vi được viết phủ
định. Tập đường đi độc lập gồm k đường đi PATH1, PATH2, …, PATHk thỏa mãn: giữa
mọi cặp đường đi độc lập PATHi và PATHj (i j) không chung ít nhất một cạnh trở lên.
Tìm kiếm tập đường kiểm thử là bước trung gian trong quá trình sinh tập ca kiểm
thử. Hai vấn đề liên quan đến tập đường kiểm thử rất quan trọng gồm:
 Vấn đề thực thi được hay không thực thi được. Một đường kiểm thử gọi là thực thi
được nếu tìm kiếm được một ca kiểm thử sao cho khi thực thi trong môi trường
thật thì đường kiểm thử nêu trên được đi qua. Ngược lại, đường kiểm thử gọi là
không thực thi được.
10
 Tính phức tạp mã nguồn. Một mã nguồn gọi là phức tạp nếu chứa nhiều vòng lặp
như nhiều vòng lặp lồng nhau hoặc nhiều vòng lặp nối tiếp nhau, kích thước lớn
hoặc thuật toán phức tạp. Mã nguồn càng phức tạp càng khiến quá trình tìm kiếm
đường kiểm thử trở nên khó khăn hơn và mất thời gian hơn.
2.4. So sánh kĩ thuật kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh và động
Mỗi một kĩ thuật kiểm thử đều có những ưu điểm và hạn chế riêng. Để có cái nhìn
tổng quan về hai kĩ thuật, chúng tôi đưa ra sự so sánh về số ca kiểm thử, thời gian sinh ca
kiểm thử, khả năng kiểm thử vòng lặp, ảnh hưởng bởi phức tạp mã nguồn đối với hai kĩ
thuật.
 Về số ca kiểm thử. Nhìn chung, với mã nguồn chỉ chứa các câu lệnh rẽ nhánh và
không chứa vòng lặp, hai kĩ thuật kiểm thử nêu trên cho số bộ ca kiểm thử như
nhau. Tuy nhiên, trong trường hợp có vòng lặp thì kĩ thuật kiểm thử tĩnh đưa ra số
ca kiểm thử ít hơn so với kiểm thử động. Theo hướng tĩnh, các đường đi chứa vòng
lặp lặp lại một lần sẽ được cấu trúc lại để lặp nhiều hơn một lần. Nói cụ thể hơn, từ
một đường kiểm thử chứa vòng lặp ban đầu sẽ sinh ra một tập các đường kiểm thử
mới dùng để kiểm thử tính đúng đắn vòng lặp. Nếu vòng lặp trong đường kiểm thử
xác định được số lần lặp tối đa thì số đường đi mới sinh ra là bảy. Ngược lại, nếu
vòng lặp không xác định số lần lặp tối đa thì số đường đi mới sinh ra là bốn.
Với mã nguồn chứa vòng lặp, kiểm thử động sử dụng kĩ thuật phủ định hệ để
sinh ca kiểm thử kế tiếp nên số ca kiểm thử có thể rất lớn hoặc không xác định. Cụ
thể, trường hợp số ca kiểm thử rất lớn xảy ra khi vòng lặp có cận lặp lớn, ví dụ,
khối lệnh điều khiển “for (int i = 0; i < 1000; i++)” có số lần lặp tối đa là 1000 lần.
Trường hợp số ca kiểm thử không xác định xảy ra khi số lần lặp không được biết
trước như “while (m!=n){...}”, trong đó m và n là hai tham số kiểu nguyên truyền
vào hàm. Để giải quyết hai vấn đề này, một vài công cụ kiểm thử như PathCrawler
chèn thêm mã nguồn xác định số lần lặp tối đa của mỗi vòng lặp hoặc thêm yêu
cầu thời gian chạy. Tuy nhiên, nhìn chung số ca kiểm thử vẫn khá lớn gây khó
khăn cho quản lí.
 Về thời gian sinh ca kiểm thử. Một cách tổng quan, kiểm thử động thực thi ca kiểm
thử lặp lại nhiều lần nên thời gian sinh ca kiểm thử lâu hơn. Một điểm chung là hai
kĩ thuật đều có bước giải hệ ràng buộc để sinh ca kiểm thử mới. Thời gian giải hệ
11
chiếm tỉ lệ đáng kể trong tổng thời gian sinh ca kiểm thử. Tuy nhiên, các công cụ
có khả năng giải hệ được phát triển khá mạnh mẽ và công bố rộng rãi trong thời
gian gần đây nên sự so sánh về thời gian giải hệ có thể bỏ qua.
 Về khả năng kiểm thử vòng lặp. Kiểm thử tĩnh hướng đến chỉ kiểm thử một vòng
lặp duy nhất tại một thời điểm. Do đó, trong trường hợp có nhiều vòng lặp, chẳng
hạn như đường kiểm thử đi qua hai vòng lặp lồng nhau thì quy trình kiểm thử tiến
hành với từng vòng lặp riêng và tìm cách phá vỡ cấu trúc lặp các vòng lặp còn lại.
Ngược lại, kiểm thử động hướng đến kiểm thử tính đúng đắn của các vòng lặp một
cách đồng thời thay vì riêng rẽ. Tư tưởng này mô phỏng quá trình thực thi trong
thực tế.
 Tính phức tạp mã nguồn. Hiện nay, quy tắc viết mã nguồn rất đa dạng và các quy
tắc mới có thể được đưa ra trong các phiên bản trình biên dịch mới. Kiểm thử tĩnh
bị hạn chế bởi tính phức tạp mã nguồn. Ví dụ, trường hợp mã nguồn chứa các hàm
biến đổi xâu thì kĩ thuật kiểm thử này yêu cầu cần phải xây dựng lại các hàm đó
một cách thủ công. Ngược lại, kiểm thử động không bị ảnh hưởng lớn bởi những
sự thay đổi này và bởi tính phức tạp mã nguồn. Nguyên nhân chính do kiểm thử
động tận dụng thế mạnh trình biên dịch để sinh ca kiểm thử mới.
2.5. Tầm quan trọng của tự động hóa quy trình kiểm thử hộp trắng dòng điều khiển
Ba trong số những nguyên nhân chính dẫn đến vấn đề tự động hóa quy trình kiểm
thử hộp trắng dòng điều khiển gồm:
 Thời gian sinh ca kiểm thử bằng tay khá lâu và dễ dẫn đến sai sót. Nguyên nhân
chính phụ thuộc vào trình độ chuyên môn của kiểm thử viên, độ phức tạp mã
nguồn và chịu áp lực bởi môi trường làm việc.
 Chi phí về nguồn nhân lực cho pha kiểm thử khá tốn kém. Muốn đảm bảo chất
lượng phần mềm (đặc biệt với dự án lớn) thì chi phí nguồn nhân lực càng cao. Do
đó, vấn đề quản lí khối lượng nguồn nhân lực trở nên phức tạp và rắc rối.
 Các thống kê cho thấy chi phí pha kiểm thử có thể chiếm tới 40%-60% tổng chi
phí phát triển dự án phần mềm [2]. Các phần mềm hệ thống, phần mềm doanh
nghiệp, v.v. đều đòi hỏi chất lượng cao nên pha kiểm thử luôn được chú trọng và
không thể bỏ qua. Hơn nữa, mỗi khi phần mềm được nâng cấp thì quá trình kiểm
thử được tiến hành lại dẫn đến chi phí đã cao nay càng cao hơn.
12
Phương pháp kiểm thử tự động hàm C sử dụng kĩ thuậtChương 3.
kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh
Chương này đề xuất phương pháp kiểm thử tự động hàm C sử dụng kĩ thuật kiểm
thử kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh. Phương pháp đề xuất cách xây
dựng đồ thị dòng điều khiển CFG, sinh tập đường đi độc lập, kĩ thuật kiểm thử tính đúng
đắn với hàm đầu vào chứa vòng lặp đơn hoặc hai vòng lặp lồng nhau. Ngoài ra, kĩ thuật
SE được mô tả một cách chi tiết nêu cách xây dựng hệ ràng buộc từ một đường thi hành
bất kì. Tổng quan về SMT-Solver và kĩ thuật sinh ngẫu nhiên được trình bày để giải hệ
ràng buộc sinh ca kiểm thử.
3.1. Tổng quan phương pháp kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh
Hình 3.1. Quy trình kiểm thử một hàm C theo phương pháp đề xuất.
Khóa luận đề xuất một phương pháp kiểm thử hàm C sử dụng phương pháp kiểm
thử hộp trắng dòng điều khiển theo hướng tĩnh và cài đặt công cụ hỗ trợ. Đầu vào của bài
Sinh CFG
Sinh tập đường đi độc lập
Sinh tập đường kiểm thử
Sinh đường kiểm thử vòng lặp
Sinh hệ ràng buộc
Sinh ca kiểm thử
Thực thi ca kiểm thử
Xuất báo cáo
Hàm C
Độ phủ
SMT-Solver
Sinh ngẫu nhiên
13
toán là một tiêu chí phủ kiểm thử và một đơn vị chương trình C chứa các biến số nguyên,
số thực và biến mảng. Đầu ra là tập ca kiểm thử thỏa mãn tiêu chí phủ kiểm thử nêu trên.
Đề xuất được mô tả khái quát ở Hình 3.1. Đầu tiên, mã nguồn được phân tích để sinh
CFG tương ứng với tiêu chí phủ kiểm thử cho trước. Sau đó, chúng tôi xây dựng tập
đường đi độc lập từ CFG nêu trên. Tiếp theo, quá trình phân tích tập đường đi độc lập để
sinh tập đường kiểm thử thỏa mãn tiêu chí phủ kiểm thử được tiến hành. Ngoài ra, để
kiểm thử tính đúng đắn của vòng lặp, các đường kiểm thử mới được xây dựng bằng cách
phân tích các đường kiểm thử chứa vòng lặp. Tiếp theo, các đường kiểm thử được phân
tích sử dụng kĩ thuật SE để sinh ra hệ ràng buộc. Mỗi hệ ràng buộc được giải bằng cách
sử dụng kĩ thuật sinh ngẫu nhiên hoặc sử dụng công cụ SMT-Solver. Nếu sử dụng công
cụ SMT-Solver, các hệ ràng buộc sẽ được chuyển đổi về dạng chuẩn SMT-Lib. Sau khi
có được ca kiểm thử, quá trình thực thi ca kiểm thử được tiến hành để lấy giá trị trả về của
mã nguồn (nếu có) và đảm bảo ca kiểm thử thực thi không lỗi.
3.2. Sinh đồ thị dòng điều khiển từ mã nguồn
Hình 3.2. Thuật toán sinh CFG từ mã nguồn.
14
Chi tiết thuật toán sinh đồ thị dòng điều khiển của hàm C thỏa mãn một tiêu chuẩn
phủ kiểm thử cho trước được trình bày ở Hình 3.2. Đầu vào thuật toán gồm hàm C được
lưu trong biến f và tiêu chí phủ kiểm thử lưu trong biến t. Đầu ra thuật toán là đồ thị dòng
điều khiển lưu trong biến graph. Đầu vào cùng một hàm C, CFG ứng với tiêu chí phủ câu
lệnh và phủ nhánh giống nhau và đơn giản hơn so với tiêu chí phủ điều kiện con. Bước
đầu tiên thuật toán, tập các khối mã nguồn con cấu thành nên f được phân tách và lưu
trong biến B (dòng 1). Tiếp theo, đồ thị G được sinh ra thỏa mãn mỗi đỉnh đồ thị G lưu
một khối mã nguồn con, các cạnh mô tả thứ tự thực hiện cúa các khối mã nguồn con trong
f (dòng 2). Sau đó, đỉnh của graph lưu f được thay thế thành đồ thị G (dòng 3). Nếu đồ thị
G tồn tại các đỉnh lưu câu lệnh break, continue và return thì con trỏ mà các đỉnh này trỏ
tới đỉnh khác sẽ trỏ lại đến đúng đỉnh khác trong graph (dòng 4, 5). Cuối cùng, những
khối mã nguồn con còn khả năng phân tích tiếp ra các khối mã nguồn con khác, hàm đệ
quy được gọi (dòng 7, 8, 9).
Hình 3.3. Mã nguồn hàm average.
Một khối mã nguồn con không cần phân tích tiếp chỉ khi đã thỏa mãn tiêu chuẩn
phủ kiểm thử. Cụ thể, với tiêu chuẩn phủ câu lệnh và phủ nhánh, các đỉnh trong CFG lưu
câu lệnh đơn và điều kiện trong các khối lệnh điều khiển. Tuy nhiên, điều kiện của khối
15
lệnh điều khiển có thể do một điều kiện hoặc nhiều điều kiện đơn hợp thành. Nếu phân
tách tiếp các điều kiện khối lệnh điều khiển thành đồ thị mà các đỉnh là điều kiện đơn và
các cạnh là nhánh true/false thì sinh ra CFG thỏa mãn tiêu chuẩn phủ điều kiện con.
Ví dụ cụ thể, Hình 3.4 đưa ra đồ thị CFG tương ứng với hàm average trình bày ở
Hình 3.3 thỏa mãn tiêu chí phủ câu lệnh và phủ nhánh. Phân tích hàm average thu được
tập khối mã nguồn con gồm 4 khối : khối while, khối if, lệnh return và câu lệnh khai báo
dòng 2. Bốn khối này được liên kết với nhau theo dạng danh sách liên kết. Tiếp tục, khối
while được phân tích tiếp thu được điều kiện kép (value[i]!=-2&&tcnt<2) và khối lệnh
khi thỏa mãn điều kiện. Khối if phân tích tương tự khối while. Lệnh return, câu lệnh khai
báo và điều kiện kép không cần phân tích tiếp. Sau đó, khối lệnh trong while được phân
tích tiếp và quá trình này cứ lặp lại như thế.
Hình 3.4. CFG hàm average tiêu chuẩn phủ câu lệnh, phủ nhánh.
Ví dụ tiếp theo, trường hợp phủ điều kiện con, điều kiện kép (a>=0 || ((b>=0 &&
c>=0) || b+c>=0) || a+b+c>=0) phân tích thành đồ thị tương ứng mô tả ở Hình 3.5.
Điều kiện kép nêu trên do ba điều kiện con hợp thành là a>=0, (b>=0 && c>=0) ||
F
F
F
T
T
T
Bắt đầu hàm
min <= value[i] &&
value[i] <= max
vcnt < 0tcnt++
value[i] != -2 && tcnt < 2
int tcnt = vcnt = sum = i = 0
return -9 return sum/vcnt
sum += value[i]
vcnt++
i++
Kết thúc hàm
T
16
b+c>=0 và a+b+c>=0. Điều kiện a>=0 và a+b+c>=0 không cần phân tích tiếp vì thỏa
mãn điều kiện đơn. Trong khi đó, điều lệnh kép (b>=0 && c>=0) || b+c>=0 sẽ được
phân tích tiếp thành 2 điều kiện con: (b>=0 && c>=0) và b+c>=0. Quá trình phân tích
cứ lặp lại như thế cho đến khi mọi điều kiện con này đều là các điều kiện đơn. Cuối cùng,
đồ thị ứng với điều kiện kép cần phân tích sẽ cập nhật trong đồ thị CFG kết quả.
Hình 3.5. CFG điều kiện kép (a>=0 || ((b>=0 && c>=0) || b+c>=0) || a+b+c>=0).
3.3. Xây dựng tập đường kiểm thử từ đồ thị dòng điều khiển
3.3.1. Xây dựng tập đường đi độc lập
Hình 3.6 mô tả thuật toán sinh tập đường đi độc lập dựa trên ý tưởng sinh tập đường
đi độc lập do MC-Cabe đề xuất nêu trong [8]. Đầu vào thuật toán là CFG được lưu bởi
biến graph, đầu ra là tập đường đi độc lập P. Bước đầu tiên, quá trình tìm đường đi ngắn
nhất shortestPath được tiến hành bằng cách duyệt đồ thị graph theo nhánh false (dòng 1),
sau đó lưu shortestPath vào tập đường đi độc lập (dòng 2). Tiếp theo, các đỉnh quyết định
trên shortestPath được thêm vào tập S (dòng 3), biến visited dùng lưu các đỉnh quyết định
đã duyệt cả hai nhánh đúng-sai được khởi tạo bằng rỗng (dòng 4). Vòng lặp while lặp lại
đến khi hai nhánh đúng-sai của mọi đỉnh quyết định tồn tại trong tập đường đi độc lập
(dòng 5). Trong vòng while, một đỉnh bất kì u trong tập S được lấy ra (dòng 6) và tìm
cạnh (u,v) chưa tồn tại trong tập đường đi độc lập (dòng 7). Từ cặp cạnh này, chúng tôi
tìm đường đi ngắn nhất nextPath đi qua cặp cạnh (u,v) để thêm vào tập đường đi độc lập
(dòng 8). Tập S được cập nhật bằng cách thêm vào các đỉnh không thuộc tập visited trên
F
F
F
F
T
T
T
T
a+b+c >= 0
b+c >= 0c >= 0
b >= 0
a >= 0
Khối lệnh khi
thỏa mãn
T
17
đường đi nextPath (dòng 10) và xóa đỉnh u (dòng 11). Cuối cùng, đỉnh u được lưu vào tập
visited (dòng 12).
Hình 3.6. Thuật toán sinh tập đường đi độc lập từ CFG.
3.3.2. Xây dựng đường kiểm thử vòng lặp
Trong thực tế, đa phần các hàm C chứa vòng lặp nên tầm quan trọng của kiểm thử
tính đúng đắn vòng lặp là tất yếu. Các đường đi sinh từ CFG chỉ có thể kiểm thử vòng lặp
tối đa 1 lần nên chưa đảm bảo tính đúng đắn vòng lặp. Vì thế, khóa luận này đề xuất cách
sinh ca kiểm thử cho hàm C chứa hai loại vòng lặp: vòng lặp đơn và hai vòng lặp lồng
nhau. Tư tưởng chung của phương pháp đề xuất là viết lại đường đi chứa vòng lặp để tạo
đường đi mới lặp nhiều hơn 1 lần, sau đó sinh ca kiểm thử từ đường đi mới đó.
Ba loại đường đi trong tập đường đi độc lập được kiểm thử vòng lặp gồm:
18
 Đường đi chứa vòng lặp. Nằm trong tập đường đi độc lập có chứa vòng lặp. Câu
lệnh ứng với đỉnh quyết định đi vào vòng lặp và thoát khỏi vòng lặp đó là phủ định
của nhau.
 Đường đi chứa vòng lặp đơn. Là đường đi có đúng một vòng lặp. Đường đi này
chỉ có một đỉnh duy nhất đi vào vòng lặp và thoát khỏi vòng lặp.
 Đường đi chứa vòng lặp lồng nhau. Là đường đi có hai vòng lặp: một vòng lặp bên
trong và một vòng lặp bên ngoài. Đường đi loại này có hai đỉnh đặc biệt: một đỉnh
đi vào và thoát khỏi vòng lặp bên trong, đỉnh còn lại đi vào và thoát khỏi vòng lặp
bên ngoài.
3.3.2.1. Kiểm thử đường đi chứa vòng lặp đơn
Đường đi chứa vòng lặp đơn được viết lại để tạo đường đi mới bằng cách sao chép
vòng lặp một số lần cụ thể. Nếu vòng lặp đơn biết số lần lặp tối đa bằng n thì số lần lặp là
0, 1, 2, một số ngẫu nhiên lần, n - 1, n và n + 1 lần. Ngược lại, nếu không biết số lần lặp
tối đa của vòng lặp đơn, số lần lặp là 0, 1, 2 và một số ngẫu nhiên lần. Hình 3.7 trình bày
các bước tạo đường đi mới với đầu vào là đường đi chứa vòng lặp đơn lưu trong biến
PATH, số lần lặp lưu trong biến n; đầu ra là đường đi mới với vòng lặp đơn được lặp lại n
lần. Đầu tiên, đỉnh điều kiện của vòng lặp đơn được gán cho biến v (dòng 1). Sau đó, khối
lặp vòng lặp khoi_lap được tìm ra (dòng 2). Tiếp theo, khối lặp khoi_lap được nhân bản n
lần để tạo đường đi mới và lưu trong biến duong_di_moi (dòng 3). Cuối cùng, nội dung
khối lặp đơn trong đường đi PATH được thay thế với nội dung khoi_lap_moi (dòng 4).
Hình 3.7. Thuật toán sinh đường kiểm thử vòng lặp.
19
3.3.2.2. Kiểm thử đường đi chứa hai vòng lặp lồng nhau
Đường đi chứa hai vòng lặp lồng nhau có hai điểm quyết định để đi vào vòng lặp và
được kiểm thử qua hai bước. Đường đi mới được sinh ra trong mỗi bước. Bước 1 là bước
kiểm thử vòng lặp bên trong bằng cách phá vỡ cấu trúc vòng lặp bên ngoài. Bước 2 là
bước kiểm thử vòng lặp bên ngoài bằng cách phá vỡ cấu trúc lặp vòng lặp bên trong.
Hình 3.8. Thuật toán sinh đường kiểm thử vòng lặp trong.
Trong bước 1, quá trình sinh đường đi mới với đầu vào gồm đường đi chứa hai vòng
lặp lồng nhau lưu trong biến PATH, số lần lặp của vòng lặp bên trong lưu trong biến n
được trình bày trong Hình 3.8. Đầu ra là đường đi chứa vòng lặp trong lặp lại n lần và cấu
trúc vòng lặp ngoài bị phá vỡ. Đầu tiên, đỉnh quyết định để đi vào vòng lặp bên ngoài
được lưu trong biến u (dòng 1), đỉnh quyết định để thoát khỏi vòng lặp ngoài lưu trong
biến v (dòng 2). Sau đó, biến lặp vòng lặp bên ngoài được lưu trong biến i (dòng 3) và tạo
một đỉnh mới lưu trong biến dinh_moi lưu lại phép gán này (dòng 4). Để phá vỡ cấu trúc
lặp vòng lặp ngoài, đỉnh v sẽ được loại bỏ khỏi đường đi PATH (dòng 5) và chèn thêm
đỉnh dinh_moi ngay sau đỉnh u (dòng 6). Đường đi PATH được viết lại để tạo đường đi
mới với số lần lặp vòng lặp bên trong bằng n lần (dòng 7).
20
Bước 2 mô tả trong Hình 3.9. Đầu vào thuật toán là đường đi cần viết lại lưu trong
biến PATH và số lần lặp vòng lặp ngoài lưu trong biến n, đầu ra là đường đi mới. Bước
đầu tiên, tìm đỉnh quyết định u thoát khỏi vòng lặp bên trong (dòng 1). Tiếp theo, loại bỏ
đỉnh u khỏi đường đi để phá vỡ cấu trúc lặp vòng lặp trong (dòng 2). Sau bước này,
đường đi chỉ còn duy nhất vòng lặp ngoài. Cuối cùng, vòng lặp ngoài được nhân bản lên n
lần để tạo ra đường đi mới (dòng 3).
Hình 3.9. Thuật toán sinh đường kiểm thử vòng lặp ngoài.
3.4. Sinh tập dữ liệu kiểm thử từ tập đường kiểm thử
3.4.1. Xây dựng hệ ràng buộc
Hệ ràng buộc được sinh ra bằng cách phân tích đường đi sử dụng kĩ thuật SE [9].
Trong kĩ thuật SE, giá trị của biến là các giá trị tượng trưng mà không phải giá trị cụ thể,
có thể là số nguyên, số thực hoặc biểu thức. Đầu vào của bước xây dựng hệ ràng buộc là
một đường kiểm thử, đầu ra là một hệ ràng buộc. Tất cả các nghiệm thỏa mãn hệ ràng
buộc này đều đảm bảo đường đi này sẽ được thực thi khi chạy trong môi trường chạy.
Biến trong hệ ràng buộc là biến truyền vào hàm, một vài trường hợp phức tạp có thêm
biến mảng. Số câu lệnh điều kiện trên đường đi bằng số biểu thức lôgic trong hệ ràng
buộc tương ứng. Một đường đi gọi là thực thi được nếu hệ ràng buộc tương ứng có
nghiệm và ngược lại. Hình 3.10 mô tả một hệ ràng buộc sinh từ một đường kiểm thử nào
đó.
21
{
Hình 3.10. Ví dụ một hệ ràng buộc.
Hình 3.11. Thuật toán sinh hệ ràng buộc từ đường kiểm thử.
Hình 3.11 trình bày cách sinh hệ ràng buộc từ đường đi. Đầu vào thuật toán là một
đường đi từ đỉnh đầu tiên đến đỉnh cuối cùng của CFG, đầu ra là hệ ràng buộc tương ứng.
Đầu tiên, tập các đỉnh trên đường đi được lưu trong biến V (dòng 1). Sau đó, bảng lưu
thông tin các biến bang_bien và tập lưu hệ ràng buộc he_rang_buoc được khởi tạo (dòng
2, 3). Trong vòng for, câu lệnh được rút gọn bằng cách thay thế biến với giá trị của biến
đó (dòng 5). Tiếp theo, nếu v là câu lệnh khởi tạo, biến mới được sinh ra và gán giá trị
mặc định là chữ cái viết hoa tên biến đó nếu biến đó không được tạo giá trị khởi đầu
22
(dòng 6). Nếu v là câu lệnh gán, giá trị biến được cập nhật trong bang_bien (dòng 12).
Nếu v là câu lệnh điều kiện thì lưu lại vào hệ ràng buộc (dòng 15). Thuật toán kết thúc khi
mọi đỉnh trên đường đi đều được phân tích.
Hình 3.12 trình bày chi tiết các bước trong pha rút gọn. Đầu tiên, các biến thường
trong câu lệnh được thay thế với giá trị biến đó. Bước tiếp theo, các chỉ số mảng dạng
biểu thức được tính toán thành các giá trị cụ thể. Sau đó, các biến mảng được thay thế với
giá trị cụ thể. Quá trình rút gọn này lặp lại với một số lần cho trước.
Hình 3.12. Quá trình rút gọn câu lệnh.
3.4.2. Tìm nghiệm thỏa mãn hệ ràng buộc
Cho tới nay, vấn đề tìm nghiệm thỏa mãn hệ ràng buộc một cách hiệu quả là một bài
toán khó và thách thức. Yêu cầu giải hệ tìm nghiệm trong thời gian nhanh nhất có thể
ngày càng gia tăng trong các bài toán khoa học kĩ thuật. Với các công cụ sinh ca kiểm thử
tự động, nhu cầu giải hệ trong thời gian thực là tất yếu và là một vấn đề mang tính cấp
bách. Vì vậy, khóa luận này trình bày hai cách tiếp cận để tìm nghiệm thỏa mãn hệ ràng
buộc gồm: tận dụng sức mạnh các công cụ SMT-Solver hiện nay như raSAT, Alt-Ergo,
Boolector, SmtInterpol, v.v. và kĩ thuật sinh ngẫu nhiên.
3.4.2.1. Giải hệ sử dụng kĩ thuật sinh ngẫu nhiên
Kĩ thuật sinh ngẫu nhiên là một kĩ thuật truyền thống để giải hệ ràng buộc. Trong kĩ
thuật này, tập giá trị các biến sẽ được sinh ngẫu nhiên trong một khoảng cho trước, trong
một khoảng thời gian cho trước, với một số lần sinh xác định. Với những hệ ràng buộc có
tính chất đặc biệt như nhiều biểu thức logic, biểu thức logic đặc biệt (ví dụ a==2) hay bản
thân mỗi biểu thức logic phức tạp thì kĩ thuật sinh ngẫu nhiên dễ dàng thể hiện điểm yếu
về thời gian.
Thay thế
biến thường
Rút gọn chỉ
số mảng
Thay thế
biến mảng
Lặp N lần cho trước
OutputInput
23
3.4.2.2. Giải hệ sử dụng SMT-Solver
Trong toán học mệnh đề, một câu của logic vị từ là một biểu thức luận lý theo dạng
chuẩn mà không có biến tự do xuất hiện trong biểu thức đó. Biến tự do là một kí hiệu xác
định những vị trí cụ thể trong một biểu thức mà tại vị trí đó, xảy ra sự thay thế biến với
một giá trị nào đó. Biến tự do không có giá trị cụ thể và cận cụ thể. Nếu một biến tự do
mang giá trị nằm trong một cận xác định, thì nó được gọi là biến biên. Ví dụ cụ thể, trong
biểu thức ∑ , biến tự do là n, biến biên là k vì k có cận [1, 10].
Lí do chính khiến câu không mang biến tự do là do câu cần một giá trị cụ thể, thay
vì giá trị không xác định. Cụ thể, giá trị của câu có thể là đúng hoặc sai. Tập các câu hợp
chính là một lý thuyết, khi đó bản thân mỗi câu nếu đứng độc lập chính là định lý. Để
đánh giá tính đúng-sai của một câu, câu được tham chiếu đến một thể hiện của lý thuyết
(interpretation of the theory). Với lý thuyết logic vị từ, các thể hiện thường được gọi là
các cấu trúc. Một lý thuyết được coi là thỏa mãn khi tất cả mọi câu tạo nên lý thuyết đó
đều đúng. Việc nghiên cứu các thuật toán để tìm ra các thể hiện của lý thuyết một cách tự
động sao cho mọi câu trong lý thuyết đều mang giá trị đúng được gọi là vấn đề SMT.
Trong khoa học máy tính và toán học mệnh đề, vấn đề SMT (lý thuyết modul thỏa
mãn) là một vấn đề NP (nondeterministic polynomial time) với các biểu thức logic được
tạo thành từ sự kết hợp các nền tảng lý thuyết cơ bản. Ví dụ cụ thể, các lý thuyết điển hình
sử dụng trong khoa học máy tính gồm lý thuyết về số nguyên, số thực; lý thuyết về các
kiểu dữ liệu có cấu trúc như list, array, bit vectors (hay bit array), v.v. Vấn đề SMT có thể
được coi là một dạng của vấn đề thỏa mãn ràng buộc (constraint satisfaction problem).
Chú ý thêm rằng, vấn đề SMT là mở rộng của vấn đề SAT (Boolean satisfiability
problem). Vấn đề SAT là làm sao xác định được một thể hiện (hay nghiệm) sao cho thỏa
mãn biểu thức luận lý đã cho. Trong vấn đề SAT, giá trị một biến chỉ có thể là true hoặc
false. Ví dụ, biểu thức luận lý a and not b có một thể hiện thỏa mãn là a = true, b = false
vì thỏa mãn a and not b = true. Vấn đề SAT là một trong những vấn đề đầu tiên được
chứng minh là vấn đề NP.
Để giải vấn đề SMT, hay nói cụ thể hơn là giải các biểu thức logic, các công cụ giải
SMT-Solver được ra đời. Hình 3.13 mô tả đầu vào, đầu ra của các công cụ SMT-Solver.
Đầu vào là hệ cần tìm nghiệm thỏa mãn được viết theo dạng chuẩn đầu vào của công cụ
24
đó. Đầu ra là nghiệm thỏa mãn trong trường hợp SAT hoặc vô nghiệm trong trường hợp
UNSAT.
Hình 3.13. Mô tả đầu vào, đầu ra SMT-Solver.
Hiện nay, nhiều công cụ SMT-Solver không những giải được lý thuyết tuyến tính
mà còn giải được lý thuyết phi tuyến tính. Ví dụ, tìm nghiệm của
với x , y R. Đa phần các công cụ SMT-Solver hiện nay đều đưa SAT-Solver
vào bộ giải của mình. Cụ thể, trong pha tiền xử lí, biểu thức đầu vào cho công cụ SMT-
Solver được chuyển về dạng biểu thức luận lý tương đương mà có thể giải được bằng các
công cụ SAT-Solver. Mặt khác, vì pha tiền xử lí này có một hạn chế là làm mất tầng ngữ
nghĩa mức cao mà biểu thức gốc chứa, nên SAT-Solver sẽ phải làm việc tốn kém hơn
trong trường hợp biểu thức gốc chứa những sự thật hiển nhiên. Ví dụ, biểu thức x+y =
y+x với x, y Z. Cho đến nay, hạn chế nêu trên được giải quyết trong T-Solver.
Ba chuẩn đầu vào các công cụ SMT-Solver phổ biến gồm SMT-Lib, CVC6
và
DIMACS7
. Trong đó, chuẩn SMT-Lib là chuẩn sử dụng rộng rãi nhất. Hình 3.14 trình bày
một hệ ràng buộc tuân theo chuẩn SMT-Lib. Cụ thể, theo sau từ khóa set-logic là ký hiệu
lý thuyết cơ bản sẽ sử dụng trong SMT-Solver. Bốn lý thuyết cơ bản sử dụng gồm:
 QF_LRA : toán học số thực tuyến tính định lượng tự do (quantifier-free linear real
arithmetic)
 QF_LIA : toán học số nguyên tuyến tính định lượng tự do (quantifier-free linear
integer arithmetic
 QF_RDL : lôgic hiệu số số thực định lượng tự do (quantifier-free real difference
logic)
 QF_IDL : lôgic hiệu số số nguyên định lượng tự do (quantifier-free integer
difference logic)
6
http://cvc4.cs.nyu.edu/
7
http://www.satcompetition.org/2009/format-benchmarks2009.html
25
Trong đó, khóa luận đề xuất sử dụng hai lý thuyết QF_LRA và QF_LIA để giải hệ
ràng buộc số nguyên và số thực. Các biến được khai báo với từ khóa declare-fun và theo
sau là kiểu biến (Int hoặc Real). Theo sau assert(! chính là các biểu thức trong hệ ràng
buộc đã được biến đổi về chuẩn biểu thức trong SMT-Lib. Ví dụ Hình 3.14 nêu đầu vào
chuẩn SMT-Lib tương ứng với ví dụ nêu ở Hình 3.10. Trong đó biểu thức not(= a 0)
tương ứng với biểu thức !(a == 0), biểu thức or (= (- b 2 ) b ) (and (= c d ) (= (- b 2 ) 0)
tương ứng với biểu thức (b-2==b) or (c==d and b-2==0). Tên của mỗi biểu thức được
đặt ngay sau biểu thức với từ khóa named (IP0, IP1, v.v). Quá trình giải hệ bắt đầu với từ
khóa check-sat. Từ khóa print-success được gán giá trị false ám chỉ thông báo thành công
sẽ không được hiển thị sau khi lệnh hoàn thành.
Hình 3.14. Ví dụ hệ ràng buộc tuân theo chuẩn SMT-Lib.
Để tìm nghiệm thỏa mãn hệ ràng buộc bằng cách sử dụng SMT-Solver, bước đầu
tiên cần biến đổi hệ ràng buộc này về chuẩn SMT-Lib. Quy trình biến đổi hệ ràng buộc về
chuẩn SMT-Lib trình bày ở Hình 3.15. Đầu tiên, biểu thức lôgic trong hệ ràng buộc được
chuyển thành biểu thức hậu tố. Sau đó, cây biểu thức tương ứng với biểu thức hậu tố được
xây dựng. Cuối cùng, cây biểu thức được duyệt sử dụng các thuật toán kinh điển trong lý
thuyết đồ thị để sinh ra biểu thức thỏa mãn chuẩn SMT-Lib.
Hình 3.15. Quá trình chuyển một biểu thức trung tố về chuẩn SMT-Lib.
Biểu thức
lôgic
Biểu thức
hậu tố
Cây biểu
thức
Biểu thức
chuẩn
SMT-Lib
26
Thuật toán 7 trình bày quá trình chuyển biểu thức trung tố về biểu thức hậu tố. Biểu
thức trung tố chỉ chứa biến, số và các toán tử mà không chứa các hàm toán học. Kĩ thuật
biến đổi biểu thức trung tố về biểu thức hậu tố không còn xa lạ với những biểu thức tính
toán chỉ gồm các phép toán cộng - trừ - nhân - chia, tuy nhiên trong thực tế biểu thức
phức tạp hơn nhiều bởi chứa thêm phép so sánh, phép phủ định, phép tuyển và phép hội.
Vì thế, khóa luận xây dựng lại bảng độ ưu tiên các toán tử để giải quyết vấn đề này. Cụ
thể, Bảng 1 đề xuất độ ưu tiên các toán tử, trong đó độ ưu tiên nhỏ nhất bằng (-2) và độ
ưu tiên lớn nhất bằng 3.
Bảng 1. Độ ưu tiên các toán tử
Toán tử Độ ưu tiên
Mở ngoặc, đóng ngoặc -2 (nhỏ nhất)
Phép tuyển, phép hội -1
Phép so sánh 0
Cộng, trừ 1
Nhân, chia, lấy phần dư 2
Phép phủ định 3
Trong thuật toán 7 ở Hình 3.16, hàm pop trả về phần tử đầu tiên trên đỉnh stack, hàm
push đẩy phần tử mới vào stack và hàm peek tương tự hàm pop nhưng kích thước stack
không thay đổi. Hàm do_uu_tien trả về độ ưu tiên toán tử. Đầu tiên, biến stack và
tập_toán_tử được khởi tạo (dòng 1, 2). Trong vòng for, nếu phần tử item xuất hiện trong
tập_toán_tử thì các phần tử trong stack được xuất ra cho đến khi phần tử trên đỉnh stack
có độ ưu tiên thấp hơn item hoặc stack bằng rỗng (dòng 5, 6). Nếu phần tử item là phép
mở ngoặc, item được lưu vào stack (dòng 9). Nếu phần tử item là kí tự đóng ngoặc, các
phần tử trong stack xuất ra cho đến khi gặp kí tự mở ngoặc (dòng 11), sau đó loại bỏ kí tự
mở ngoặc khỏi stack (dòng 15). Ngược lại, nếu item là biến hoặc số thì bieu_thuc_hau_to
được cập nhật ngay lập tức (dòng 17). Cuối cùng, bieu_thuc_hau_to được chuẩn hóa bằng
cách thay thế các phần tử trong biểu thức với cách thể hiện tương ứng theo chuẩn SMT-
Lib (dòng 20). Cụ thể, theo chuẩn SMT-Lib cách thể hiện biến mảng theo ngôn ngữ lập
trình C không cho phép nên được viết lại đơn giản hơn. Ví dụ, biến mảng a[1] thay thế
27
thành a_1_, phép phủ định thay thế thành “not”, phép lấy dư (%) thay thế thành “mod”,
phép hội thay thế thành “and”, v.v.
Hình 3.16. Thuật toán xây dựng biểu thức hậu tố.
Thuật toán 8 ở Hình 3.17 trình bày quy trình chuyển biểu thức hậu tố về cây biểu
thức. Mỗi một đỉnh NodeTree của cây biểu thức gồm có con trái, con phải và lưu trữ một
phần tử của biểu thức hậu tố. Đầu tiên, biến Stack và tap_toan_tu được khởi tạo (dòng 1,
2). Nếu item xuất hiện trong tap_toan_tu, hai phần tử trên đỉnh Stack được lấy làm con
trái và con phải của đỉnh parent, trong đó đỉnh parent là NodeTree lưu item. Biến parent
28
được lưu vào Stack và sẽ là con trái hoặc con phải của một đỉnh nào đó trong các lần
duyệt tiếp theo (dòng 4 - 8). Ngược lại, nếu item không xuất hiện trong tap_toan_tu thì
một NodeTree mới được tạo ra và lưu vào Stack (dòng 10, 11). Thuật toán kết thúc khi
mọi phần tử trong biểu thức hậu tố đều được duyệt.
Hình 3.17. Thuật toán xây dựng cây biểu thức từ biểu thức hậu tố.
Thuật toán 9 ở Hình 3.18 trình bày thứ tự duyệt cây biểu thức để sinh ra biểu thức
thỏa mãn chuấn SMT-Lib. Đầu vào là gốc cây biểu thức, đầu ra là biểu thức chuẩn SMT -
Lib được lưu ở biến toàn cục Bieu_thuc_chuan_smt_lib. Nút cha luôn được duyệt trước,
sau đó duyệt đến con trái và con phải. Nếu nội dung node xuất hiện trong tap_toan_tu
(dòng 3), nội dung node được thêm vào cuối xâu Bieu_thuc_chuan_smt_lib (dòng 4), sau
đó mới duyệt con trái và con phải (dòng 5, 6). Nếu node là nút lá, nội dung node được
thêm vào cuối xâu Bieu_thuc_chuan_smt_lib (dòng 8). Tiếp theo, nếu node là con phải
của một đỉnh NodeTree nào đó thì dấu ngoặc thêm vào cuối xâu
Bieu_thuc_chuan_smt_lib (dòng 8). Thuật toán kết thúc khi cây duyệt xong toàn bộ.
29
Hình 3.18. Thuật toán duyệt cây biểu thức.
Ví dụ cụ thể, xét biểu thức trung tố “!(1*x>=y[2])||x>(-3)||!(1>a &&a>b[1][1])”.
Đầu tiên, sử dụng thuật toán 7 để chuyển biểu thức trung tố nêu trên thành biểu thức hậu
tố. Đầu ra của thuật toán 7 là biểu thức hậu tố “1 x * y_2_ >= not x (-3) > or 1 a > a
b_1__1_ > and not or”, trong đó b_1__1_ đại diện cho biến mảng b[1][1]. Bước tiếp
theo, sử dụng thuật toán 8 phân tích biểu thức hậu tố nêu trên để tạo cây biểu thức. Cuối
cùng, phân tích cây biểu thức sử dụng thuật toán 9 thu được biểu thức chuẩn SMT-Lib là
“(or (or (not (>= (* 1 x ) y_2_ ) ) (> x (- 3) ) ) (not (and (> 1 a ) (> a b_1__1_ ) ) ) )”.
3.4.2.3. So sánh ưu điểm, nhược điểm của hai hướng sinh ca kiểm thử
Trong thực tế, mỗi một công cụ SMT-Solver chỉ chấp nhận hệ ràng buộc thỏa mãn
một vài tiêu chí nhất định. Hơn nữa, mỗi một công cụ SMT-Solver chỉ tương thích với
một vài môi trường. Ngoài ra, hầu hết SMT-Solver đều có giao diện với một hoặc một vài
ngôn ngữ lập trình. Ví dụ, ABsolver8
chỉ chạy trên Linux hỗ trợ giải hệ tuyến tính và phi
8
http://absolver.sourceforge.net/
30
tuyến tính; MiniSmt9
chạy trên cả Linux hỗ trợ giải hệ phi tuyến tính; SmtInterpol chạy
trên Linux, Window và Mac giải hệ số nguyên tuyến tính, số thực tuyến tính và biểu
tượng hàm (function symbol hoặc uninterpreted function), v.v.
Ngược lại, giải hệ bằng kĩ thuật sinh ngẫu nhiên tuy mang tính may rủi nhưng có thể
giải được hệ ràng buộc theo nhiều dạng khác nhau. Các biểu thức trong hệ ràng buộc có
thể là biểu thức logic đơn giản đến phức tạp, có các hàm toán học như sin, cos, sqrt, v.v.
Ưu điểm SMT-Solver là giải hệ ràng buộc rất nhanh và hiệu quả nhưng chỉ áp dụng được
với một số loại hệ. Rõ ràng, những hệ có thể giải bằng SMT-Solver thì không nên giải
bằng kĩ thuật sinh ngẫu nhiên. Những hệ không thể giải bằng SMT-Solver thì dùng kĩ
thuật sinh ngẫu nhiên thay thế. Hai kĩ thuật được kết hợp với nhau với mục đích lấy ưu
điểm kĩ thuật này bù nhược điểm kĩ thuật kia và ngược lại.
9
http://cl-informatik.uibk.ac.at/software/minismt/
31
Thực nghiệmChương 4.
4.1. Các thư viện hỗ trợ
4.1.1. Giới thiệu về thư viện SMT-Solver SmtInterpol
Thư viện SmtInterpol [12] được viết bằng ngôn ngữ Java. Thư viện này chấp nhận
đầu vào thỏa mãn chuẩn SMT-Lib và giải hệ ràng buộc số nguyên tuyến tính, số thực
tuyến tính, hàm tượng trưng (function symbol hay uninterpreted function). Hai cách sử
dụng SmtInterpol gồm sử dụng API và qua môi trường dòng lệnh cmd. Giao diện gọi thư
viện SmtInterpol qua dòng lệnh như sau, trong đó hệ ràng buộc được lưu trong tệp
contraintEquations.smt2 đặt tại ổ C.
String cmd = "java -jar C:/smtinterpol.jar C:/contraintEquations.smt2";
Process p = Runtime.getRuntime().exec(cmd);
4.1.2. Giới thiệu về thư viện CDT
CDT10
là một bộ phân tích cấu trúc xử lý mã nguồn ngôn ngữ C/C++ để lấy cây
AST. Cây AST là một cách biểu diễn cấu trúc mã nguồn dưới dạng một tập các đỉnh và
liên kết giữa các đỉnh. Mỗi một đỉnh tương ứng với một thành phần trong mã nguồn như
câu lệnh gán, khối lệnh điều kiện, biến, phép toán, v.v. Ví dụ, đỉnh IASTDeclSpecifier
tương ứng với kiểu trả về của hàm hay kiểu biến. Đỉnh IASTBinaryExpression tương ứng
với dấu phép toán. Đỉnh IASTName đại diện tên biến, tên hàm. IASTReturnStatement
chính là câu lệnh return. Hình 4.1 minh họa cây AST tương ứng với câu lệnh return x*3.
Tùy vào yêu cầu phân tích mà độ sâu cây AST là khác nhau. Ở cấp độ xây dựng
CFG từ mã nguồn thì cần phân tích đến khi mỗi một đỉnh trong AST tương ứng với câu
lệnh gán/khởi tạo/điều kiện là đủ, thay vì phân tích sâu hơn đến mức biến/toán tử/tên
hàm/... Trong thử nghiệm nêu ra ở [4], thời gian xây dựng cây AST từ mã nguồn có độ
dài 25 000 dòng trên máy tính chạy Java 32 bit là 0.40 giây. CDT được coi là một trong
những bộ phân tích cấu trúc mã nguồn C hiệu quả nhất và được sử dụng rộng rãi.
10
http://eclipse.org/cdt/
32
Hình 4.1. Minh họa cây AST ứng với mã nguồn return x*3 .
4.1.3. Giới thiệu về thư viện Jeval
Jeval11
là một thư viện mã nguồn mở mạnh mẽ dùng tính toán giá trị biểu thức. Đầu
vào của Jeval là một biểu thức logic và tập giá trị các biến trong biểu thức đó. Đầu ra là
giá trị luận lý đúng/sai. Các hàm toán học với số nguyên và số thực, hàm kiểu xâu và biểu
thức luận lý được tối ưu hóa với hiệu suất cao. Ngoài ra, Jeval hỗ trợ gần như đầy đủ các
phép toán sử dụng trong lập trình C gồm phép so sánh, phép phủ định, phép tuyển, phép
hội, phép lấy phần dư và các phép toán học cơ bản. Như vậy, sử dụng thư viện Jeval là
một giải pháp hiệu quả đối với kĩ thuật sinh ngẫu nhiên để giải hệ ràng buộc.
4.2. Giới thiệu công cụ kiểm thử tự động hàm C
4.2.1. Tổng quan về công cụ CFT4CUnit
CFT4CUnit được xây dựng theo phương pháp đề xuất nêu trong chương 3. Công cụ
sử dụng thư viện SmtInterpol kết hợp với kĩ thuật sinh ngẫu nhiên để giải hệ ràng buộc
sinh ca kiểm thử. Với kĩ thuật sinh ngẫu nhiên, người dùng cần xác định cận lặp [a,b] và
số lần sinh ngẫu nhiên. Công cụ cung cấp khả năng xuất kết quả kiểm thử ra tệp excel.
Công cụ được xây dựng bằng ngôn ngữ Java sử dụng các thư viện hỗ trợ gồm CDT giúp
phân tích hàm C xây dựng CFG, Jeval giúp tính toán giá trị biểu thức. Công cụ
CFT4CUnit, tài liệu hướng dẫn sử dụng và tập ví dụ thử nghiệm được cung cấp ở địa chỉ
11
http://jeval.sourceforge.net/
IASTReturnStatement
IASTBinaryExpression: *
IASTLiteralExpression: 3IASTIdExpression
IASTName: x
33
http://uet.vnu.edu.vn/~hungpn/CFT4CUnit/. Hình 4.2 mô tả giao diện tổng quan của công
cụ CFT4CUnit.
Hình 4.2. Giao diện công cụ CFT4CUnit.
4.2.1. Đầu vào công cụ
Đầu vào công cụ CFT4CUnit là một hàm C chứa các biến số nguyên (kiểu int), số
thực (kiểu double, float) và biến mảng một chiều hoặc hai chiều. Chỉ số biến mảng có thể
là số nguyên hoặc biểu thức. Các khối lệnh điều khiển được xử lí bao gồm rẽ nhánh, for,
while...do, do...while, switch...case. Hình 4.3 là một ví dụ đầu vào công cụ.
Hình 4.3. Ví dụ đầu vào công cụ CFT4CUnit.
34
4.2.2. Đầu ra công cụ
4.2.2.1. Đồ thị dòng điều khiển
Công cụ CFT4CUnit sẽ phân tích hàm đầu vào để sinh ra đồ thị dòng điều khiển
thỏa mãn tiêu chí phủ câu lệnh, phủ nhánh và phủ điều kiện con. Người sử dụng nhấn một
đường kiểm thử bất kì thì đường đi tương ứng trên CFG chuyển sang màu đỏ, ngoài ra
thứ tự thực hiện từng câu lệnh được hiển thị. Hơn nữa, người dùng có thể tương tác với
các đỉnh trong CFG để di chuyển sang vị trí mới.
Thẻ Đồ thị CFG phủ câu lệnh/nhánh hiển thị CFG thỏa mãn tiêu chí phủ câu lệnh và
phủ nhánh. Thẻ Đồ thị CFG phủ điều kiện con hiển thị CFG ứng với tiêu chí phủ điều
kiện con. Hình 4.4 mô tả đồ thị CFG của hàm foo nêu ở Hình 4.3 thỏa mãn tiêu chí phủ
câu lệnh và phủ nhánh. Hình 4.5 hiển thị đồ thị CFG hàm foo ứng với tiêu chí phủ điều
kiện con. Đỉnh đầu tiên mang nhãn Bat dau ham, đỉnh kết thúc mang nhãn Ket thuc ham.
Đường màu xanh lam ứng với nhánh đúng, đường màu xanh lá cây ứng với nhánh sai.
Hình 4.4. Đồ thị CFG thỏa mãn tiêu chí
phủ câu lệnh và phủ nhánh.
Hình 4.5. Đồ thị CFG thỏa mãn tiêu chí phủ
điều kiện con.
35
Hình 4.6. Đường đi tương ứng trên CFG chuyển sang màu đỏ khi người
dùng nhấn vào một đường kiểm thử bất kì.
4.2.2.2. Tập đường kiểm thử
Các đường kiểm thử tương ứng với từng độ phủ được sinh tự động và hiển thị ở các
thẻ Phủ câu lệnh, Phủ nhánh và Phủ điều kiện con. Cụ thể, thẻ Phủ câu lệnh hiển thị tập
đường kiểm thử thỏa mãn tiêu chí phủ câu lệnh. Thẻ Phủ nhánh hiện danh sách tập đường
kiểm thử thỏa mãn tiêu chí phủ nhánh. Thẻ Phủ điều kiện con đưa ra tập đường kiểm thử
thỏa mãn tiêu chí phủ điều kiện con. Ngoài ra, tập đường đi độc lập tương ứng với độ phủ
câu lệnh và phủ nhánh hiển thị ở thẻ Tập đường đi độc lập.
Hình 4.7. Tập đường kiểm thử thỏa mãn phủ câu lệnh hàm foo.
Hình 4.8. Tập đường kiểm thử thỏa mãn phủ nhánh hàm foo.
36
Hình 4.9. Tập đường kiểm thử thỏa mãn phủ điều kiện con hàm foo.
Hình 4.10. Tập đường đi độc lập để sinh tập đường kiểm thử phủ nhánh
và phủ câu lệnh hàm foo.
4.2.2.3. Tập ca kiểm thử
Người dùng nhấn vào nút Tìm ca kiểm thử để sinh ca kiểm thử trong thời gian thực.
Tùy vào loại hệ ràng buộc cần giải mà công cụ sử dụng kĩ thuật sinh ngẫu nhiên hay tận
dụng thế mạnh SMT-Solver. Thông tin về quá trình SE được hiển thị chi tiết ở thẻ Quá
trình SE. Ví dụ minh họa ở Hình 4.11.
Hình 4.11. Ca kiểm thử thỏa mãn đường đi màu đỏ sinh theo kĩ thuật
ngẫu nhiên và dùng SMT-Solver.
37
4.2.2.4. Biểu thức chuẩn SMT-Lib
Khi người dùng nhấn vào một đường kiểm thử, hệ ràng buộc thỏa mãn chuẩn SMT-
Lib được sinh tự động và hiển thị ở thẻ Hệ ràng buộc chuẩn SMT-Lib. Trong quá trình
chạy, chương trình sẽ tự động lưu hệ dạng chuẩn SMT-Lib vào ổ C để làm đầu vào thư
viện SmtInterpol. Người dùng có thể cài đặt lại đường dẫn thư viện SmtInterpol theo ý
mình. Hình 4.12 trình bày hệ ràng buộc chuẩn SMT-Lib ứng với đường đi màu đỏ ở thẻ
Đồ thị CFG phủ câu lệnh/nhánh. Đường đi màu đỏ này là một trong hai đường kiểm thử
thỏa mãn tiêu chí phủ câu lệnh.
Hình 4.12. Hệ ràng buộc chuẩn SMT-Lib tương ứng với đường kiểm thử màu đỏ.
4.2.2.5. Kiểm thử vòng lặp đơn
Để kiểm thử vòng lặp đơn, bước đầu tiên người dùng cần xác định biến lặp vòng lặp
này. Sau đó, người dùng nhấn nút Tìm ca kiểm thử để sinh tập ca kiểm thử đánh giá tính
đúng đắn vòng lặp. Tập các ca kiểm thử này hiển thị ở thẻ Kiểm thử vòng lặp đơn gồm
các thông tin: số lần lặp, đường kiểm thử tương ứng số lần lặp, hệ ràng buộc, ca kiểm thử,
giá trị trả về và thông tin quá trình giải hệ (sử dụng SMT-Solver hay sinh ngẫu nhiên).
Hình 4.13 nêu ví dụ kiểm thử vòng lặp đơn hàm tinh_tong. Vòng lặp đơn vì không
xác định số lần lặp tối đa nên vòng lặp được lặp lại 0 lần, 1 lần, 2 lần, một số ngẫu nhiên
(9 lần).
38
Hình 4.13. Kiểm thử vòng lặp đơn hàm tinh_tong.
4.2.2.6. Kiểm thử vòng lặp lồng nhau
Để kiểm thử đường kiểm thử chứa hai vòng lặp lồng nhau, đầu tiên người dùng cần
xác định biến lặp vòng lặp trong và vòng lặp ngoài. Sau đó, người dùng nhấn nút Tìm ca
kiểm thử để sinh các ca kiểm thử đánh giá tính đúng đắn vòng lặp. Thẻ Kiểm thử vòng lặp
trong hiển thị tập ca kiểm thử kiểm tra vòng lặp trong. Thẻ Kiểm thử vòng lặp ngoài hiển
thị tập ca kiểm thử kiểm tra vòng lặp bên ngoài.
Hình 4.14. Kiểm thử một đường kiểm thử chứa hai vòng lặp lồng nhau
trong hàm SelectionSort.
39
4.2.3. Thực nghiệm
Để chỉ ra tính hiệu quả của phương pháp đề xuất, phần thực nghiệm đưa ra sự so
sánh về khả năng sinh ca kiểm thử giữa ba công cụ: công cụ theo phương pháp đề xuất
CFT4CUnit, công cụ đề xuất trong [5] và công cụ PathCrawler. Đầu vào ba công cụ là
một hàm C với các biến số nguyên, số thực và biến mảng. Đầu ra ba công cụ là tập ca
kiểm thử. Tập ví dụ thực nghiệm chia thành ba loại: tập ví dụ có câu lệnh điều kiện đơn
giản, tập ví dụ có câu lệnh điều kiện phức tạp, tập ví dụ chứa vòng lặp, tập ví dụ có chỉ số
biến mảng phức tạp. Các tập ví dụ được thực hiện trong máy hệ điều hành Window 7 32
bit, Intel(R) Core™ i5-2410M CPU @ 2.30GHz với 6GB Ram.
Bảng 2 đưa ra sự so sánh giữa ba công cụ CFT4CUnit, công cụ đề xuất trong [5] và
PathCrawler. Công cụ CFT4CUnit có độ phủ điều kiện con, công cụ đề xuất trong [5] và
PathCrawler có độ phủ nhánh. Tiêu chí đánh giá là số lỗi phát hiện được trong hàm C.
Trong ví dụ foo, PathCrawler gặp phải lỗi interrupted vì không thể sinh thành công
ca kiểm thử đầu tiên. Ngược lại, kĩ thuật kiểm thử luồng điều khiển hướng tĩnh bộc lộ ưu
điểm khi sinh tập ca kiểm thử thành công và phát hiện được lỗi. Công cụ đề xuất trong [5]
phát hiện ít lỗi tiềm ẩn hơn so với CFT4CUnit do không sinh tập ca kiểm thử phủ điều
kiện con.
Với ví dụ UCLN, PathCrawler gặp phải lỗi interrupted vì ca kiểm thử đầu tiên dễ
sinh ra hệ ràng buộc dài. Các hệ ràng buộc mới được xây dựng bằng cách phủ định hệ
ràng buộc nêu trên khá phức tạp. Do đó, quá trình tìm ca kiểm thử kế tiếp từ các hệ ràng
buộc mới trở nên khó khăn và mất thời gian. Kết quả, trong một khoảng thời gian giới hạn
từ trước, PathCrawler không hoàn thành quá trình sinh ca kiểm thử. Ngược lại,
CFT4CUnit và công cụ trong [5] đều sinh thành công 6 ca kiểm thử.
Trong ví dụ Grade, PathCrawler sinh tới 12 ca kiểm thử trong khi hai công cụ còn
lại sinh số ca kiểm thử ít hơn nhiều mà cùng phát hiện 1 lỗi.
Xét ví dụ Average, CFT4CUnit phát hiện được 2 lỗi trong khi công cụ đề xuất trong
[5] chỉ phát hiện được một lỗi. Ví dụ Average cho thấy khả năng phát hiện lỗi tốt hơn khi
sinh tập ca kiểm thử thỏa mãn tiêu chí phủ điều kiện con thay vì phủ nhánh. Trong khi đó,
PathCrawler sinh tới 21 ca kiểm thử nhưng không phát hiện được lỗi nào.
40
Cuối cùng, với ví dụ ComplexIndex chứa chỉ số biến mảng dạng biểu thức,
PathCrawler và công cụ đề xuất trong [5] không giải quyết được vấn đề này. Ngược lại, vì
CFT4CUnit có quá trình rút gọn chỉ số mảng dạng biểu thức nên phát hiện được một lỗi.
Bảng 2. So sánh CFT4CUnit, công cụ đề xuất trong [5] và PathCrawler
Hàm C
CFT4CUnit
Công cụ đề xuất
trong [5]
PathCrawler
Số lỗi
Số đường
kiểm thử
Số lỗi
Số đường
kiểm thử
Số lỗi
Số đường
kiểm thử
Foo 2 5 1 3 - -
UCLN 0 6 0 6 - -
Grade 1 6 1 6 1 12
Average 2 5 1 3 0 21
ComplexIndex 1 3 - - - -
Bảng 3 nêu các ví dụ chứa vòng lặp đơn và tập ca kiểm thử đánh giá các vòng lặp đó
được sinh bởi công cụ CFT4CUnit. Công cụ đề xuất trong [5] không sinh được ca kiểm
thử cho vòng lặp. Kĩ thuật kiểm thử vòng lặp của PathCrawler có tư tưởng và hướng đến
mục tiêu khác so với CFT4CUnit nên không nêu so sánh ở khóa luận này. Ở Bảng 3, các
đỉnh đi vào vòng lặp và thoát khỏi vòng lặp được bôi đậm. Nếu các đường kiểm thử mới
có vòng lặp sao chép một số lần cụ thể không có ca kiểm thử nào thỏa mãn, cột ca kiểm
thử ghi dấu “-“.
Bảng 3. Kiểm thử vòng lặp đơn sử dụng công cụ CFT4CUnit
Mã nguồn
Đường đi chứa vòng lặp trong tập
đường đi độc lập
Số lần
lặp
Ca kiểm thử
UCLN
!(m<0)#!(n<0)#!(m==0)#!(n==0)#
(m!=n)#(m>n)#(m=m-n)#
!(m!=n)#(return m)
0 n = 4, m = 4
1 n = 4, m = 8
2 n = 1, m = 3
41
6 n = 1, m = 7
!(m<0)#!(n<0)#!(m==0)#!(n==0)#
(m!=n)#!(m>n)#(n=n-m)#
!(m!=n)#(return m)
0 n = 6, m = 6
1 n = 4, m = 2
2 n = 9 , m = 3
8 n = 9, m = 1;
LaSo
NguyenTo
(int i=2)#!((n%i)==0)#(i++)#
(i<=n/2)#!((n%i)==0)#(i++)#
!(i<=n/2)#(return 1)
1 n = 1
2 n = 7
5 -
Average
(int tcnt=0,vcnt=0,sum=0,i=0)
#(value[i]!=-2&&tcnt<10)#
(tcnt++)#
(min<=value[i]&&value[i]<=max)#
(sum=sum+value[i])#(vcnt++)#
(i++)#!(value[i]!=-2&&tcnt<10)#
!(vcnt<0)#(return sum/vcnt)
0
max = -4, min = 5,
value[0] = -2
1
max = 3, min = 1,
value[0] = 3,
value[1] = -2
2
max = 5, min = -1,
value[0] = 5, value[1] = 4
,value[2] = -2
7
max = 4, min = -4,
value[0] = -4,
value[1] = -1,
value[2] = 3,
value[3] = 1,
value[4] = 0,
value[5] = 4,
value[6] = 0,
value[7] = -2
(int tcnt=0,vcnt=0,sum=0,i=0)
#(value[i]!=-2&&tcnt<10)#
(tcnt++)#
!(min<=value[i]&&value[i]<=max)
0
max = 0, min = 5,
value[0] = -2
1
max = -3, min = 5,
value[0] = -4,
42
#(i++)#!(value[i]!=-2&&tcnt<10)#
!(vcnt<0)#(return sum/vcnt)
value[1] = -2
2
max = -1, min = 2,
value[0] = 3,
value[1] = 3,
value[2] = -2
8
max = -1, min = 0,
value[0] = -1,
value[1] = 2,
value[2] = -4,
value[3] = 5,
value[4] = -1,
value[5] = -3,
value[6] = -3,
value[7] = 5,
value[8] = -2
Bảng 4 trình bày các ca kiểm thử để kiểm thử tính đúng đắn vòng lặp hàm
SelectionSort sử dụng công cụ CFT4CUnit. Công cụ đề xuất trong [5] không sinh ca kiểm
thử cho hai vòng lặp lồng nhau.
Bảng 4. Kiểm thử hai vòng lặp lồng nhau hàm SelectionSort sử dụng CFT4CUnit
Đường đi chứa vòng
lặp trong tập đường đi
độc lập
Số lần
lặp
Ca kiểm thử
Kiểm thử vòng
lặp trong
(int i,j)#(i=0)#
(i<size-1)#
(int min=i)#(j=i+1)#
(j<size)
#!(a[j]<a[min])#(j++)
# !(j<size)#(int
tem=a[i])#
(a[i]=a[min])
#(a[min]=tem)#(i++)#
1 size = 8, a[6] = -3, a[7] = 7
2
size = 9, a[6] = 6, a[7] = 18,
a[8] = 14
4
size = 11, a[6] = -3, a[7] = 7,
a[8] = 19, a[9] = 9, a[10] = 12
Kiểm thử vòng
lặp ngoài
1 size = 2 ,a[0] = -2, a[1] = 5
2 size=3, a[0]=-5, a[1] =7, a[2] = 1
43
!(i<size-1)
7
size = 8, a[0] = -8, a[1] = 8,
a[2] = 8, a[3] = 3, a[4] = -1,
a[5] = 9, a[6] = 7, a[7] = -4
4.2.4. Ý nghĩa thực nghiệm
Kết quả thực nghiệm cho thấy ưu điểm của phương pháp đề xuất so với công cụ đề
xuất trong [5] và PathCrawler. Phương pháp đề xuất giải quyết tốt những hàm mà
PathCrawler không thể sinh ca kiểm thử đầu tiên. Ngoài ra, phương pháp đề xuất kiểm
thử hàm đến tiêu chí phủ điều kiện con nên phát hiện được nhiều vấn đề trong mã nguồn
hơn so với công cụ đề xuất trong [5] như trong ví dụ Average.
Về kiểm thử vòng lặp, PathCrawler có thể sinh số lượng ca kiểm thử rất lớn hoặc
không xác định. Ví dụ, trong hàm Average, PathCrawler sinh tới 21 ca kiểm thử nhưng
không phát hiện được lỗi nào. Công cụ đề xuất trong [5] không nêu chiến thuật kiểm thử
tính đúng đắn của vòng lặp. Công cụ CFT4CUnit hướng đến tìm tập ca kiểm thử để kiểm
tra tính đúng đắn của từng vòng lặp. Tùy vào loại vòng lặp, chúng tôi hoàn toàn xác định
được số lượng ca kiểm thử tối đa sinh ra bởi CFT4CUnit. Trường hợp vòng lặp đơn biết
số lần lặp tối đa, số lượng ca kiểm thử sinh bởi CFT4CUnit là 7 trong khi PathCrawler có
thể hơn rất nhiều nếu số lần lặp lớn. Với vòng lặp đơn không biết số lần lặp tối đa, số ca
kiểm thử sinh bởi PathCrawler có thể không xác định trong khi CFT4CUnit chỉ sinh tối
đa 4 ca kiểm thử.
Trong trường hợp hai vòng lặp lồng nhau, số ca kiểm thử tối đa mà CFT4CUnit sinh
là 14 (gồm 7 ca kiểm thử đánh giá vòng lặp bên trong, 7 ca kiểm thử đánh giá vòng lặp
bên ngoài). Ngược lại, số ca kiểm thử tối đa sinh bởi PathCrawler không xác định và bằng
m*n, trong đó m là số lần lặp tối đa vòng lặp bên trong, n là số lần lặp tối đa vòng lặp bên
ngoài. Trong trường hợp tệ nhất, PathCrawler sinh số lượng ca kiểm thử không xác định
nếu số lần lặp tối đa vòng lặp bên trong và vòng lặp bên ngoài không xác định. Trong pha
kiểm thử chất lượng phần mềm, nếu số lượng ca kiểm thử rất lớn hoặc không xác định sẽ
gây rất nhiều khó khăn cho khâu quản lý.
Về khả năng giải hệ ràng buộc, CFT4CUnit kết hợp sinh ngẫu nhiên và tận dụng thế
mạnh công cụ SMT-Solver nên giải được nhiều hệ ràng buộc khác nhau. Ví dụ cụ thể,
trong hàm Average, câu lệnh điều kiện có toán tử so sánh khác nên không thể giải được
44
trong SmtInterpol. Tuy nhiên, phép sinh ngẫu nhiên giải quyết hiệu quả vấn đề này. Một
ví dụ khác, trường hợp hệ ràng buộc có biến mảng chỉ số phức tạp như trong ví dụ
ComplexIndex, quá trình biến đổi hệ có biến mảng kiểu này về chuẩn SMT-Lib rất khó
khăn và phức tạp nên sinh ngẫu nhiên được coi là một giải pháp thay thế khả thi. Đối với
PathCrawler và công cụ đề xuất trong [5], vấn đề này rất khó giải quyết.
Đề tài: Xây dựng công cụ kiểm thử tự động cho chương trình C
Đề tài: Xây dựng công cụ kiểm thử tự động cho chương trình C
Đề tài: Xây dựng công cụ kiểm thử tự động cho chương trình C

Contenu connexe

Tendances

Báo Cáo Đồ Án 2 : Thiết Kế Web Bán Đồng Hồ
Báo Cáo Đồ Án 2 : Thiết Kế Web Bán Đồng HồBáo Cáo Đồ Án 2 : Thiết Kế Web Bán Đồng Hồ
Báo Cáo Đồ Án 2 : Thiết Kế Web Bán Đồng Hồ
zDollz Lovez
 
PHÂN TÍCH THIẾT KẾ HỆ THỐNG BÁN HÀNG QUA MẠNG
PHÂN TÍCH THIẾT KẾ HỆ THỐNG BÁN HÀNG QUA MẠNGPHÂN TÍCH THIẾT KẾ HỆ THỐNG BÁN HÀNG QUA MẠNG
PHÂN TÍCH THIẾT KẾ HỆ THỐNG BÁN HÀNG QUA MẠNG
Thùy Linh
 
Bài tập nhập môn lập trình
Bài tập nhập môn lập trìnhBài tập nhập môn lập trình
Bài tập nhập môn lập trình
Huy Rùa
 
Báo Cáo Cuối Ký Thực Tập Tốt Nghiệp Xậy Dựng Web Bán Hàng Trực Tuyến bằng Ope...
Báo Cáo Cuối Ký Thực Tập Tốt Nghiệp Xậy Dựng Web Bán Hàng Trực Tuyến bằng Ope...Báo Cáo Cuối Ký Thực Tập Tốt Nghiệp Xậy Dựng Web Bán Hàng Trực Tuyến bằng Ope...
Báo Cáo Cuối Ký Thực Tập Tốt Nghiệp Xậy Dựng Web Bán Hàng Trực Tuyến bằng Ope...
hoainhan1501
 
Đề thi trắc nghiệm Xác suất thống kê có lời giải
Đề thi trắc nghiệm Xác suất thống kê có lời giảiĐề thi trắc nghiệm Xác suất thống kê có lời giải
Đề thi trắc nghiệm Xác suất thống kê có lời giải
希夢 坂井
 

Tendances (20)

Bài thuyết trình: Cuộc sống trong thế giới ảo
Bài thuyết trình: Cuộc sống trong thế giới ảoBài thuyết trình: Cuộc sống trong thế giới ảo
Bài thuyết trình: Cuộc sống trong thế giới ảo
 
Đề tài: Xây dựng ứng dụng Android nghe nhạc trên internet, HOT
Đề tài: Xây dựng ứng dụng Android nghe nhạc trên internet, HOTĐề tài: Xây dựng ứng dụng Android nghe nhạc trên internet, HOT
Đề tài: Xây dựng ứng dụng Android nghe nhạc trên internet, HOT
 
Baigiang05 thuattoan(1s 1p)
Baigiang05 thuattoan(1s 1p)Baigiang05 thuattoan(1s 1p)
Baigiang05 thuattoan(1s 1p)
 
Báo Cáo Đồ Án 2 : Thiết Kế Web Bán Đồng Hồ
Báo Cáo Đồ Án 2 : Thiết Kế Web Bán Đồng HồBáo Cáo Đồ Án 2 : Thiết Kế Web Bán Đồng Hồ
Báo Cáo Đồ Án 2 : Thiết Kế Web Bán Đồng Hồ
 
PHÂN TÍCH THIẾT KẾ HỆ THỐNG BÁN HÀNG QUA MẠNG
PHÂN TÍCH THIẾT KẾ HỆ THỐNG BÁN HÀNG QUA MẠNGPHÂN TÍCH THIẾT KẾ HỆ THỐNG BÁN HÀNG QUA MẠNG
PHÂN TÍCH THIẾT KẾ HỆ THỐNG BÁN HÀNG QUA MẠNG
 
bảng tra phân phối chuẩn
bảng tra phân phối chuẩnbảng tra phân phối chuẩn
bảng tra phân phối chuẩn
 
Đề thi mẫu trắc nghiệm cấu trúc dữ liệu cà giải thuật
Đề thi mẫu trắc nghiệm cấu trúc dữ liệu cà giải thuậtĐề thi mẫu trắc nghiệm cấu trúc dữ liệu cà giải thuật
Đề thi mẫu trắc nghiệm cấu trúc dữ liệu cà giải thuật
 
Bài tập nhập môn lập trình
Bài tập nhập môn lập trìnhBài tập nhập môn lập trình
Bài tập nhập môn lập trình
 
Giáo trình phân tích thiết kế hệ thống thông tin
Giáo trình phân tích thiết kế hệ thống thông tinGiáo trình phân tích thiết kế hệ thống thông tin
Giáo trình phân tích thiết kế hệ thống thông tin
 
Đề tài: Xây dựng website giới thiệu sản phẩm phần mềm, HOT
Đề tài: Xây dựng website giới thiệu sản phẩm phần mềm, HOTĐề tài: Xây dựng website giới thiệu sản phẩm phần mềm, HOT
Đề tài: Xây dựng website giới thiệu sản phẩm phần mềm, HOT
 
Slide buổi hội thảo - họp báo công bố chính thức iQB 8.0
Slide buổi hội thảo - họp báo công bố chính thức iQB 8.0Slide buổi hội thảo - họp báo công bố chính thức iQB 8.0
Slide buổi hội thảo - họp báo công bố chính thức iQB 8.0
 
SINH VIÊN VÀ MẠNG XÃ HỘI FACEBOOK - MỘT PHÂN TÍCH VỀ SỰ TIẾN TRIỂN VỐN XÃ HỘI...
SINH VIÊN VÀ MẠNG XÃ HỘI FACEBOOK - MỘT PHÂN TÍCH VỀ SỰ TIẾN TRIỂN VỐN XÃ HỘI...SINH VIÊN VÀ MẠNG XÃ HỘI FACEBOOK - MỘT PHÂN TÍCH VỀ SỰ TIẾN TRIỂN VỐN XÃ HỘI...
SINH VIÊN VÀ MẠNG XÃ HỘI FACEBOOK - MỘT PHÂN TÍCH VỀ SỰ TIẾN TRIỂN VỐN XÃ HỘI...
 
Đồ án kiểm thử phần mềm
Đồ án kiểm thử phần mềmĐồ án kiểm thử phần mềm
Đồ án kiểm thử phần mềm
 
Báo Cáo Cuối Ký Thực Tập Tốt Nghiệp Xậy Dựng Web Bán Hàng Trực Tuyến bằng Ope...
Báo Cáo Cuối Ký Thực Tập Tốt Nghiệp Xậy Dựng Web Bán Hàng Trực Tuyến bằng Ope...Báo Cáo Cuối Ký Thực Tập Tốt Nghiệp Xậy Dựng Web Bán Hàng Trực Tuyến bằng Ope...
Báo Cáo Cuối Ký Thực Tập Tốt Nghiệp Xậy Dựng Web Bán Hàng Trực Tuyến bằng Ope...
 
Xử lý tín hiệu số
Xử lý tín hiệu sốXử lý tín hiệu số
Xử lý tín hiệu số
 
Đề thi trắc nghiệm Xác suất thống kê có lời giải
Đề thi trắc nghiệm Xác suất thống kê có lời giảiĐề thi trắc nghiệm Xác suất thống kê có lời giải
Đề thi trắc nghiệm Xác suất thống kê có lời giải
 
đồ áN xây dựng website bán laptop 1129155
đồ áN xây dựng website bán laptop 1129155đồ áN xây dựng website bán laptop 1129155
đồ áN xây dựng website bán laptop 1129155
 
Đề tài: Xây dựng Website quản lý điểm trường Phổ thông, 9đ
Đề tài: Xây dựng Website quản lý điểm trường Phổ thông, 9đĐề tài: Xây dựng Website quản lý điểm trường Phổ thông, 9đ
Đề tài: Xây dựng Website quản lý điểm trường Phổ thông, 9đ
 
Đề tài: Tác động của mạng xã hội Facebook đối với học sinh trung học cơ sở
Đề tài: Tác động của mạng xã hội Facebook đối với học sinh trung học cơ sởĐề tài: Tác động của mạng xã hội Facebook đối với học sinh trung học cơ sở
Đề tài: Tác động của mạng xã hội Facebook đối với học sinh trung học cơ sở
 
Báo cáo đồ án - Thiết kế web tại Thanh Hóa
Báo cáo đồ án - Thiết kế web tại Thanh HóaBáo cáo đồ án - Thiết kế web tại Thanh Hóa
Báo cáo đồ án - Thiết kế web tại Thanh Hóa
 

Similaire à Đề tài: Xây dựng công cụ kiểm thử tự động cho chương trình C

Điều khiển cân bằng hệ con lắc ngược.pdf
Điều khiển cân bằng hệ con lắc ngược.pdfĐiều khiển cân bằng hệ con lắc ngược.pdf
Điều khiển cân bằng hệ con lắc ngược.pdf
Man_Ebook
 
Nghiên cứu phát triển hệ điều khiển đo đặc tính đầu ra cho bộ định vị sử dụng...
Nghiên cứu phát triển hệ điều khiển đo đặc tính đầu ra cho bộ định vị sử dụng...Nghiên cứu phát triển hệ điều khiển đo đặc tính đầu ra cho bộ định vị sử dụng...
Nghiên cứu phát triển hệ điều khiển đo đặc tính đầu ra cho bộ định vị sử dụng...
Man_Ebook
 
Thiết kế và chế tạo xe AGV ứng dụng Slam tối ưu hóa đường đi.pdf
Thiết kế và chế tạo xe AGV ứng dụng Slam tối ưu hóa đường đi.pdfThiết kế và chế tạo xe AGV ứng dụng Slam tối ưu hóa đường đi.pdf
Thiết kế và chế tạo xe AGV ứng dụng Slam tối ưu hóa đường đi.pdf
Man_Ebook
 
Nghiên cứu giải pháp đo kiểm tra đánh giá độ mòn bồn chứa xăng dầu dung tích ...
Nghiên cứu giải pháp đo kiểm tra đánh giá độ mòn bồn chứa xăng dầu dung tích ...Nghiên cứu giải pháp đo kiểm tra đánh giá độ mòn bồn chứa xăng dầu dung tích ...
Nghiên cứu giải pháp đo kiểm tra đánh giá độ mòn bồn chứa xăng dầu dung tích ...
Man_Ebook
 

Similaire à Đề tài: Xây dựng công cụ kiểm thử tự động cho chương trình C (20)

Luận văn: Phương pháp sinh dữ liệu kiểm thử tự động từ biểu đồ
Luận văn: Phương pháp sinh dữ liệu kiểm thử tự động từ biểu đồLuận văn: Phương pháp sinh dữ liệu kiểm thử tự động từ biểu đồ
Luận văn: Phương pháp sinh dữ liệu kiểm thử tự động từ biểu đồ
 
Luận văn thạc sĩ
Luận văn thạc sĩLuận văn thạc sĩ
Luận văn thạc sĩ
 
Luận văn: Tính toán khoảng giải các ràng buộc không tuyến tính
Luận văn: Tính toán khoảng giải các ràng buộc không tuyến tínhLuận văn: Tính toán khoảng giải các ràng buộc không tuyến tính
Luận văn: Tính toán khoảng giải các ràng buộc không tuyến tính
 
Luận văn thạc sĩ
Luận văn thạc sĩLuận văn thạc sĩ
Luận văn thạc sĩ
 
Luận văn: Kiểm thử tự động tương tác giao diện người dùng, 9đ
Luận văn: Kiểm thử tự động tương tác giao diện người dùng, 9đLuận văn: Kiểm thử tự động tương tác giao diện người dùng, 9đ
Luận văn: Kiểm thử tự động tương tác giao diện người dùng, 9đ
 
Tìm Hiểu Các Kỹ Thuật Kiểm Thử Phần Mềm và Một Số Ứng Dụng Trong Thực Tế
Tìm Hiểu Các Kỹ Thuật Kiểm Thử Phần Mềm và Một Số Ứng Dụng Trong Thực Tế Tìm Hiểu Các Kỹ Thuật Kiểm Thử Phần Mềm và Một Số Ứng Dụng Trong Thực Tế
Tìm Hiểu Các Kỹ Thuật Kiểm Thử Phần Mềm và Một Số Ứng Dụng Trong Thực Tế
 
Điều khiển cân bằng hệ con lắc ngược.pdf
Điều khiển cân bằng hệ con lắc ngược.pdfĐiều khiển cân bằng hệ con lắc ngược.pdf
Điều khiển cân bằng hệ con lắc ngược.pdf
 
Đề tài: Công cụ sinh dữ liệu thử tự động cho chương trình Java
Đề tài: Công cụ sinh dữ liệu thử tự động cho chương trình JavaĐề tài: Công cụ sinh dữ liệu thử tự động cho chương trình Java
Đề tài: Công cụ sinh dữ liệu thử tự động cho chương trình Java
 
Nghiên cứu phát triển hệ điều khiển đo đặc tính đầu ra cho bộ định vị sử dụng...
Nghiên cứu phát triển hệ điều khiển đo đặc tính đầu ra cho bộ định vị sử dụng...Nghiên cứu phát triển hệ điều khiển đo đặc tính đầu ra cho bộ định vị sử dụng...
Nghiên cứu phát triển hệ điều khiển đo đặc tính đầu ra cho bộ định vị sử dụng...
 
Luận Văn Xây Dựng Ca Kiểm Thử Từ Biểu Đồ Luồng Dữ Liệu.doc
Luận Văn Xây Dựng Ca Kiểm Thử Từ Biểu Đồ Luồng Dữ Liệu.docLuận Văn Xây Dựng Ca Kiểm Thử Từ Biểu Đồ Luồng Dữ Liệu.doc
Luận Văn Xây Dựng Ca Kiểm Thử Từ Biểu Đồ Luồng Dữ Liệu.doc
 
Tailieu.vncty.com t ke-testcase
Tailieu.vncty.com   t ke-testcaseTailieu.vncty.com   t ke-testcase
Tailieu.vncty.com t ke-testcase
 
Kiem thu
Kiem thuKiem thu
Kiem thu
 
Nghiên cứu, thiết kế, thử nghiệm xe hai bánh tự cân bằng​
Nghiên cứu, thiết kế, thử nghiệm xe hai bánh tự cân bằng​Nghiên cứu, thiết kế, thử nghiệm xe hai bánh tự cân bằng​
Nghiên cứu, thiết kế, thử nghiệm xe hai bánh tự cân bằng​
 
Thiết kế và chế tạo xe AGV ứng dụng Slam tối ưu hóa đường đi.pdf
Thiết kế và chế tạo xe AGV ứng dụng Slam tối ưu hóa đường đi.pdfThiết kế và chế tạo xe AGV ứng dụng Slam tối ưu hóa đường đi.pdf
Thiết kế và chế tạo xe AGV ứng dụng Slam tối ưu hóa đường đi.pdf
 
Nghiên cứu giải pháp đo kiểm tra đánh giá độ mòn bồn chứa xăng dầu dung tích ...
Nghiên cứu giải pháp đo kiểm tra đánh giá độ mòn bồn chứa xăng dầu dung tích ...Nghiên cứu giải pháp đo kiểm tra đánh giá độ mòn bồn chứa xăng dầu dung tích ...
Nghiên cứu giải pháp đo kiểm tra đánh giá độ mòn bồn chứa xăng dầu dung tích ...
 
Kiểm chứng các chương trình phần mềm hướng khía cạnh, HAY
Kiểm chứng các chương trình phần mềm hướng khía cạnh, HAYKiểm chứng các chương trình phần mềm hướng khía cạnh, HAY
Kiểm chứng các chương trình phần mềm hướng khía cạnh, HAY
 
Kiểm Thử Đột Biến Trong Môi Trường SimulinkMatlab.doc
Kiểm Thử Đột Biến Trong Môi Trường SimulinkMatlab.docKiểm Thử Đột Biến Trong Môi Trường SimulinkMatlab.doc
Kiểm Thử Đột Biến Trong Môi Trường SimulinkMatlab.doc
 
Giám sát và cảnh báo hoạt động phương tiện vận tải ô tô
Giám sát và cảnh báo hoạt động phương tiện vận tải ô tôGiám sát và cảnh báo hoạt động phương tiện vận tải ô tô
Giám sát và cảnh báo hoạt động phương tiện vận tải ô tô
 
Đề tài: Giám sát và cảnh báo hoạt động phương tiện vận tải ô tô
Đề tài: Giám sát và cảnh báo hoạt động phương tiện vận tải ô tôĐề tài: Giám sát và cảnh báo hoạt động phương tiện vận tải ô tô
Đề tài: Giám sát và cảnh báo hoạt động phương tiện vận tải ô tô
 
VỀ MỘT PHƯƠNG PHÁP TỔNG HỢP HỆ ĐIỀU KHIỂN MỜ DÙNG MẠNG NƠRON ỨNG DỤNG TRONG C...
VỀ MỘT PHƯƠNG PHÁP TỔNG HỢP HỆ ĐIỀU KHIỂN MỜ DÙNG MẠNG NƠRON ỨNG DỤNG TRONG C...VỀ MỘT PHƯƠNG PHÁP TỔNG HỢP HỆ ĐIỀU KHIỂN MỜ DÙNG MẠNG NƠRON ỨNG DỤNG TRONG C...
VỀ MỘT PHƯƠNG PHÁP TỔNG HỢP HỆ ĐIỀU KHIỂN MỜ DÙNG MẠNG NƠRON ỨNG DỤNG TRONG C...
 

Plus de Dịch Vụ Viết Bài Trọn Gói ZALO 0917193864

Plus de Dịch Vụ Viết Bài Trọn Gói ZALO 0917193864 (20)

Yếu Tố Tự Truyện Trong Truyện Ngắn Thạch Lam Và Thanh Tịnh.doc
Yếu Tố Tự Truyện Trong Truyện Ngắn Thạch Lam Và Thanh Tịnh.docYếu Tố Tự Truyện Trong Truyện Ngắn Thạch Lam Và Thanh Tịnh.doc
Yếu Tố Tự Truyện Trong Truyện Ngắn Thạch Lam Và Thanh Tịnh.doc
 
Từ Ngữ Biểu Thị Tâm Lí – Tình Cảm Trong Ca Dao Người Việt.doc
Từ Ngữ Biểu Thị Tâm Lí – Tình Cảm Trong Ca Dao Người Việt.docTừ Ngữ Biểu Thị Tâm Lí – Tình Cảm Trong Ca Dao Người Việt.doc
Từ Ngữ Biểu Thị Tâm Lí – Tình Cảm Trong Ca Dao Người Việt.doc
 
Quản Lý Hoạt Động Dạy Học Các Môn Khoa Học Tự Nhiên Theo Chuẩn Kiến Thức Và K...
Quản Lý Hoạt Động Dạy Học Các Môn Khoa Học Tự Nhiên Theo Chuẩn Kiến Thức Và K...Quản Lý Hoạt Động Dạy Học Các Môn Khoa Học Tự Nhiên Theo Chuẩn Kiến Thức Và K...
Quản Lý Hoạt Động Dạy Học Các Môn Khoa Học Tự Nhiên Theo Chuẩn Kiến Thức Và K...
 
Quản Lý Thu Thuế Giá Trị Gia Tăng Đối Với Doanh Nghiệp Ngoài Quốc Doanh Trên ...
Quản Lý Thu Thuế Giá Trị Gia Tăng Đối Với Doanh Nghiệp Ngoài Quốc Doanh Trên ...Quản Lý Thu Thuế Giá Trị Gia Tăng Đối Với Doanh Nghiệp Ngoài Quốc Doanh Trên ...
Quản Lý Thu Thuế Giá Trị Gia Tăng Đối Với Doanh Nghiệp Ngoài Quốc Doanh Trên ...
 
Thu Hút Nguồn Nhân Lực Trình Độ Cao Vào Các Cơ Quan Hành Chính Nhà Nước Tỉnh ...
Thu Hút Nguồn Nhân Lực Trình Độ Cao Vào Các Cơ Quan Hành Chính Nhà Nước Tỉnh ...Thu Hút Nguồn Nhân Lực Trình Độ Cao Vào Các Cơ Quan Hành Chính Nhà Nước Tỉnh ...
Thu Hút Nguồn Nhân Lực Trình Độ Cao Vào Các Cơ Quan Hành Chính Nhà Nước Tỉnh ...
 
Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Doanh Nghiệp Tại Ngân Hàng Thương Mại ...
Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Doanh Nghiệp Tại Ngân Hàng Thương Mại ...Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Doanh Nghiệp Tại Ngân Hàng Thương Mại ...
Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Doanh Nghiệp Tại Ngân Hàng Thương Mại ...
 
Vaporisation Of Single And Binary Component Droplets In Heated Flowing Gas St...
Vaporisation Of Single And Binary Component Droplets In Heated Flowing Gas St...Vaporisation Of Single And Binary Component Droplets In Heated Flowing Gas St...
Vaporisation Of Single And Binary Component Droplets In Heated Flowing Gas St...
 
Quản Lý Hoạt Động Dạy Học Các Trường Thpt Trên Địa Bàn Huyện Sơn Hà Tỉnh Quản...
Quản Lý Hoạt Động Dạy Học Các Trường Thpt Trên Địa Bàn Huyện Sơn Hà Tỉnh Quản...Quản Lý Hoạt Động Dạy Học Các Trường Thpt Trên Địa Bàn Huyện Sơn Hà Tỉnh Quản...
Quản Lý Hoạt Động Dạy Học Các Trường Thpt Trên Địa Bàn Huyện Sơn Hà Tỉnh Quản...
 
Tác Giả Hàm Ẩn Trong Tiểu Thuyết Nguyễn Việt Hà.doc
Tác Giả Hàm Ẩn Trong Tiểu Thuyết Nguyễn Việt Hà.docTác Giả Hàm Ẩn Trong Tiểu Thuyết Nguyễn Việt Hà.doc
Tác Giả Hàm Ẩn Trong Tiểu Thuyết Nguyễn Việt Hà.doc
 
Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Ngắn Hạn Tại Ngân Hàng Công Thƣơng Chi...
Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Ngắn Hạn Tại Ngân Hàng Công Thƣơng Chi...Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Ngắn Hạn Tại Ngân Hàng Công Thƣơng Chi...
Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Ngắn Hạn Tại Ngân Hàng Công Thƣơng Chi...
 
Quản Lý Nhà Nước Về Nuôi Trồng Thủy Sản Nước Ngọt Trên Địa Bàn Thành Phố Hải ...
Quản Lý Nhà Nước Về Nuôi Trồng Thủy Sản Nước Ngọt Trên Địa Bàn Thành Phố Hải ...Quản Lý Nhà Nước Về Nuôi Trồng Thủy Sản Nước Ngọt Trên Địa Bàn Thành Phố Hải ...
Quản Lý Nhà Nước Về Nuôi Trồng Thủy Sản Nước Ngọt Trên Địa Bàn Thành Phố Hải ...
 
Song Song Hóa Các Thuật Toán Trên Mạng Đồ Thị.doc
Song Song Hóa Các Thuật Toán Trên Mạng Đồ Thị.docSong Song Hóa Các Thuật Toán Trên Mạng Đồ Thị.doc
Song Song Hóa Các Thuật Toán Trên Mạng Đồ Thị.doc
 
Ứng Dụng Số Phức Trong Các Bài Toán Sơ Cấp.doc
Ứng Dụng Số Phức Trong Các Bài Toán Sơ Cấp.docỨng Dụng Số Phức Trong Các Bài Toán Sơ Cấp.doc
Ứng Dụng Số Phức Trong Các Bài Toán Sơ Cấp.doc
 
Vai Trò Của Cái Bi Trong Giáo Dục Thẩm Mỹ.doc
Vai Trò Của Cái Bi Trong Giáo Dục Thẩm Mỹ.docVai Trò Của Cái Bi Trong Giáo Dục Thẩm Mỹ.doc
Vai Trò Của Cái Bi Trong Giáo Dục Thẩm Mỹ.doc
 
Quản Lý Hoạt Động Giáo Dục Ngoài Giờ Lên Lớp Ở Các Trường Thcs Huyện Chư Păh ...
Quản Lý Hoạt Động Giáo Dục Ngoài Giờ Lên Lớp Ở Các Trường Thcs Huyện Chư Păh ...Quản Lý Hoạt Động Giáo Dục Ngoài Giờ Lên Lớp Ở Các Trường Thcs Huyện Chư Păh ...
Quản Lý Hoạt Động Giáo Dục Ngoài Giờ Lên Lớp Ở Các Trường Thcs Huyện Chư Păh ...
 
Thu Hút Vốn Đầu Tư Vào Lĩnh Vực Nông Nghiệp Trên Địa Bàn Tỉnh Gia Lai.doc
Thu Hút Vốn Đầu Tư Vào Lĩnh Vực Nông Nghiệp Trên Địa Bàn Tỉnh Gia Lai.docThu Hút Vốn Đầu Tư Vào Lĩnh Vực Nông Nghiệp Trên Địa Bàn Tỉnh Gia Lai.doc
Thu Hút Vốn Đầu Tư Vào Lĩnh Vực Nông Nghiệp Trên Địa Bàn Tỉnh Gia Lai.doc
 
Quản Lý Hoạt Động Dạy Học Ngoại Ngữ Tại Các Trung Tâm Ngoại Ngữ - Tin Học Trê...
Quản Lý Hoạt Động Dạy Học Ngoại Ngữ Tại Các Trung Tâm Ngoại Ngữ - Tin Học Trê...Quản Lý Hoạt Động Dạy Học Ngoại Ngữ Tại Các Trung Tâm Ngoại Ngữ - Tin Học Trê...
Quản Lý Hoạt Động Dạy Học Ngoại Ngữ Tại Các Trung Tâm Ngoại Ngữ - Tin Học Trê...
 
Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Doanh Nghiệp Tại Ngân Hàng Thƣơng Mại ...
Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Doanh Nghiệp Tại Ngân Hàng Thƣơng Mại ...Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Doanh Nghiệp Tại Ngân Hàng Thƣơng Mại ...
Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Doanh Nghiệp Tại Ngân Hàng Thƣơng Mại ...
 
Tạo Việc Làm Cho Thanh Niên Trên Địa Bàn Quận Thanh Khê, Thành Phố Đà Nẵng.doc
Tạo Việc Làm Cho Thanh Niên Trên Địa Bàn Quận Thanh Khê, Thành Phố Đà Nẵng.docTạo Việc Làm Cho Thanh Niên Trên Địa Bàn Quận Thanh Khê, Thành Phố Đà Nẵng.doc
Tạo Việc Làm Cho Thanh Niên Trên Địa Bàn Quận Thanh Khê, Thành Phố Đà Nẵng.doc
 
Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Trung Và Dài Hạn Tại Ngân Hàng Thương ...
Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Trung Và Dài Hạn Tại Ngân Hàng Thương ...Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Trung Và Dài Hạn Tại Ngân Hàng Thương ...
Quản Trị Rủi Ro Tín Dụng Trong Cho Vay Trung Và Dài Hạn Tại Ngân Hàng Thương ...
 

Dernier

SLIDE - Tu van, huong dan cong tac tuyen sinh-2024 (đầy đủ chi tiết).pdf
SLIDE - Tu van, huong dan cong tac tuyen sinh-2024 (đầy đủ chi tiết).pdfSLIDE - Tu van, huong dan cong tac tuyen sinh-2024 (đầy đủ chi tiết).pdf
SLIDE - Tu van, huong dan cong tac tuyen sinh-2024 (đầy đủ chi tiết).pdf
hoangtuansinh1
 
bài tập lớn môn kiến trúc máy tính và hệ điều hành
bài tập lớn môn kiến trúc máy tính và hệ điều hànhbài tập lớn môn kiến trúc máy tính và hệ điều hành
bài tập lớn môn kiến trúc máy tính và hệ điều hành
dangdinhkien2k4
 
xemsomenh.com-Vòng Tràng Sinh - Cách An 12 Sao Và Ý Nghĩa Từng Sao.pdf
xemsomenh.com-Vòng Tràng Sinh - Cách An 12 Sao Và Ý Nghĩa Từng Sao.pdfxemsomenh.com-Vòng Tràng Sinh - Cách An 12 Sao Và Ý Nghĩa Từng Sao.pdf
xemsomenh.com-Vòng Tràng Sinh - Cách An 12 Sao Và Ý Nghĩa Từng Sao.pdf
Xem Số Mệnh
 
C6. Van de dan toc va ton giao ....pdf . Chu nghia xa hoi
C6. Van de dan toc va ton giao ....pdf . Chu nghia xa hoiC6. Van de dan toc va ton giao ....pdf . Chu nghia xa hoi
C6. Van de dan toc va ton giao ....pdf . Chu nghia xa hoi
dnghia2002
 
SD-05_Xây dựng website bán váy Lolita Alice - Phùng Thị Thúy Hiền PH 2 7 8 6 ...
SD-05_Xây dựng website bán váy Lolita Alice - Phùng Thị Thúy Hiền PH 2 7 8 6 ...SD-05_Xây dựng website bán váy Lolita Alice - Phùng Thị Thúy Hiền PH 2 7 8 6 ...
SD-05_Xây dựng website bán váy Lolita Alice - Phùng Thị Thúy Hiền PH 2 7 8 6 ...
ChuThNgnFEFPLHN
 
Bài tập nhóm Kỹ Năng Gỉai Quyết Tranh Chấp Lao Động (1).pptx
Bài tập nhóm Kỹ Năng Gỉai Quyết Tranh Chấp Lao Động (1).pptxBài tập nhóm Kỹ Năng Gỉai Quyết Tranh Chấp Lao Động (1).pptx
Bài tập nhóm Kỹ Năng Gỉai Quyết Tranh Chấp Lao Động (1).pptx
DungxPeach
 

Dernier (20)

TÀI LIỆU BỒI DƯỠNG HỌC SINH GIỎI LÝ LUẬN VĂN HỌC NĂM HỌC 2023-2024 - MÔN NGỮ ...
TÀI LIỆU BỒI DƯỠNG HỌC SINH GIỎI LÝ LUẬN VĂN HỌC NĂM HỌC 2023-2024 - MÔN NGỮ ...TÀI LIỆU BỒI DƯỠNG HỌC SINH GIỎI LÝ LUẬN VĂN HỌC NĂM HỌC 2023-2024 - MÔN NGỮ ...
TÀI LIỆU BỒI DƯỠNG HỌC SINH GIỎI LÝ LUẬN VĂN HỌC NĂM HỌC 2023-2024 - MÔN NGỮ ...
 
Trắc nghiệm CHƯƠNG 5 môn Chủ nghĩa xã hội
Trắc nghiệm CHƯƠNG 5 môn Chủ nghĩa xã hộiTrắc nghiệm CHƯƠNG 5 môn Chủ nghĩa xã hội
Trắc nghiệm CHƯƠNG 5 môn Chủ nghĩa xã hội
 
SLIDE - Tu van, huong dan cong tac tuyen sinh-2024 (đầy đủ chi tiết).pdf
SLIDE - Tu van, huong dan cong tac tuyen sinh-2024 (đầy đủ chi tiết).pdfSLIDE - Tu van, huong dan cong tac tuyen sinh-2024 (đầy đủ chi tiết).pdf
SLIDE - Tu van, huong dan cong tac tuyen sinh-2024 (đầy đủ chi tiết).pdf
 
BỘ LUYỆN NGHE VÀO 10 TIẾNG ANH DẠNG TRẮC NGHIỆM 4 CÂU TRẢ LỜI - CÓ FILE NGHE.pdf
BỘ LUYỆN NGHE VÀO 10 TIẾNG ANH DẠNG TRẮC NGHIỆM 4 CÂU TRẢ LỜI - CÓ FILE NGHE.pdfBỘ LUYỆN NGHE VÀO 10 TIẾNG ANH DẠNG TRẮC NGHIỆM 4 CÂU TRẢ LỜI - CÓ FILE NGHE.pdf
BỘ LUYỆN NGHE VÀO 10 TIẾNG ANH DẠNG TRẮC NGHIỆM 4 CÂU TRẢ LỜI - CÓ FILE NGHE.pdf
 
ĐỀ CHÍNH THỨC KỲ THI TUYỂN SINH VÀO LỚP 10 THPT CÁC TỈNH THÀNH NĂM HỌC 2020 –...
ĐỀ CHÍNH THỨC KỲ THI TUYỂN SINH VÀO LỚP 10 THPT CÁC TỈNH THÀNH NĂM HỌC 2020 –...ĐỀ CHÍNH THỨC KỲ THI TUYỂN SINH VÀO LỚP 10 THPT CÁC TỈNH THÀNH NĂM HỌC 2020 –...
ĐỀ CHÍNH THỨC KỲ THI TUYỂN SINH VÀO LỚP 10 THPT CÁC TỈNH THÀNH NĂM HỌC 2020 –...
 
bài tập lớn môn kiến trúc máy tính và hệ điều hành
bài tập lớn môn kiến trúc máy tính và hệ điều hànhbài tập lớn môn kiến trúc máy tính và hệ điều hành
bài tập lớn môn kiến trúc máy tính và hệ điều hành
 
các nội dung phòng chống xâm hại tình dục ở trẻ em
các nội dung phòng chống xâm hại tình dục ở trẻ emcác nội dung phòng chống xâm hại tình dục ở trẻ em
các nội dung phòng chống xâm hại tình dục ở trẻ em
 
TUYỂN TẬP 50 ĐỀ LUYỆN THI TUYỂN SINH LỚP 10 THPT MÔN TOÁN NĂM 2024 CÓ LỜI GIẢ...
TUYỂN TẬP 50 ĐỀ LUYỆN THI TUYỂN SINH LỚP 10 THPT MÔN TOÁN NĂM 2024 CÓ LỜI GIẢ...TUYỂN TẬP 50 ĐỀ LUYỆN THI TUYỂN SINH LỚP 10 THPT MÔN TOÁN NĂM 2024 CÓ LỜI GIẢ...
TUYỂN TẬP 50 ĐỀ LUYỆN THI TUYỂN SINH LỚP 10 THPT MÔN TOÁN NĂM 2024 CÓ LỜI GIẢ...
 
kinh tế chính trị mác lênin chương hai và hàng hoá và sxxhh
kinh tế chính trị mác lênin chương hai và hàng hoá và sxxhhkinh tế chính trị mác lênin chương hai và hàng hoá và sxxhh
kinh tế chính trị mác lênin chương hai và hàng hoá và sxxhh
 
xemsomenh.com-Vòng Tràng Sinh - Cách An 12 Sao Và Ý Nghĩa Từng Sao.pdf
xemsomenh.com-Vòng Tràng Sinh - Cách An 12 Sao Và Ý Nghĩa Từng Sao.pdfxemsomenh.com-Vòng Tràng Sinh - Cách An 12 Sao Và Ý Nghĩa Từng Sao.pdf
xemsomenh.com-Vòng Tràng Sinh - Cách An 12 Sao Và Ý Nghĩa Từng Sao.pdf
 
Giới thiệu Dự án Sản Phụ Khoa - Y Học Cộng Đồng
Giới thiệu Dự án Sản Phụ Khoa - Y Học Cộng ĐồngGiới thiệu Dự án Sản Phụ Khoa - Y Học Cộng Đồng
Giới thiệu Dự án Sản Phụ Khoa - Y Học Cộng Đồng
 
Giáo trình nhập môn lập trình - Đặng Bình Phương
Giáo trình nhập môn lập trình - Đặng Bình PhươngGiáo trình nhập môn lập trình - Đặng Bình Phương
Giáo trình nhập môn lập trình - Đặng Bình Phương
 
C6. Van de dan toc va ton giao ....pdf . Chu nghia xa hoi
C6. Van de dan toc va ton giao ....pdf . Chu nghia xa hoiC6. Van de dan toc va ton giao ....pdf . Chu nghia xa hoi
C6. Van de dan toc va ton giao ....pdf . Chu nghia xa hoi
 
xemsomenh.com-Vòng Lộc Tồn - Vòng Bác Sĩ và Cách An Trong Vòng Lộc Tồn.pdf
xemsomenh.com-Vòng Lộc Tồn - Vòng Bác Sĩ và Cách An Trong Vòng Lộc Tồn.pdfxemsomenh.com-Vòng Lộc Tồn - Vòng Bác Sĩ và Cách An Trong Vòng Lộc Tồn.pdf
xemsomenh.com-Vòng Lộc Tồn - Vòng Bác Sĩ và Cách An Trong Vòng Lộc Tồn.pdf
 
SD-05_Xây dựng website bán váy Lolita Alice - Phùng Thị Thúy Hiền PH 2 7 8 6 ...
SD-05_Xây dựng website bán váy Lolita Alice - Phùng Thị Thúy Hiền PH 2 7 8 6 ...SD-05_Xây dựng website bán váy Lolita Alice - Phùng Thị Thúy Hiền PH 2 7 8 6 ...
SD-05_Xây dựng website bán váy Lolita Alice - Phùng Thị Thúy Hiền PH 2 7 8 6 ...
 
TÀI LIỆU BỒI DƯỠNG HỌC SINH GIỎI KỸ NĂNG VIẾT ĐOẠN VĂN NGHỊ LUẬN XÃ HỘI 200 C...
TÀI LIỆU BỒI DƯỠNG HỌC SINH GIỎI KỸ NĂNG VIẾT ĐOẠN VĂN NGHỊ LUẬN XÃ HỘI 200 C...TÀI LIỆU BỒI DƯỠNG HỌC SINH GIỎI KỸ NĂNG VIẾT ĐOẠN VĂN NGHỊ LUẬN XÃ HỘI 200 C...
TÀI LIỆU BỒI DƯỠNG HỌC SINH GIỎI KỸ NĂNG VIẾT ĐOẠN VĂN NGHỊ LUẬN XÃ HỘI 200 C...
 
Kiến thức cơ bản về tư duy số - VTC Net Viet
Kiến thức cơ bản về tư duy số - VTC Net VietKiến thức cơ bản về tư duy số - VTC Net Viet
Kiến thức cơ bản về tư duy số - VTC Net Viet
 
Đề thi tin học HK2 lớp 3 Chân Trời Sáng Tạo
Đề thi tin học HK2 lớp 3 Chân Trời Sáng TạoĐề thi tin học HK2 lớp 3 Chân Trời Sáng Tạo
Đề thi tin học HK2 lớp 3 Chân Trời Sáng Tạo
 
Bài học phòng cháy chữa cháy - PCCC tại tòa nhà
Bài học phòng cháy chữa cháy - PCCC tại tòa nhàBài học phòng cháy chữa cháy - PCCC tại tòa nhà
Bài học phòng cháy chữa cháy - PCCC tại tòa nhà
 
Bài tập nhóm Kỹ Năng Gỉai Quyết Tranh Chấp Lao Động (1).pptx
Bài tập nhóm Kỹ Năng Gỉai Quyết Tranh Chấp Lao Động (1).pptxBài tập nhóm Kỹ Năng Gỉai Quyết Tranh Chấp Lao Động (1).pptx
Bài tập nhóm Kỹ Năng Gỉai Quyết Tranh Chấp Lao Động (1).pptx
 

Đề tài: Xây dựng công cụ kiểm thử tự động cho chương trình C

  • 1. ĐẠI HỌC QUỐC GIA HÀ NỘI TRƯỜNG ĐẠI HỌC CÔNG NGHỆ Nguyễn Đức Anh XÂY DỰNG CÔNG CỤ KIỂM THỬ TỰ ĐỘNG CHO CÁC CHƯƠNG TRÌNH C KHÓA LUẬN TỐT NGHIỆP ĐẠI HỌC HỆ CHÍNH QUY Ngành: Công nghệ thông tin HÀ NỘI – 2015
  • 2. ĐẠI HỌC QUỐC GIA HÀ NỘI TRƯỜNG ĐẠI HỌC CÔNG NGHỆ Nguyễn Đức Anh XÂY DỰNG CÔNG CỤ KIỂM THỬ TỰ ĐỘNG CHO CÁC CHƯƠNG TRÌNH C KHÓA LUẬN TỐT NGHIỆP ĐẠI HỌC HỆ CHÍNH QUY Ngành: Công Nghệ Thông Tin Cán bộ hướng dẫn: TS. Phạm Ngọc Hùng (ký tên) HÀ NỘI - 2015
  • 3. LỜI CẢM ƠN VIETNAM NATIONAL UNIVERSITY, HANOI UNIVERSITY OF ENGINEERING AND TECHNOLOGY Nguyen Duc Anh A METHOD AND TOOL SUPPORTING FOR AUTOMATED TESTING OF C PROGRAMS THE BS THESIS Major: Information Technology Supervisor: Dr. Pham Ngoc Hung HA NOI - 2015
  • 4. LỜI CẢM ƠN Đầu tiên, tôi xin gửi lời cám ơn chân thành tới Tiến sĩ Phạm Ngọc Hùng – giảng viên bộ môn Công Nghệ Phần Mềm – người đã hướng dẫn tận tình, tỉ mỉ, chu đáo tôi trong suốt hai năm làm khóa luận tốt nghiệp. Quãng thời gian được thầy hướng dẫn đã giúp tôi học hỏi, đúc kết được nhiều kinh nghiệm về phương pháp nghiên cứu, kĩ năng giao tiếp, kĩ năng làm việc nhóm, kĩ năng trình bày. Thầy còn truyền cho tôi ngọn lửa yêu nghiên cứu khoa học, niềm tin vượt qua những khó khăn trong cuộc sống và dạy tôi cách vượt qua những khó khăn đó. Tôi cảm thấy tự hào và may mắn khi là một sinh viên được thầy hướng dẫn trong những năm tháng đại học. Ngoài ra, tôi xin gửi lời cám ơn chân thành đến tập thể lớp K56 đã giúp đỡ tôi nhiệt tình để hoàn thành khóa luận sao cho đạt hiệu quả cao nhất. Các bạn đã giúp đỡ tôi bằng hành động, bằng lời nói mỗi khi tôi gặp khó khăn, thất bại. Bốn năm bên nhau không phải là dài nhưng đối với tôi, đây là quãng thời gian tuyệt vời nhất và không thể nào quên. Tiếp theo, tôi xin gửi lời cảm ơn đến các thầy cô giảng viên Trường Đại học Công Nghệ - Đại học Quốc Gia Hà Nội – những người đã tận tâm truyền đạt những kiến thức quý báu làm nền tảng để tôi tiếp tục đi xa hơn nữa trong lĩnh vực công nghệ thông tin. Cuối cùng, tôi xin được cảm ơn gia đình đã nuôi tôi khôn lớn để trở thành người có ích cho xã hội, giúp tôi có một điểm tựa vững chắc để yên tâm học hành trong suốt bao năm qua. Tôi xin gửi lời cám ơn chân thành tới cha, mẹ, em gái đã luôn động viên và cổ vũ tôi mỗi khi tôi gặp khó khăn và thử thách. Hà Nội, ngày 03 tháng 05 năm 2014 Sinh viên Nguyễn Đức Anh
  • 5. TÓM TẮT Ngày nay, ngôn ngữ C là một trong những ngôn ngữ lập trình phổ biến để phát triển phần mềm, đặc biệt là các phần mềm hệ thống. Một trong những kĩ thuật kiểm thử hiệu quả hay được sử dụng là sinh ca kiểm thử trong kiểm thử hộp trắng dòng điều khiển. Để tiết kiệm chi phí kiểm thử phần mềm, quá trình sinh ca kiểm thử nên được tự động hóa hết mức có thể. Trong khi đó, các công cụ kiểm thử hiện nay chỉ tập trung vào thực thi các ca kiểm thử mà ít quan tâm đến sinh ca kiểm thử tự động. Một vài công cụ kiểm thử sinh ca kiểm thử tự động nhưng số lượng ca kiểm thử không xác định hoặc khá lớn gây khó khăn cho quản lý, ngoài ra còn hạn chế về thời gian sinh ca kiểm thử. Vì thế, khóa luận đề xuất một phương pháp sinh ca kiểm thử tự động cho một hàm C chứa các biến số nguyên, số thực và biến mảng sử dụng kĩ thuật kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh và cài đặt công cụ hỗ trợ CFT4CUnit. Đầu vào gồm một hàm C và tiêu chí phủ kiểm thử phủ. Đầu ra gồm tập ca kiểm thử thỏa mãn tiêu chí phủ kiểm thử và tập ca kiểm thử để kiểm thử vòng lặp (nếu hàm C có vòng lặp). Cụ thể bước đầu tiên, mã nguồn được phân tích để sinh đồ thị dòng điều khiển thỏa mãn tiêu chí phủ kiểm thử. Sau đó, đồ thị dòng điều khiển được phân tích để xây dựng tập đường kiểm thử. Tiếp theo, các đường kiểm thử chứa vòng lặp được cấu trúc lại để sinh thêm các đường kiểm thử mới dùng kiểm thử tính đúng đắn vòng lặp. Kế tiếp, các đường kiểm thử được phân tích bằng kĩ thuật SE để xây dựng hệ ràng buộc tương ứng. Cuối cùng, hệ ràng buộc được giải để sinh ca kiểm thử bằng cách kết hợp kĩ thuật sinh ngẫu nhiên và tận dụng thế mạnh các công cụ SMT-Solver. Kết quả thực nghiệm cho thấy khả năng phát hiện được lỗi khá tốt trong hàm C với số bộ ca kiểm thử tối thiểu mà vẫn đảm bảo tính đúng đắn cao của mã nguồn. Ngoài ra, thời gian sinh ca kiểm thử được cải thiện đáng kể và giải được nhiều hệ ràng buộc khác nhau vì kết hợp kĩ thuật sinh ngẫu nhiên và sử dụng công cụ SMT-Solver. Từ khóa: Kiểm thử tự động, hàm C, đồ thị dòng điều khiển, ca kiểm thử, Symbolic Execution, SMT-Solver
  • 6. ABSTRACT Nowadays, C programming language has been known as one of the most popular programming languages to develope applications, especially system applications. Because of high demand in quality, testing phase is performed quite rigorously and strictly. As a result, the cost of the testing phase can be up to 40% - 60% the total cost of application development process. Test case generation in white-box testing is an effective technique and used widely to ensure the high quality of applications. To reduce the cost of the testing phase, the test case generation process should be automated as much as possible. However, some testing tools focus on executing test cases and output the testing report instead of generating test cases automatically. Other testing tools assist to generate test cases automatically but the number of test cases may be a lot or un-known which cause many difficult and challenging problems such as management, time limit, etc. The thesis proposes an approach how to generate test cases automatically for C Unit containing integer variables, float variables, array variables. The proposed approach is based on white-box testing and implements in CFT4CUnit tool to demonstrate the effectiveness of the approach. Firstly, source code is analysed to generate corresponding Control Flow Graph (CFG). Then I traverse the CFG to obtain the independent paths. After that, paths containing loop is re- constructed to create some new paths used to test the loop. Next, each path is analysed by using symbolic execution technique to generate corresponding constraints. Finally, the process of solving the constraints is performed to find solution as fast as possible by combining random technique and SMT-Solvers. The experimental result shows the effectiveness of the approach with the minimum number of test cases but ensures the high quality of source code. Keywords: automated testing, C Unit, control flow testing, test case, symbolic execution, SMT- Solver
  • 7. LỜI CAM ĐOAN Tôi xin cam đoan rằng những nghiên cứu về kiểm thử tự động cho hàm C được trình bày trong luận án này là của tôi và chưa từng được nộp như một báo cáo khóa luận tại trường Đại học Công Nghệ - Đại học Quốc Gia Hà Nội hoặc bất kỳ trường đại học khác. Những gì tôi viết ra không sao chép từ các tài liệu, không sử dụng các kết quả của người khác mà không trích dẫn cụ thể. Tôi xin cam đoan công cụ kiểm thử tự động tôi trình bày trong khoá luận là do tôi tự phát triển, không sao chép mã nguồn của người khác. Nếu sai tôi hoàn toàn chịu trách nhiệm theo quy định của trường Đại học Công Nghệ - Đại học Quốc Gia Hà Nội. Hà Nội, ngày 03 tháng 05 năm 2015 Sinh viên Nguyễn Đức Anh
  • 8. MỤC LỤC Đặt vấn đề.................................................................................................................1Chương 1. Tổng quan kĩ thuật kiểm thử hộp trắng dòng điều khiển....................................4Chương 2. 2.1. Tổng quan kĩ thuật kiểm thử hộp trắng dòng điều khiển.........................................4 2.2. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng động ..........4 2.3. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh............6 2.3.1. Các tiêu chí phủ kiểm thử..................................................................................7 2.3.2. Đồ thị dòng điều khiển ......................................................................................8 2.3.3. Đường kiểm thử.................................................................................................9 2.4. So sánh kĩ thuật kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh và động ...10 2.5. Tầm quan trọng của tự động hóa quy trình kiểm thử hộp trắng dòng điều khiển .11 Phương pháp kiểm thử tự động hàm C sử dụng kĩ thuật kiểm thử hộp trắngChương 3. dòng điều khiển theo hướng tĩnh................................................................................................12 3.1. Tổng quan phương pháp kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh.....12 3.2. Sinh đồ thị dòng điều khiển từ mã nguồn ..............................................................13 3.3. Xây dựng tập đường kiểm thử từ đồ thị dòng điều khiển......................................16 3.3.1. Xây dựng tập đường đi độc lập........................................................................16 3.3.2. Xây dựng đường kiểm thử vòng lặp................................................................17 3.3.2.1. Kiểm thử đường đi chứa vòng lặp đơn.....................................................18 3.3.2.2. Kiểm thử đường đi chứa hai vòng lặp lồng nhau....................................19 3.4. Sinh tập dữ liệu kiểm thử từ tập đường kiểm thử ..................................................20 3.4.1. Xây dựng hệ ràng buộc....................................................................................20 3.4.2. Tìm nghiệm thỏa mãn hệ ràng buộc ................................................................22 3.4.2.1. Giải hệ sử dụng kĩ thuật sinh ngẫu nhiên ................................................22
  • 9. 3.4.2.2. Giải hệ sử dụng SMT-Solver...................................................................23 3.4.2.3. So sánh ưu điểm, nhược điểm của hai hướng sinh ca kiểm thử..............29 Thực nghiệm ..........................................................................................................31Chương 4. 4.1. Các thư viện hỗ trợ.................................................................................................31 4.1.1. Giới thiệu về thư viện SMT-Solver SmtInterpol.............................................31 4.1.2. Giới thiệu về thư viện CDT .............................................................................31 4.1.3. Giới thiệu về thư viện Jeval.............................................................................32 4.2. Giới thiệu công cụ kiểm thử tự động hàm C..........................................................32 4.2.1. Tổng quan về công cụ CFT4CUnit..................................................................32 4.2.1. Đầu vào công cụ ..............................................................................................33 4.2.2. Đầu ra công cụ..................................................................................................34 4.2.2.1. Đồ thị dòng điều khiển ............................................................................34 4.2.2.2. Tập đường kiểm thử ................................................................................35 4.2.2.3. Tập ca kiểm thử.......................................................................................36 4.2.2.4. Biểu thức chuẩn SMT-Lib.......................................................................37 4.2.2.5. Kiểm thử vòng lặp đơn............................................................................37 4.2.2.6. Kiểm thử vòng lặp lồng nhau ..................................................................38 4.2.3. Thực nghiệm.....................................................................................................39 4.2.4. Ý nghĩa thực nghiệm .......................................................................................43 Kết luận ..................................................................................................................45Chương 5.
  • 10. DANH SÁCH BẢNG Bảng 1. Độ ưu tiên các toán tử ......................................................................................................26 Bảng 2. So sánh CFT4CUnit, công cụ đề xuất trong [5] và PathCrawler.....................................40 Bảng 3. Kiểm thử vòng lặp đơn sử dụng công cụ CFT4CUnit .....................................................40 Bảng 4. Kiểm thử hai vòng lặp lồng nhau hàm SelectionSort sử dụng công cụ CFT4CUnit.......42 DANH SÁCH KÝ HIỆU, CHỮ VIẾT TẮT AST Abstract Syntax Tree CFG Control Flow Graph CDT C/C++ Development Tooling CVC Cooperating Validity Checker DIMACS Center for Discrete Mathematics and Theoretical Computer Science SMT-Solver Satisfiability Modulo Theories Solver SAT Boolean Satisfiability Problem T-Solver Theory-specific Solvers SE Symbolic Execution
  • 11. DANH SÁCH HÌNH VẼ Hình 2.1. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng động..................5 Hình 2.2: Ví dụ một luật chèn mã nguồn trong DMS/SRT.............................................................6 Hình 2.3. Mã nguồn hàm triangle sau khi thêm khối mã nguồn mới..............................................6 Hình 2.4. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh....................7 Hình 2.5: Các cấu trúc điều khiển phổ biến. ...................................................................................9 Hình 3.1. Quy trình kiểm thử một hàm C theo phương pháp đề xuất...........................................12 Hình 3.2. Thuật toán sinh CFG từ mã nguồn ................................................................................13 Hình 3.3. Mã nguồn hàm average. ................................................................................................14 Hình 3.4. CFG hàm average tiêu chuẩn phủ câu lệnh, phủ nhánh. ...............................................15 Hình 3.5. CFG điều kiện kép (a>=0 || ((b>=0 && c>=0) || b+c>=0) || a+b+c>=0).......................16 Hình 3.6. Thuật toán sinh tập đường đi độc lập từ CFG. ..............................................................17 Hình 3.7. Thuật toán sinh đường kiểm thử vòng lặp.....................................................................18 Hình 3.8. Thuật toán sinh đường kiểm thử vòng lặp trong. ..........................................................19 Hình 3.9. Thuật toán sinh đường kiểm thử vòng lặp ngoài...........................................................20 Hình 3.10. Ví dụ một hệ ràng buộc. ..............................................................................................21 Hình 3.11. Thuật toán sinh hệ ràng buộc từ đường kiểm thử........................................................21 Hình 3.12. Quá trình rút gọn câu lệnh...........................................................................................22 Hình 3.13. Mô tả đầu vào, đầu ra SMT-Solver. ............................................................................24 Hình 3.14. Ví dụ hệ ràng buộc tuân theo chuẩn SMT-Lib. ...........................................................25 Hình 3.15. Quá trình chuyển một biểu thức trung tố về chuẩn SMT-Lib. ....................................25 Hình 3.16. Thuật toán xây dựng biểu thức hậu tố. ........................................................................27 Hình 3.17. Thuật toán xây dựng cây biểu thức từ biểu thức hậu tố. .............................................28 Hình 3.18. Thuật toán duyệt cây biểu thức....................................................................................29 Hình 4.1. Minh họa cây AST ứng với mã nguồn return x*3 ........................................................32
  • 12. Hình 4.2. Giao diện công cụ đề xuất. ............................................................................................33 Hình 4.3. Ví dụ đầu vào công cụ CFT4CUnit...............................................................................33 Hình 4.4. Đồ thị CFG tiêu chí phủ câu lệnh và phủ nhánh. ..........................................................34 Hình 4.5. Đồ thị CFG tiêu chí phủ điều kiện con..........................................................................34 Hình 4.6. Đường đi tương ứng trên CFG được bôi đỏ khi click vào một đường kiểm thử bất kì.35 Hình 4.7. Tập đường kiểm thử thỏa mãn phủ câu lệnh hàm foo...................................................35 Hình 4.8. Tập đường kiểm thử thỏa mãn phủ nhánh hàm foo.......................................................35 Hình 4.9. Tập đường kiểm thử thỏa mãn phủ điều kiện con hàm foo...........................................36 Hình 4.10. Tập đường đi độc lập để sinh tập đường kiểm thử phủ nhánh và phủ câu lệnh..........36 Hình 4.11. Ca kiểm thử thỏa mãn đường đi màu đỏ sinh theo kĩ thuật ngẫu nhiên và dùng SMT- Solver.............................................................................................................................................36 Hình 4.12. Hệ ràng buộc chuẩn SMT-Lib tương ứng với đường kiểm thử màu đỏ......................37 Hình 4.13. Kiểm thử vòng lặp đơn hàm tinh_tong........................................................................38 Hình 4.14. Kiểm thử một đường kiểm thử chứa hai vòng lặp lồng nhau trong hàm SelectionSort. .......................................................................................................................................................38
  • 13. 1 Đặt vấn đềChương 1. Ngày nay, ngôn ngữ C là một trong những ngôn ngữ lập trình phổ biến để phát triển các hệ thống nhúng nói riêng, các phần mềm hệ thống nói chung và các phần mềm ứng dụng. Các thống kê trên githut1 và TIOBE2 cho thấy ngôn ngữ C là một trong mười ngôn ngữ lập trình phổ biến nhất năm 2014. Thực tế, các phần mềm (đặc biệt là phần mềm hệ thống) thường yêu cầu cao về chất lượng nên đòi hỏi quá trình kiểm thử thực hiện khắt khe và nghiêm ngặt. Vì thế, kiểm thử hộp trắng được coi là một kĩ thuật an toàn và hiệu quả nhằm đảm bảo độ tin cậy cao của phần mềm. Ưu điểm của kiểm thử hộp trắng là tìm lỗi bằng cách xem xét trực tiếp trên mã nguồn trong khi kiểm thử hộp đen chỉ phát hiện được những lỗi dựa trên tài liệu đặc tả phần mềm. Rõ ràng, dù tài liệu đặc tả tốt đến đâu, nếu kiểm thử viên chỉ tìm kiếm lỗi dựa trên đặc tả sẽ không thể phát hiện được những lỗi lập trình tiềm ẩn gây nên lỗi khi chạy phần mềm, vì thế chỉ sử dụng kiểm thử hộp đen là chưa đủ để thỏa mãn tiêu chí độ tin cậy cao. Trong bối cảnh ngành công nghiệp phần mềm hiện nay, kiểm thử hộp trắng cần được tự động hóa hết mức có thể [1]. Nói chung, kiểm thử là một quá trình rất tốn thời gian, công sức và chi phí có thể chiếm 40% – 60% tổng chi phí trong toàn bộ quá trình phát triển phần mềm [2]. Thêm nữa, độ phức tạp mã nguồn của các phần mềm ngày càng tăng khiến khối lượng mã nguồn cần kiểm thử hộp trắng không chỉ tăng lên mà còn khó phân tích hơn rất nhiều. Vì thế, kiểm thử tự động là một giải pháp hiệu quả nhằm giúp kiểm thử viên bớt nhàm chán, giảm thiểu thời gian, công sức và chi phí trong khi vẫn đảm bảo độ tin cậy cao của phần mềm. Ngoài ra, kiểm thử tự động không chỉ có ý nghĩa khi dự án không đủ tài nguyên mà còn trong kiểm thử hồi quy khi phần mềm cần sửa đổi hoặc nâng cấp. Trong phương pháp kiểm thử hộp trắng, kiểm thử viên không chỉ cần hiểu rõ giải thuật mà còn cần có các kỹ năng và kiến thức tốt về ngôn ngữ lập trình viết mã nguồn, nhằm hiểu rõ mã nguồn cần kiểm thử. Hơn nữa, việc áp dụng các kĩ thuật kiểm thử hộp 1 github là nơi lưu trữ mã nguồn trực tuyến rất phổ biến và mạnh mẽ 2 Tiêu chí đánh giá tính phổ biến ngôn ngữ lập trình dựa trên số kết quả tìm kiếm trả về khi truy vấn tên ngôn ngữ lập trình trên các trên mạng nổi tiếng gồm Google, Google Blogs, MSN, Yahoo, Baidu, Wikipedia và Youtube
  • 14. 2 trắng thường tốn thời gian và công sức nhất là khi mã nguồn cần kiểm thử có độ phức tạp cao. Vì vậy, các kĩ thuật kiểm thử hộp trắng chủ yếu được sử dụng cho kiểm thử đơn vị. Kiểm thử hộp trắng có hai kĩ thuật phổ biến là kiểm thử hộp trắng dòng điều khiển và kiểm thử hộp trắng dòng dữ liệu. Kiểm thử hộp trắng dòng dữ liệu là kĩ thuật tìm kiếm lỗi thường hay xuất hiện liên quan đến phép gán và sử dụng các biến trong chương trình. Trong khi đó, kiểm thử hộp trắng dòng điều khiển tập trung kiểm thử tính đúng đắn của các giải thuật sử dụng trong chương trình. Mỗi một kĩ thuật kiểm thử nêu trên đều có thế mạnh riêng và không thể thay thế cho nhau được. Hai kĩ thuật phổ biến trong kiểm thử hộp trắng dòng điều khiển là theo hướng tĩnh và hướng động. Dù là hướng tĩnh hay hướng động, mục đích cuối cùng là làm sao sinh tập ca kiểm thử đủ tốt để kiểm tra tính đúng đắn mã nguồn. Các công cụ kiểm thử hướng động khá phổ biến gồm PathCrawler[11], CAUT3 , CREST4 . Theo cách tiếp cận này, mã nguồn sẽ được bổ sung thêm các câu lệnh mới để lưu vết đường đi khi thực thi một bộ đầu vào. Mỗi một đường đi tương ứng với một hệ ràng buộc, ca kiểm thử tiếp theo được sinh ra bằng cách phủ định hệ ràng buộc đó. Hạn chế thứ nhất, nếu không tìm được ca kiểm thử đầu tiên, hay hệ ràng buộc đầu tiên, quá trình kiểm thử không thể tiếp tục. Hạn chế thứ hai, số bộ kiểm thử sinh ra tương đối lớn (hoặc không xác định) do số lượng hệ ràng buộc phủ định không ít, đặc biệt với vòng lặp có biến lặp lớn hoặc số lần lặp không xác định. Hạn chế thứ ba, thời gian sinh ca kiểm thử lâu hơn do phải thực thi lại mã nguồn nhiều lần trong môi trường chạy. Hạn chế thứ tư, số lượng hệ ràng buộc cần giải khá lớn (đặc biệt mã nguồn có vòng lặp) và tính đa dạng hệ ràng buộc nên chỉ dùng kĩ thuật sinh ngẫu nhiên là không khả thi mà phải sử dụng thêm SMT-Solver. Tuy các công cụ này tận dụng thế mạnh SMT-Solver, tổng chi phí thời gian sinh ca kiểm thử vẫn hơn đáng kể so với kiểm thử tĩnh. Khóa luận này đề xuất cách sinh ca kiểm thử cho một hàm C sử dụng kĩ thuật kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh để giải quyết những hạn chế nêu trên. Tư tưởng chính của phương pháp đề xuất là tập trung phân tích cấu trúc mã nguồn để sinh ca kiểm thử thay vì thực thi mã nguồn lặp lại nhiều lần. Kết quả là thời gian sinh tập ca kiểm thử nhanh hơn do giảm bớt số lần thực thi mã nguồn. Hơn nữa, số lượng ca kiểm thử tối 3 http://www.lab205.org/caut/ 4 https://code.google.com/p/crest/
  • 15. 3 thiểu thay vì khá lớn mà vẫn đảm bảo tính đúng đắn cao của mã nguồn. Ngoài ra, thời gian sinh một ca kiểm thử nhanh hơn do tận dụng thế mạnh công cụ SMT-Solver. Cuối cùng, bởi vì có sự kết hợp kĩ thuật sinh ngẫu nhiên và tận dụng thế mạnh công cụ SMT- Solver nên giải được nhiều dạng hệ ràng buộc khác nhau. Phần còn lại khóa luận được trình bày như sau. Đầu tiên, chương 2 giới thiệu tổng quan và đưa ra sự so sánh về kĩ thuật kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh và hướng động. Tiếp theo, phương pháp đề xuất dựa trên kĩ thuật kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh được trình bày trong chương 3. Sau đó, chương 4 mô tả công cụ triển khai phương pháp đề xuất và thực nghiệm. Cuối cùng, chương 5 trình bày tóm tắt các kết quả đã đạt được, kết luận, những hạn chế và hướng nghiên cứu phát triển trong tương lai.
  • 16. 4 Tổng quan kĩ thuật kiểm thử hộp trắng dòng điều khiểnChương 2. Ở phần này, khóa luận trình bày các kiến thức tổng quan về kiểm thử hộp trắng dòng điều khiển gồm hai kĩ thuật kiểm thử hướng tĩnh và hướng động, đồng thời đưa ra sự so sánh về ưu điểm và nhược điểm của từng kĩ thuật. 2.1. Tổng quan kĩ thuật kiểm thử hộp trắng dòng điều khiển Kiểm thử hộp trắng dòng điều khiển chia ra gồm kiểm thử hướng tĩnh và kiểm thử hướng động. Đầu vào của hai kĩ thuật này đều là mã nguồn và tiêu chí phủ kiểm thử. Sau một loạt quá trình phân tích, đầu ra tương ứng là tập ca kiểm thử. Mỗi một kĩ thuật đều có những ưu điểm và hạn chế riêng. Mục tiêu của kiểm thử hộp trắng dòng điều khiển là tìm tập ca kiểm thử tối thiểu nhưng đạt được độ phủ tối đa. 2.2. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng động Theo kĩ thuật này, mã nguồn sẽ được thêm các đoạn chương trình con trước khi thực thi trong môi trường chạy. Hình 2.1 trình bày quy trình chung của kiểm thử động. Nhìn chung, kĩ thuật này gồm 6 bước cơ bản được diễn giải theo thứ tự dưới đây: Bước 1. Chèn thêm các đoạn mã nguồn mới vào mã nguồn cần kiểm thử. Bước 2. Chọn ngẫu nhiên một tập giá trị đầu vào hợp lệ làm ca kiểm thử đầu tiên. Bước 3. Thực thi chương trình với bộ giá trị vừa tìm được. Nếu không thực thi được, quay lại bước 2 để sinh bộ giá trị khác. Bước 4. Tìm tập các câu lệnh đã được đi qua với bộ giá trị ở bước 3 để xây dựng được hệ ràng buộc tương ứng. Bước 5. Phủ định hệ ràng buộc thu được ở bước 4 để sinh các hệ ràng buộc mới có tác dụng sinh các ca kiểm thử kế tiếp. Nếu không thể sinh hệ phủ định nào khác, thuật toán kết thúc. Bước 6. Giải hệ ràng buộc thu được ở bước 5 để sinh ca kiểm thử kế tiếp. Nếu không có ca kiểm thử nào thỏa mãn, quay về bước 5 để tìm hệ ràng buộc phủ định mới sao cho khác hệ ràng buộc hiện tại. Ngược lại, quay lại bước 3 để sinh ca kiểm thử kế tiếp.
  • 17. 5 Hình 2.1. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng động. Trong bước 1, quá trình chèn thêm khối mã nguồn mới vào mã nguồn cần kiểm thử được tiến hành một cách tự động. Công cụ DMS/SRT5 được đánh giá khá mạnh mẽ để thực hiện pha này. Đoạn mã nguồn thêm vào có chức năng đánh dấu, thoát chương trình hoặc ghi thông tin về quá trình thực thi ra tệp, v.v. Để làm được điều này, chúng tôi cần xây dựng các luật chèn thêm mã nguồn mới vào mã nguồn cần kiểm thử. Với công cụ DMS/SRT, mỗi một luật bắt đầu với từ khóa rule và theo sau là tên đặt cho luật. Từ khóa rewrite to nêu cách biến đổi đoạn mã nguồn gốc về đoạn mã nguồn mới. Kiểu dữ liệu có thể là expression (ứng với biểu thức), statement (ứng với câu lệnh gán hoặc khởi tạo), type (ứng với kiểu dữ liệu), identifier (ứng với định danh như tên biến, tên hàm), v.v. Hình 2.2 mô tả một luật chèn thêm câu lệnh đánh dấu vào khối lệnh điều khiển rẽ nhánh. Cụ thể, biến mảng visited đánh dấu vị trí câu lệnh đi qua được bổ 5 http://www.semanticdesigns.com/Products/DMS/DMSToolkit.html Source code Tiêu chí phủ Pha chèn thêm khối lệnh mới Tìm ca kiểm thử khởi đầu ngẫu nhiên Thực thi ca kiểm thử vừa tìm được Tái tạo đường thực thi Tạo đường thực thi mới Tìm được ca kiểm thử mới TrueFalseKết thúc
  • 18. 6 sung vào mã nguồn ban đầu ngay sau mỗi khối lệnh điều khiển rẽ nhánh. Hình 2.3 đưa ra mã nguồn triangle sau khi áp dụng luật. Hình 2.2: Ví dụ một luật chèn mã nguồn trong DMS/SRT. Hình 2.3. Mã nguồn hàm triangle sau khi thêm khối mã nguồn mới. 2.3. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh Trong kiểm thử tĩnh, mã nguồn không được thực thi trong môi trường chạy để sinh ca kiểm thử. Trong kiểm thử tĩnh, quá trình chạy ca kiểm thử chỉ thực hiện duy nhất một
  • 19. 7 lần với từng ca kiểm thử để tính toán giá trị trả về và đảm bảo ca kiểm thử thực thi không có vấn đề. Các bước tổng quát trong kĩ thuật này được trình bày ở Hình 2.4. Đầu tiên, đồ thị dòng điều khiển được xây dựng dựa trên mã nguồn và tiêu chí phủ kiểm thử. Bước tiếp theo, từ đồ thị dòng điều khiển chúng tôi xây dựng được tập đường kiểm thử. Mỗi một đường kiểm thử trong tập đường kiểm thử mô tả hành vi chương trình với một miền bộ đầu vào nào đó. Sau đó, pha tìm ca kiểm thử thỏa mãn đường kiểm thử được tiến hành. Cuối cùng, ca kiểm thử được thực thi trong môi trường chạy. Hình 2.4. Quy trình chung của kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh. 2.3.1. Các tiêu chí phủ kiểm thử Tiêu chí phủ kiểm thử là một thước đo để đánh giá tính đúng đắn của mã nguồn cần kiểm thử với một tập ca kiểm thử nào đó. Tập ca kiểm thử khiến mã nguồn có độ phủ cao được đánh giá là tốt hơn so với tập ca kiểm thử khác khiến mã nguồn có độ phủ thấp hơn. Chất lượng mã nguồn được đánh giá tỉ lệ thuận với độ phủ. Độ phủ được đánh giá dựa trên hai thông số gồm tiêu chí phủ kiểm thử và tập ca kiểm thử. Công thức tính độ phủ là tỉ lệ các thành phần được kiểm thử trên tổng số các thành phần cần kiểm thử sau khi đã thực hiện tập ca kiểm thử. Thành phần có thể là câu lệnh, điểm quyết định, điều kiện con, đường thi hành hoặc là sự kết hợp của chúng. Source code Tiêu chí phủ Xây dựng đồ thị dòng điều khiển Xây dựng tập đường kiểm thử Tìm tập ca kiểm thử Thực thi tập ca kiểm thử Kết thúc
  • 20. 8 Tiêu chí phủ kiểm thử được giới thiệu lần đầu tiên vào 1963 trong tạp chí hàng tháng “Communications of the ACM”. Cho tới nay, nhiều tiêu chí phủ kiểm thử được đưa ra. Khóa luận sử dụng ba tiêu chí phủ kiểm thử phổ biến để đánh giá chất lượng mã nguồn gồm:  Phủ câu lệnh: Mỗi một câu lệnh được thực thi ít nhất một lần sau khi chạy tập ca kiểm thử.  Phủ nhánh: Mỗi một nhánh đều được đi qua ít nhất một lần sau khi chạy tập ca kiểm thử.  Phủ điều kiện con: Mọi nhánh đúng-sai đều được đi qua với một tập ca kiểm thử nào đó, trong đó các câu lệnh điều kiện kép được phân tách thành các câu lệnh điều kiện đơn. 2.3.2. Đồ thị dòng điều khiển Sinh ca kiểm thử dựa trên mã nguồn phức tạp và khó khăn hơn so với sinh ca kiểm thử dựa trên đồ thị dòng điều khiển (Control Flow Graph – CFG). CFG là một đồ thị có hướng mô tả cấu trúc lôgic của chương trình một cách trực quan và đơn giản hơn, gồm có các đỉnh tương ứng với các câu lệnh/nhóm câu lệnh và các cạnh là các dòng điều khiển giữa các câu lệnh/nhóm câu lệnh. Đỉnh đầu tiên của CFG là trạng thái đầu tiên của hàm, đỉnh cuối cùng của CFG là trạng thái kết thúc của hàm. Đỉnh i nối đến đỉnh j thì câu lệnh tương ứng đỉnh j có thể được thực thi sau khi thực hiện câu lệnh tương ứng ở đỉnh i. Trong ngôn ngữ C, các cấu trúc điều khiển trong CFG gồm tuần tự, rẽ nhánh, while...do, do...while, for. Hình 2.5 minh họa các cấu trúc điều khiển nêu trên. Trong đó đỉnh có nhãn c tượng trưng cho câu lệnh điều kiện. Các đỉnh còn lại tượng trưng câu lệnh gán, khai báo, v.v. Các thành phần cơ bản của đồ thị dòng điều khiển gồm đỉnh xuất phát, đỉnh xử lí, đỉnh quyết định, đỉnh kết nối và đỉnh kết thúc.  Đỉnh xuất phát và đỉnh kết thúc: Hai đỉnh này là duy nhất, trong đó đỉnh xuất phát đại diện cho tên hàm.  Đỉnh quyết định: Là đỉnh tương ứng với câu lệnh điều kiện trong khối lệnh điều khiển rẽ nhánh, do...while, while..do. Ví dụ cụ thể, với khối lệnh điều khiển “if (a > b) { ... }” thì đỉnh quyết định tương ứng với “a > b”.  Đỉnh kết nối: Là đỉnh có nhiều hơn hai đỉnh khác trỏ đến mà không phải đỉnh quyết định.
  • 21. 9  Đỉnh xử lí: Là đỉnh tương ứng với câu lệnh gán, câu lệnh khởi tạo hoặc câu lệnh khai báo và không phải đỉnh kết nối. Các khối lệnh điều khiển cũng chứa các loại câu lệnh này. Ví dụ, khối lệnh “for (i = 0; i < 10; i++)” chứa hai đỉnh xử lí gồm câu lệnh gán “i = 0” và câu lệnh tăng giá trị biến i là “i++”. Hình 2.5: Các cấu trúc điều khiển phổ biến. 2.3.3. Đường kiểm thử Với một bộ giá trị đầu vào, một tập các câu lệnh gán, câu lệnh khai báo và câu lệnh điều kiện được đi qua. Danh sách các câu lệnh này được sắp theo thứ tự thực hiện chính là một đường đi. Trong số tất cả các đường đi có thể, một tập đường đi được chọn sao cho thỏa mãn tiêu chí phủ kiểm thử được gọi là tập đường kiểm thử. Đường kiểm thử là một đường đi từ đỉnh đầu tiên đến đỉnh cuối cùng của CFG được biểu diễn dưới một tập các đỉnh từ đỉnh v1 đến đỉnh vn, trong đó hai đỉnh liền kề có cạnh nối với nhau. Nếu cạnh (vi ,vj) (i j) là nhánh false, câu lệnh lưu ở đỉnh vi được viết phủ định. Tập đường đi độc lập gồm k đường đi PATH1, PATH2, …, PATHk thỏa mãn: giữa mọi cặp đường đi độc lập PATHi và PATHj (i j) không chung ít nhất một cạnh trở lên. Tìm kiếm tập đường kiểm thử là bước trung gian trong quá trình sinh tập ca kiểm thử. Hai vấn đề liên quan đến tập đường kiểm thử rất quan trọng gồm:  Vấn đề thực thi được hay không thực thi được. Một đường kiểm thử gọi là thực thi được nếu tìm kiếm được một ca kiểm thử sao cho khi thực thi trong môi trường thật thì đường kiểm thử nêu trên được đi qua. Ngược lại, đường kiểm thử gọi là không thực thi được.
  • 22. 10  Tính phức tạp mã nguồn. Một mã nguồn gọi là phức tạp nếu chứa nhiều vòng lặp như nhiều vòng lặp lồng nhau hoặc nhiều vòng lặp nối tiếp nhau, kích thước lớn hoặc thuật toán phức tạp. Mã nguồn càng phức tạp càng khiến quá trình tìm kiếm đường kiểm thử trở nên khó khăn hơn và mất thời gian hơn. 2.4. So sánh kĩ thuật kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh và động Mỗi một kĩ thuật kiểm thử đều có những ưu điểm và hạn chế riêng. Để có cái nhìn tổng quan về hai kĩ thuật, chúng tôi đưa ra sự so sánh về số ca kiểm thử, thời gian sinh ca kiểm thử, khả năng kiểm thử vòng lặp, ảnh hưởng bởi phức tạp mã nguồn đối với hai kĩ thuật.  Về số ca kiểm thử. Nhìn chung, với mã nguồn chỉ chứa các câu lệnh rẽ nhánh và không chứa vòng lặp, hai kĩ thuật kiểm thử nêu trên cho số bộ ca kiểm thử như nhau. Tuy nhiên, trong trường hợp có vòng lặp thì kĩ thuật kiểm thử tĩnh đưa ra số ca kiểm thử ít hơn so với kiểm thử động. Theo hướng tĩnh, các đường đi chứa vòng lặp lặp lại một lần sẽ được cấu trúc lại để lặp nhiều hơn một lần. Nói cụ thể hơn, từ một đường kiểm thử chứa vòng lặp ban đầu sẽ sinh ra một tập các đường kiểm thử mới dùng để kiểm thử tính đúng đắn vòng lặp. Nếu vòng lặp trong đường kiểm thử xác định được số lần lặp tối đa thì số đường đi mới sinh ra là bảy. Ngược lại, nếu vòng lặp không xác định số lần lặp tối đa thì số đường đi mới sinh ra là bốn. Với mã nguồn chứa vòng lặp, kiểm thử động sử dụng kĩ thuật phủ định hệ để sinh ca kiểm thử kế tiếp nên số ca kiểm thử có thể rất lớn hoặc không xác định. Cụ thể, trường hợp số ca kiểm thử rất lớn xảy ra khi vòng lặp có cận lặp lớn, ví dụ, khối lệnh điều khiển “for (int i = 0; i < 1000; i++)” có số lần lặp tối đa là 1000 lần. Trường hợp số ca kiểm thử không xác định xảy ra khi số lần lặp không được biết trước như “while (m!=n){...}”, trong đó m và n là hai tham số kiểu nguyên truyền vào hàm. Để giải quyết hai vấn đề này, một vài công cụ kiểm thử như PathCrawler chèn thêm mã nguồn xác định số lần lặp tối đa của mỗi vòng lặp hoặc thêm yêu cầu thời gian chạy. Tuy nhiên, nhìn chung số ca kiểm thử vẫn khá lớn gây khó khăn cho quản lí.  Về thời gian sinh ca kiểm thử. Một cách tổng quan, kiểm thử động thực thi ca kiểm thử lặp lại nhiều lần nên thời gian sinh ca kiểm thử lâu hơn. Một điểm chung là hai kĩ thuật đều có bước giải hệ ràng buộc để sinh ca kiểm thử mới. Thời gian giải hệ
  • 23. 11 chiếm tỉ lệ đáng kể trong tổng thời gian sinh ca kiểm thử. Tuy nhiên, các công cụ có khả năng giải hệ được phát triển khá mạnh mẽ và công bố rộng rãi trong thời gian gần đây nên sự so sánh về thời gian giải hệ có thể bỏ qua.  Về khả năng kiểm thử vòng lặp. Kiểm thử tĩnh hướng đến chỉ kiểm thử một vòng lặp duy nhất tại một thời điểm. Do đó, trong trường hợp có nhiều vòng lặp, chẳng hạn như đường kiểm thử đi qua hai vòng lặp lồng nhau thì quy trình kiểm thử tiến hành với từng vòng lặp riêng và tìm cách phá vỡ cấu trúc lặp các vòng lặp còn lại. Ngược lại, kiểm thử động hướng đến kiểm thử tính đúng đắn của các vòng lặp một cách đồng thời thay vì riêng rẽ. Tư tưởng này mô phỏng quá trình thực thi trong thực tế.  Tính phức tạp mã nguồn. Hiện nay, quy tắc viết mã nguồn rất đa dạng và các quy tắc mới có thể được đưa ra trong các phiên bản trình biên dịch mới. Kiểm thử tĩnh bị hạn chế bởi tính phức tạp mã nguồn. Ví dụ, trường hợp mã nguồn chứa các hàm biến đổi xâu thì kĩ thuật kiểm thử này yêu cầu cần phải xây dựng lại các hàm đó một cách thủ công. Ngược lại, kiểm thử động không bị ảnh hưởng lớn bởi những sự thay đổi này và bởi tính phức tạp mã nguồn. Nguyên nhân chính do kiểm thử động tận dụng thế mạnh trình biên dịch để sinh ca kiểm thử mới. 2.5. Tầm quan trọng của tự động hóa quy trình kiểm thử hộp trắng dòng điều khiển Ba trong số những nguyên nhân chính dẫn đến vấn đề tự động hóa quy trình kiểm thử hộp trắng dòng điều khiển gồm:  Thời gian sinh ca kiểm thử bằng tay khá lâu và dễ dẫn đến sai sót. Nguyên nhân chính phụ thuộc vào trình độ chuyên môn của kiểm thử viên, độ phức tạp mã nguồn và chịu áp lực bởi môi trường làm việc.  Chi phí về nguồn nhân lực cho pha kiểm thử khá tốn kém. Muốn đảm bảo chất lượng phần mềm (đặc biệt với dự án lớn) thì chi phí nguồn nhân lực càng cao. Do đó, vấn đề quản lí khối lượng nguồn nhân lực trở nên phức tạp và rắc rối.  Các thống kê cho thấy chi phí pha kiểm thử có thể chiếm tới 40%-60% tổng chi phí phát triển dự án phần mềm [2]. Các phần mềm hệ thống, phần mềm doanh nghiệp, v.v. đều đòi hỏi chất lượng cao nên pha kiểm thử luôn được chú trọng và không thể bỏ qua. Hơn nữa, mỗi khi phần mềm được nâng cấp thì quá trình kiểm thử được tiến hành lại dẫn đến chi phí đã cao nay càng cao hơn.
  • 24. 12 Phương pháp kiểm thử tự động hàm C sử dụng kĩ thuậtChương 3. kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh Chương này đề xuất phương pháp kiểm thử tự động hàm C sử dụng kĩ thuật kiểm thử kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh. Phương pháp đề xuất cách xây dựng đồ thị dòng điều khiển CFG, sinh tập đường đi độc lập, kĩ thuật kiểm thử tính đúng đắn với hàm đầu vào chứa vòng lặp đơn hoặc hai vòng lặp lồng nhau. Ngoài ra, kĩ thuật SE được mô tả một cách chi tiết nêu cách xây dựng hệ ràng buộc từ một đường thi hành bất kì. Tổng quan về SMT-Solver và kĩ thuật sinh ngẫu nhiên được trình bày để giải hệ ràng buộc sinh ca kiểm thử. 3.1. Tổng quan phương pháp kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh Hình 3.1. Quy trình kiểm thử một hàm C theo phương pháp đề xuất. Khóa luận đề xuất một phương pháp kiểm thử hàm C sử dụng phương pháp kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh và cài đặt công cụ hỗ trợ. Đầu vào của bài Sinh CFG Sinh tập đường đi độc lập Sinh tập đường kiểm thử Sinh đường kiểm thử vòng lặp Sinh hệ ràng buộc Sinh ca kiểm thử Thực thi ca kiểm thử Xuất báo cáo Hàm C Độ phủ SMT-Solver Sinh ngẫu nhiên
  • 25. 13 toán là một tiêu chí phủ kiểm thử và một đơn vị chương trình C chứa các biến số nguyên, số thực và biến mảng. Đầu ra là tập ca kiểm thử thỏa mãn tiêu chí phủ kiểm thử nêu trên. Đề xuất được mô tả khái quát ở Hình 3.1. Đầu tiên, mã nguồn được phân tích để sinh CFG tương ứng với tiêu chí phủ kiểm thử cho trước. Sau đó, chúng tôi xây dựng tập đường đi độc lập từ CFG nêu trên. Tiếp theo, quá trình phân tích tập đường đi độc lập để sinh tập đường kiểm thử thỏa mãn tiêu chí phủ kiểm thử được tiến hành. Ngoài ra, để kiểm thử tính đúng đắn của vòng lặp, các đường kiểm thử mới được xây dựng bằng cách phân tích các đường kiểm thử chứa vòng lặp. Tiếp theo, các đường kiểm thử được phân tích sử dụng kĩ thuật SE để sinh ra hệ ràng buộc. Mỗi hệ ràng buộc được giải bằng cách sử dụng kĩ thuật sinh ngẫu nhiên hoặc sử dụng công cụ SMT-Solver. Nếu sử dụng công cụ SMT-Solver, các hệ ràng buộc sẽ được chuyển đổi về dạng chuẩn SMT-Lib. Sau khi có được ca kiểm thử, quá trình thực thi ca kiểm thử được tiến hành để lấy giá trị trả về của mã nguồn (nếu có) và đảm bảo ca kiểm thử thực thi không lỗi. 3.2. Sinh đồ thị dòng điều khiển từ mã nguồn Hình 3.2. Thuật toán sinh CFG từ mã nguồn.
  • 26. 14 Chi tiết thuật toán sinh đồ thị dòng điều khiển của hàm C thỏa mãn một tiêu chuẩn phủ kiểm thử cho trước được trình bày ở Hình 3.2. Đầu vào thuật toán gồm hàm C được lưu trong biến f và tiêu chí phủ kiểm thử lưu trong biến t. Đầu ra thuật toán là đồ thị dòng điều khiển lưu trong biến graph. Đầu vào cùng một hàm C, CFG ứng với tiêu chí phủ câu lệnh và phủ nhánh giống nhau và đơn giản hơn so với tiêu chí phủ điều kiện con. Bước đầu tiên thuật toán, tập các khối mã nguồn con cấu thành nên f được phân tách và lưu trong biến B (dòng 1). Tiếp theo, đồ thị G được sinh ra thỏa mãn mỗi đỉnh đồ thị G lưu một khối mã nguồn con, các cạnh mô tả thứ tự thực hiện cúa các khối mã nguồn con trong f (dòng 2). Sau đó, đỉnh của graph lưu f được thay thế thành đồ thị G (dòng 3). Nếu đồ thị G tồn tại các đỉnh lưu câu lệnh break, continue và return thì con trỏ mà các đỉnh này trỏ tới đỉnh khác sẽ trỏ lại đến đúng đỉnh khác trong graph (dòng 4, 5). Cuối cùng, những khối mã nguồn con còn khả năng phân tích tiếp ra các khối mã nguồn con khác, hàm đệ quy được gọi (dòng 7, 8, 9). Hình 3.3. Mã nguồn hàm average. Một khối mã nguồn con không cần phân tích tiếp chỉ khi đã thỏa mãn tiêu chuẩn phủ kiểm thử. Cụ thể, với tiêu chuẩn phủ câu lệnh và phủ nhánh, các đỉnh trong CFG lưu câu lệnh đơn và điều kiện trong các khối lệnh điều khiển. Tuy nhiên, điều kiện của khối
  • 27. 15 lệnh điều khiển có thể do một điều kiện hoặc nhiều điều kiện đơn hợp thành. Nếu phân tách tiếp các điều kiện khối lệnh điều khiển thành đồ thị mà các đỉnh là điều kiện đơn và các cạnh là nhánh true/false thì sinh ra CFG thỏa mãn tiêu chuẩn phủ điều kiện con. Ví dụ cụ thể, Hình 3.4 đưa ra đồ thị CFG tương ứng với hàm average trình bày ở Hình 3.3 thỏa mãn tiêu chí phủ câu lệnh và phủ nhánh. Phân tích hàm average thu được tập khối mã nguồn con gồm 4 khối : khối while, khối if, lệnh return và câu lệnh khai báo dòng 2. Bốn khối này được liên kết với nhau theo dạng danh sách liên kết. Tiếp tục, khối while được phân tích tiếp thu được điều kiện kép (value[i]!=-2&&tcnt<2) và khối lệnh khi thỏa mãn điều kiện. Khối if phân tích tương tự khối while. Lệnh return, câu lệnh khai báo và điều kiện kép không cần phân tích tiếp. Sau đó, khối lệnh trong while được phân tích tiếp và quá trình này cứ lặp lại như thế. Hình 3.4. CFG hàm average tiêu chuẩn phủ câu lệnh, phủ nhánh. Ví dụ tiếp theo, trường hợp phủ điều kiện con, điều kiện kép (a>=0 || ((b>=0 && c>=0) || b+c>=0) || a+b+c>=0) phân tích thành đồ thị tương ứng mô tả ở Hình 3.5. Điều kiện kép nêu trên do ba điều kiện con hợp thành là a>=0, (b>=0 && c>=0) || F F F T T T Bắt đầu hàm min <= value[i] && value[i] <= max vcnt < 0tcnt++ value[i] != -2 && tcnt < 2 int tcnt = vcnt = sum = i = 0 return -9 return sum/vcnt sum += value[i] vcnt++ i++ Kết thúc hàm T
  • 28. 16 b+c>=0 và a+b+c>=0. Điều kiện a>=0 và a+b+c>=0 không cần phân tích tiếp vì thỏa mãn điều kiện đơn. Trong khi đó, điều lệnh kép (b>=0 && c>=0) || b+c>=0 sẽ được phân tích tiếp thành 2 điều kiện con: (b>=0 && c>=0) và b+c>=0. Quá trình phân tích cứ lặp lại như thế cho đến khi mọi điều kiện con này đều là các điều kiện đơn. Cuối cùng, đồ thị ứng với điều kiện kép cần phân tích sẽ cập nhật trong đồ thị CFG kết quả. Hình 3.5. CFG điều kiện kép (a>=0 || ((b>=0 && c>=0) || b+c>=0) || a+b+c>=0). 3.3. Xây dựng tập đường kiểm thử từ đồ thị dòng điều khiển 3.3.1. Xây dựng tập đường đi độc lập Hình 3.6 mô tả thuật toán sinh tập đường đi độc lập dựa trên ý tưởng sinh tập đường đi độc lập do MC-Cabe đề xuất nêu trong [8]. Đầu vào thuật toán là CFG được lưu bởi biến graph, đầu ra là tập đường đi độc lập P. Bước đầu tiên, quá trình tìm đường đi ngắn nhất shortestPath được tiến hành bằng cách duyệt đồ thị graph theo nhánh false (dòng 1), sau đó lưu shortestPath vào tập đường đi độc lập (dòng 2). Tiếp theo, các đỉnh quyết định trên shortestPath được thêm vào tập S (dòng 3), biến visited dùng lưu các đỉnh quyết định đã duyệt cả hai nhánh đúng-sai được khởi tạo bằng rỗng (dòng 4). Vòng lặp while lặp lại đến khi hai nhánh đúng-sai của mọi đỉnh quyết định tồn tại trong tập đường đi độc lập (dòng 5). Trong vòng while, một đỉnh bất kì u trong tập S được lấy ra (dòng 6) và tìm cạnh (u,v) chưa tồn tại trong tập đường đi độc lập (dòng 7). Từ cặp cạnh này, chúng tôi tìm đường đi ngắn nhất nextPath đi qua cặp cạnh (u,v) để thêm vào tập đường đi độc lập (dòng 8). Tập S được cập nhật bằng cách thêm vào các đỉnh không thuộc tập visited trên F F F F T T T T a+b+c >= 0 b+c >= 0c >= 0 b >= 0 a >= 0 Khối lệnh khi thỏa mãn T
  • 29. 17 đường đi nextPath (dòng 10) và xóa đỉnh u (dòng 11). Cuối cùng, đỉnh u được lưu vào tập visited (dòng 12). Hình 3.6. Thuật toán sinh tập đường đi độc lập từ CFG. 3.3.2. Xây dựng đường kiểm thử vòng lặp Trong thực tế, đa phần các hàm C chứa vòng lặp nên tầm quan trọng của kiểm thử tính đúng đắn vòng lặp là tất yếu. Các đường đi sinh từ CFG chỉ có thể kiểm thử vòng lặp tối đa 1 lần nên chưa đảm bảo tính đúng đắn vòng lặp. Vì thế, khóa luận này đề xuất cách sinh ca kiểm thử cho hàm C chứa hai loại vòng lặp: vòng lặp đơn và hai vòng lặp lồng nhau. Tư tưởng chung của phương pháp đề xuất là viết lại đường đi chứa vòng lặp để tạo đường đi mới lặp nhiều hơn 1 lần, sau đó sinh ca kiểm thử từ đường đi mới đó. Ba loại đường đi trong tập đường đi độc lập được kiểm thử vòng lặp gồm:
  • 30. 18  Đường đi chứa vòng lặp. Nằm trong tập đường đi độc lập có chứa vòng lặp. Câu lệnh ứng với đỉnh quyết định đi vào vòng lặp và thoát khỏi vòng lặp đó là phủ định của nhau.  Đường đi chứa vòng lặp đơn. Là đường đi có đúng một vòng lặp. Đường đi này chỉ có một đỉnh duy nhất đi vào vòng lặp và thoát khỏi vòng lặp.  Đường đi chứa vòng lặp lồng nhau. Là đường đi có hai vòng lặp: một vòng lặp bên trong và một vòng lặp bên ngoài. Đường đi loại này có hai đỉnh đặc biệt: một đỉnh đi vào và thoát khỏi vòng lặp bên trong, đỉnh còn lại đi vào và thoát khỏi vòng lặp bên ngoài. 3.3.2.1. Kiểm thử đường đi chứa vòng lặp đơn Đường đi chứa vòng lặp đơn được viết lại để tạo đường đi mới bằng cách sao chép vòng lặp một số lần cụ thể. Nếu vòng lặp đơn biết số lần lặp tối đa bằng n thì số lần lặp là 0, 1, 2, một số ngẫu nhiên lần, n - 1, n và n + 1 lần. Ngược lại, nếu không biết số lần lặp tối đa của vòng lặp đơn, số lần lặp là 0, 1, 2 và một số ngẫu nhiên lần. Hình 3.7 trình bày các bước tạo đường đi mới với đầu vào là đường đi chứa vòng lặp đơn lưu trong biến PATH, số lần lặp lưu trong biến n; đầu ra là đường đi mới với vòng lặp đơn được lặp lại n lần. Đầu tiên, đỉnh điều kiện của vòng lặp đơn được gán cho biến v (dòng 1). Sau đó, khối lặp vòng lặp khoi_lap được tìm ra (dòng 2). Tiếp theo, khối lặp khoi_lap được nhân bản n lần để tạo đường đi mới và lưu trong biến duong_di_moi (dòng 3). Cuối cùng, nội dung khối lặp đơn trong đường đi PATH được thay thế với nội dung khoi_lap_moi (dòng 4). Hình 3.7. Thuật toán sinh đường kiểm thử vòng lặp.
  • 31. 19 3.3.2.2. Kiểm thử đường đi chứa hai vòng lặp lồng nhau Đường đi chứa hai vòng lặp lồng nhau có hai điểm quyết định để đi vào vòng lặp và được kiểm thử qua hai bước. Đường đi mới được sinh ra trong mỗi bước. Bước 1 là bước kiểm thử vòng lặp bên trong bằng cách phá vỡ cấu trúc vòng lặp bên ngoài. Bước 2 là bước kiểm thử vòng lặp bên ngoài bằng cách phá vỡ cấu trúc lặp vòng lặp bên trong. Hình 3.8. Thuật toán sinh đường kiểm thử vòng lặp trong. Trong bước 1, quá trình sinh đường đi mới với đầu vào gồm đường đi chứa hai vòng lặp lồng nhau lưu trong biến PATH, số lần lặp của vòng lặp bên trong lưu trong biến n được trình bày trong Hình 3.8. Đầu ra là đường đi chứa vòng lặp trong lặp lại n lần và cấu trúc vòng lặp ngoài bị phá vỡ. Đầu tiên, đỉnh quyết định để đi vào vòng lặp bên ngoài được lưu trong biến u (dòng 1), đỉnh quyết định để thoát khỏi vòng lặp ngoài lưu trong biến v (dòng 2). Sau đó, biến lặp vòng lặp bên ngoài được lưu trong biến i (dòng 3) và tạo một đỉnh mới lưu trong biến dinh_moi lưu lại phép gán này (dòng 4). Để phá vỡ cấu trúc lặp vòng lặp ngoài, đỉnh v sẽ được loại bỏ khỏi đường đi PATH (dòng 5) và chèn thêm đỉnh dinh_moi ngay sau đỉnh u (dòng 6). Đường đi PATH được viết lại để tạo đường đi mới với số lần lặp vòng lặp bên trong bằng n lần (dòng 7).
  • 32. 20 Bước 2 mô tả trong Hình 3.9. Đầu vào thuật toán là đường đi cần viết lại lưu trong biến PATH và số lần lặp vòng lặp ngoài lưu trong biến n, đầu ra là đường đi mới. Bước đầu tiên, tìm đỉnh quyết định u thoát khỏi vòng lặp bên trong (dòng 1). Tiếp theo, loại bỏ đỉnh u khỏi đường đi để phá vỡ cấu trúc lặp vòng lặp trong (dòng 2). Sau bước này, đường đi chỉ còn duy nhất vòng lặp ngoài. Cuối cùng, vòng lặp ngoài được nhân bản lên n lần để tạo ra đường đi mới (dòng 3). Hình 3.9. Thuật toán sinh đường kiểm thử vòng lặp ngoài. 3.4. Sinh tập dữ liệu kiểm thử từ tập đường kiểm thử 3.4.1. Xây dựng hệ ràng buộc Hệ ràng buộc được sinh ra bằng cách phân tích đường đi sử dụng kĩ thuật SE [9]. Trong kĩ thuật SE, giá trị của biến là các giá trị tượng trưng mà không phải giá trị cụ thể, có thể là số nguyên, số thực hoặc biểu thức. Đầu vào của bước xây dựng hệ ràng buộc là một đường kiểm thử, đầu ra là một hệ ràng buộc. Tất cả các nghiệm thỏa mãn hệ ràng buộc này đều đảm bảo đường đi này sẽ được thực thi khi chạy trong môi trường chạy. Biến trong hệ ràng buộc là biến truyền vào hàm, một vài trường hợp phức tạp có thêm biến mảng. Số câu lệnh điều kiện trên đường đi bằng số biểu thức lôgic trong hệ ràng buộc tương ứng. Một đường đi gọi là thực thi được nếu hệ ràng buộc tương ứng có nghiệm và ngược lại. Hình 3.10 mô tả một hệ ràng buộc sinh từ một đường kiểm thử nào đó.
  • 33. 21 { Hình 3.10. Ví dụ một hệ ràng buộc. Hình 3.11. Thuật toán sinh hệ ràng buộc từ đường kiểm thử. Hình 3.11 trình bày cách sinh hệ ràng buộc từ đường đi. Đầu vào thuật toán là một đường đi từ đỉnh đầu tiên đến đỉnh cuối cùng của CFG, đầu ra là hệ ràng buộc tương ứng. Đầu tiên, tập các đỉnh trên đường đi được lưu trong biến V (dòng 1). Sau đó, bảng lưu thông tin các biến bang_bien và tập lưu hệ ràng buộc he_rang_buoc được khởi tạo (dòng 2, 3). Trong vòng for, câu lệnh được rút gọn bằng cách thay thế biến với giá trị của biến đó (dòng 5). Tiếp theo, nếu v là câu lệnh khởi tạo, biến mới được sinh ra và gán giá trị mặc định là chữ cái viết hoa tên biến đó nếu biến đó không được tạo giá trị khởi đầu
  • 34. 22 (dòng 6). Nếu v là câu lệnh gán, giá trị biến được cập nhật trong bang_bien (dòng 12). Nếu v là câu lệnh điều kiện thì lưu lại vào hệ ràng buộc (dòng 15). Thuật toán kết thúc khi mọi đỉnh trên đường đi đều được phân tích. Hình 3.12 trình bày chi tiết các bước trong pha rút gọn. Đầu tiên, các biến thường trong câu lệnh được thay thế với giá trị biến đó. Bước tiếp theo, các chỉ số mảng dạng biểu thức được tính toán thành các giá trị cụ thể. Sau đó, các biến mảng được thay thế với giá trị cụ thể. Quá trình rút gọn này lặp lại với một số lần cho trước. Hình 3.12. Quá trình rút gọn câu lệnh. 3.4.2. Tìm nghiệm thỏa mãn hệ ràng buộc Cho tới nay, vấn đề tìm nghiệm thỏa mãn hệ ràng buộc một cách hiệu quả là một bài toán khó và thách thức. Yêu cầu giải hệ tìm nghiệm trong thời gian nhanh nhất có thể ngày càng gia tăng trong các bài toán khoa học kĩ thuật. Với các công cụ sinh ca kiểm thử tự động, nhu cầu giải hệ trong thời gian thực là tất yếu và là một vấn đề mang tính cấp bách. Vì vậy, khóa luận này trình bày hai cách tiếp cận để tìm nghiệm thỏa mãn hệ ràng buộc gồm: tận dụng sức mạnh các công cụ SMT-Solver hiện nay như raSAT, Alt-Ergo, Boolector, SmtInterpol, v.v. và kĩ thuật sinh ngẫu nhiên. 3.4.2.1. Giải hệ sử dụng kĩ thuật sinh ngẫu nhiên Kĩ thuật sinh ngẫu nhiên là một kĩ thuật truyền thống để giải hệ ràng buộc. Trong kĩ thuật này, tập giá trị các biến sẽ được sinh ngẫu nhiên trong một khoảng cho trước, trong một khoảng thời gian cho trước, với một số lần sinh xác định. Với những hệ ràng buộc có tính chất đặc biệt như nhiều biểu thức logic, biểu thức logic đặc biệt (ví dụ a==2) hay bản thân mỗi biểu thức logic phức tạp thì kĩ thuật sinh ngẫu nhiên dễ dàng thể hiện điểm yếu về thời gian. Thay thế biến thường Rút gọn chỉ số mảng Thay thế biến mảng Lặp N lần cho trước OutputInput
  • 35. 23 3.4.2.2. Giải hệ sử dụng SMT-Solver Trong toán học mệnh đề, một câu của logic vị từ là một biểu thức luận lý theo dạng chuẩn mà không có biến tự do xuất hiện trong biểu thức đó. Biến tự do là một kí hiệu xác định những vị trí cụ thể trong một biểu thức mà tại vị trí đó, xảy ra sự thay thế biến với một giá trị nào đó. Biến tự do không có giá trị cụ thể và cận cụ thể. Nếu một biến tự do mang giá trị nằm trong một cận xác định, thì nó được gọi là biến biên. Ví dụ cụ thể, trong biểu thức ∑ , biến tự do là n, biến biên là k vì k có cận [1, 10]. Lí do chính khiến câu không mang biến tự do là do câu cần một giá trị cụ thể, thay vì giá trị không xác định. Cụ thể, giá trị của câu có thể là đúng hoặc sai. Tập các câu hợp chính là một lý thuyết, khi đó bản thân mỗi câu nếu đứng độc lập chính là định lý. Để đánh giá tính đúng-sai của một câu, câu được tham chiếu đến một thể hiện của lý thuyết (interpretation of the theory). Với lý thuyết logic vị từ, các thể hiện thường được gọi là các cấu trúc. Một lý thuyết được coi là thỏa mãn khi tất cả mọi câu tạo nên lý thuyết đó đều đúng. Việc nghiên cứu các thuật toán để tìm ra các thể hiện của lý thuyết một cách tự động sao cho mọi câu trong lý thuyết đều mang giá trị đúng được gọi là vấn đề SMT. Trong khoa học máy tính và toán học mệnh đề, vấn đề SMT (lý thuyết modul thỏa mãn) là một vấn đề NP (nondeterministic polynomial time) với các biểu thức logic được tạo thành từ sự kết hợp các nền tảng lý thuyết cơ bản. Ví dụ cụ thể, các lý thuyết điển hình sử dụng trong khoa học máy tính gồm lý thuyết về số nguyên, số thực; lý thuyết về các kiểu dữ liệu có cấu trúc như list, array, bit vectors (hay bit array), v.v. Vấn đề SMT có thể được coi là một dạng của vấn đề thỏa mãn ràng buộc (constraint satisfaction problem). Chú ý thêm rằng, vấn đề SMT là mở rộng của vấn đề SAT (Boolean satisfiability problem). Vấn đề SAT là làm sao xác định được một thể hiện (hay nghiệm) sao cho thỏa mãn biểu thức luận lý đã cho. Trong vấn đề SAT, giá trị một biến chỉ có thể là true hoặc false. Ví dụ, biểu thức luận lý a and not b có một thể hiện thỏa mãn là a = true, b = false vì thỏa mãn a and not b = true. Vấn đề SAT là một trong những vấn đề đầu tiên được chứng minh là vấn đề NP. Để giải vấn đề SMT, hay nói cụ thể hơn là giải các biểu thức logic, các công cụ giải SMT-Solver được ra đời. Hình 3.13 mô tả đầu vào, đầu ra của các công cụ SMT-Solver. Đầu vào là hệ cần tìm nghiệm thỏa mãn được viết theo dạng chuẩn đầu vào của công cụ
  • 36. 24 đó. Đầu ra là nghiệm thỏa mãn trong trường hợp SAT hoặc vô nghiệm trong trường hợp UNSAT. Hình 3.13. Mô tả đầu vào, đầu ra SMT-Solver. Hiện nay, nhiều công cụ SMT-Solver không những giải được lý thuyết tuyến tính mà còn giải được lý thuyết phi tuyến tính. Ví dụ, tìm nghiệm của với x , y R. Đa phần các công cụ SMT-Solver hiện nay đều đưa SAT-Solver vào bộ giải của mình. Cụ thể, trong pha tiền xử lí, biểu thức đầu vào cho công cụ SMT- Solver được chuyển về dạng biểu thức luận lý tương đương mà có thể giải được bằng các công cụ SAT-Solver. Mặt khác, vì pha tiền xử lí này có một hạn chế là làm mất tầng ngữ nghĩa mức cao mà biểu thức gốc chứa, nên SAT-Solver sẽ phải làm việc tốn kém hơn trong trường hợp biểu thức gốc chứa những sự thật hiển nhiên. Ví dụ, biểu thức x+y = y+x với x, y Z. Cho đến nay, hạn chế nêu trên được giải quyết trong T-Solver. Ba chuẩn đầu vào các công cụ SMT-Solver phổ biến gồm SMT-Lib, CVC6 và DIMACS7 . Trong đó, chuẩn SMT-Lib là chuẩn sử dụng rộng rãi nhất. Hình 3.14 trình bày một hệ ràng buộc tuân theo chuẩn SMT-Lib. Cụ thể, theo sau từ khóa set-logic là ký hiệu lý thuyết cơ bản sẽ sử dụng trong SMT-Solver. Bốn lý thuyết cơ bản sử dụng gồm:  QF_LRA : toán học số thực tuyến tính định lượng tự do (quantifier-free linear real arithmetic)  QF_LIA : toán học số nguyên tuyến tính định lượng tự do (quantifier-free linear integer arithmetic  QF_RDL : lôgic hiệu số số thực định lượng tự do (quantifier-free real difference logic)  QF_IDL : lôgic hiệu số số nguyên định lượng tự do (quantifier-free integer difference logic) 6 http://cvc4.cs.nyu.edu/ 7 http://www.satcompetition.org/2009/format-benchmarks2009.html
  • 37. 25 Trong đó, khóa luận đề xuất sử dụng hai lý thuyết QF_LRA và QF_LIA để giải hệ ràng buộc số nguyên và số thực. Các biến được khai báo với từ khóa declare-fun và theo sau là kiểu biến (Int hoặc Real). Theo sau assert(! chính là các biểu thức trong hệ ràng buộc đã được biến đổi về chuẩn biểu thức trong SMT-Lib. Ví dụ Hình 3.14 nêu đầu vào chuẩn SMT-Lib tương ứng với ví dụ nêu ở Hình 3.10. Trong đó biểu thức not(= a 0) tương ứng với biểu thức !(a == 0), biểu thức or (= (- b 2 ) b ) (and (= c d ) (= (- b 2 ) 0) tương ứng với biểu thức (b-2==b) or (c==d and b-2==0). Tên của mỗi biểu thức được đặt ngay sau biểu thức với từ khóa named (IP0, IP1, v.v). Quá trình giải hệ bắt đầu với từ khóa check-sat. Từ khóa print-success được gán giá trị false ám chỉ thông báo thành công sẽ không được hiển thị sau khi lệnh hoàn thành. Hình 3.14. Ví dụ hệ ràng buộc tuân theo chuẩn SMT-Lib. Để tìm nghiệm thỏa mãn hệ ràng buộc bằng cách sử dụng SMT-Solver, bước đầu tiên cần biến đổi hệ ràng buộc này về chuẩn SMT-Lib. Quy trình biến đổi hệ ràng buộc về chuẩn SMT-Lib trình bày ở Hình 3.15. Đầu tiên, biểu thức lôgic trong hệ ràng buộc được chuyển thành biểu thức hậu tố. Sau đó, cây biểu thức tương ứng với biểu thức hậu tố được xây dựng. Cuối cùng, cây biểu thức được duyệt sử dụng các thuật toán kinh điển trong lý thuyết đồ thị để sinh ra biểu thức thỏa mãn chuẩn SMT-Lib. Hình 3.15. Quá trình chuyển một biểu thức trung tố về chuẩn SMT-Lib. Biểu thức lôgic Biểu thức hậu tố Cây biểu thức Biểu thức chuẩn SMT-Lib
  • 38. 26 Thuật toán 7 trình bày quá trình chuyển biểu thức trung tố về biểu thức hậu tố. Biểu thức trung tố chỉ chứa biến, số và các toán tử mà không chứa các hàm toán học. Kĩ thuật biến đổi biểu thức trung tố về biểu thức hậu tố không còn xa lạ với những biểu thức tính toán chỉ gồm các phép toán cộng - trừ - nhân - chia, tuy nhiên trong thực tế biểu thức phức tạp hơn nhiều bởi chứa thêm phép so sánh, phép phủ định, phép tuyển và phép hội. Vì thế, khóa luận xây dựng lại bảng độ ưu tiên các toán tử để giải quyết vấn đề này. Cụ thể, Bảng 1 đề xuất độ ưu tiên các toán tử, trong đó độ ưu tiên nhỏ nhất bằng (-2) và độ ưu tiên lớn nhất bằng 3. Bảng 1. Độ ưu tiên các toán tử Toán tử Độ ưu tiên Mở ngoặc, đóng ngoặc -2 (nhỏ nhất) Phép tuyển, phép hội -1 Phép so sánh 0 Cộng, trừ 1 Nhân, chia, lấy phần dư 2 Phép phủ định 3 Trong thuật toán 7 ở Hình 3.16, hàm pop trả về phần tử đầu tiên trên đỉnh stack, hàm push đẩy phần tử mới vào stack và hàm peek tương tự hàm pop nhưng kích thước stack không thay đổi. Hàm do_uu_tien trả về độ ưu tiên toán tử. Đầu tiên, biến stack và tập_toán_tử được khởi tạo (dòng 1, 2). Trong vòng for, nếu phần tử item xuất hiện trong tập_toán_tử thì các phần tử trong stack được xuất ra cho đến khi phần tử trên đỉnh stack có độ ưu tiên thấp hơn item hoặc stack bằng rỗng (dòng 5, 6). Nếu phần tử item là phép mở ngoặc, item được lưu vào stack (dòng 9). Nếu phần tử item là kí tự đóng ngoặc, các phần tử trong stack xuất ra cho đến khi gặp kí tự mở ngoặc (dòng 11), sau đó loại bỏ kí tự mở ngoặc khỏi stack (dòng 15). Ngược lại, nếu item là biến hoặc số thì bieu_thuc_hau_to được cập nhật ngay lập tức (dòng 17). Cuối cùng, bieu_thuc_hau_to được chuẩn hóa bằng cách thay thế các phần tử trong biểu thức với cách thể hiện tương ứng theo chuẩn SMT- Lib (dòng 20). Cụ thể, theo chuẩn SMT-Lib cách thể hiện biến mảng theo ngôn ngữ lập trình C không cho phép nên được viết lại đơn giản hơn. Ví dụ, biến mảng a[1] thay thế
  • 39. 27 thành a_1_, phép phủ định thay thế thành “not”, phép lấy dư (%) thay thế thành “mod”, phép hội thay thế thành “and”, v.v. Hình 3.16. Thuật toán xây dựng biểu thức hậu tố. Thuật toán 8 ở Hình 3.17 trình bày quy trình chuyển biểu thức hậu tố về cây biểu thức. Mỗi một đỉnh NodeTree của cây biểu thức gồm có con trái, con phải và lưu trữ một phần tử của biểu thức hậu tố. Đầu tiên, biến Stack và tap_toan_tu được khởi tạo (dòng 1, 2). Nếu item xuất hiện trong tap_toan_tu, hai phần tử trên đỉnh Stack được lấy làm con trái và con phải của đỉnh parent, trong đó đỉnh parent là NodeTree lưu item. Biến parent
  • 40. 28 được lưu vào Stack và sẽ là con trái hoặc con phải của một đỉnh nào đó trong các lần duyệt tiếp theo (dòng 4 - 8). Ngược lại, nếu item không xuất hiện trong tap_toan_tu thì một NodeTree mới được tạo ra và lưu vào Stack (dòng 10, 11). Thuật toán kết thúc khi mọi phần tử trong biểu thức hậu tố đều được duyệt. Hình 3.17. Thuật toán xây dựng cây biểu thức từ biểu thức hậu tố. Thuật toán 9 ở Hình 3.18 trình bày thứ tự duyệt cây biểu thức để sinh ra biểu thức thỏa mãn chuấn SMT-Lib. Đầu vào là gốc cây biểu thức, đầu ra là biểu thức chuẩn SMT - Lib được lưu ở biến toàn cục Bieu_thuc_chuan_smt_lib. Nút cha luôn được duyệt trước, sau đó duyệt đến con trái và con phải. Nếu nội dung node xuất hiện trong tap_toan_tu (dòng 3), nội dung node được thêm vào cuối xâu Bieu_thuc_chuan_smt_lib (dòng 4), sau đó mới duyệt con trái và con phải (dòng 5, 6). Nếu node là nút lá, nội dung node được thêm vào cuối xâu Bieu_thuc_chuan_smt_lib (dòng 8). Tiếp theo, nếu node là con phải của một đỉnh NodeTree nào đó thì dấu ngoặc thêm vào cuối xâu Bieu_thuc_chuan_smt_lib (dòng 8). Thuật toán kết thúc khi cây duyệt xong toàn bộ.
  • 41. 29 Hình 3.18. Thuật toán duyệt cây biểu thức. Ví dụ cụ thể, xét biểu thức trung tố “!(1*x>=y[2])||x>(-3)||!(1>a &&a>b[1][1])”. Đầu tiên, sử dụng thuật toán 7 để chuyển biểu thức trung tố nêu trên thành biểu thức hậu tố. Đầu ra của thuật toán 7 là biểu thức hậu tố “1 x * y_2_ >= not x (-3) > or 1 a > a b_1__1_ > and not or”, trong đó b_1__1_ đại diện cho biến mảng b[1][1]. Bước tiếp theo, sử dụng thuật toán 8 phân tích biểu thức hậu tố nêu trên để tạo cây biểu thức. Cuối cùng, phân tích cây biểu thức sử dụng thuật toán 9 thu được biểu thức chuẩn SMT-Lib là “(or (or (not (>= (* 1 x ) y_2_ ) ) (> x (- 3) ) ) (not (and (> 1 a ) (> a b_1__1_ ) ) ) )”. 3.4.2.3. So sánh ưu điểm, nhược điểm của hai hướng sinh ca kiểm thử Trong thực tế, mỗi một công cụ SMT-Solver chỉ chấp nhận hệ ràng buộc thỏa mãn một vài tiêu chí nhất định. Hơn nữa, mỗi một công cụ SMT-Solver chỉ tương thích với một vài môi trường. Ngoài ra, hầu hết SMT-Solver đều có giao diện với một hoặc một vài ngôn ngữ lập trình. Ví dụ, ABsolver8 chỉ chạy trên Linux hỗ trợ giải hệ tuyến tính và phi 8 http://absolver.sourceforge.net/
  • 42. 30 tuyến tính; MiniSmt9 chạy trên cả Linux hỗ trợ giải hệ phi tuyến tính; SmtInterpol chạy trên Linux, Window và Mac giải hệ số nguyên tuyến tính, số thực tuyến tính và biểu tượng hàm (function symbol hoặc uninterpreted function), v.v. Ngược lại, giải hệ bằng kĩ thuật sinh ngẫu nhiên tuy mang tính may rủi nhưng có thể giải được hệ ràng buộc theo nhiều dạng khác nhau. Các biểu thức trong hệ ràng buộc có thể là biểu thức logic đơn giản đến phức tạp, có các hàm toán học như sin, cos, sqrt, v.v. Ưu điểm SMT-Solver là giải hệ ràng buộc rất nhanh và hiệu quả nhưng chỉ áp dụng được với một số loại hệ. Rõ ràng, những hệ có thể giải bằng SMT-Solver thì không nên giải bằng kĩ thuật sinh ngẫu nhiên. Những hệ không thể giải bằng SMT-Solver thì dùng kĩ thuật sinh ngẫu nhiên thay thế. Hai kĩ thuật được kết hợp với nhau với mục đích lấy ưu điểm kĩ thuật này bù nhược điểm kĩ thuật kia và ngược lại. 9 http://cl-informatik.uibk.ac.at/software/minismt/
  • 43. 31 Thực nghiệmChương 4. 4.1. Các thư viện hỗ trợ 4.1.1. Giới thiệu về thư viện SMT-Solver SmtInterpol Thư viện SmtInterpol [12] được viết bằng ngôn ngữ Java. Thư viện này chấp nhận đầu vào thỏa mãn chuẩn SMT-Lib và giải hệ ràng buộc số nguyên tuyến tính, số thực tuyến tính, hàm tượng trưng (function symbol hay uninterpreted function). Hai cách sử dụng SmtInterpol gồm sử dụng API và qua môi trường dòng lệnh cmd. Giao diện gọi thư viện SmtInterpol qua dòng lệnh như sau, trong đó hệ ràng buộc được lưu trong tệp contraintEquations.smt2 đặt tại ổ C. String cmd = "java -jar C:/smtinterpol.jar C:/contraintEquations.smt2"; Process p = Runtime.getRuntime().exec(cmd); 4.1.2. Giới thiệu về thư viện CDT CDT10 là một bộ phân tích cấu trúc xử lý mã nguồn ngôn ngữ C/C++ để lấy cây AST. Cây AST là một cách biểu diễn cấu trúc mã nguồn dưới dạng một tập các đỉnh và liên kết giữa các đỉnh. Mỗi một đỉnh tương ứng với một thành phần trong mã nguồn như câu lệnh gán, khối lệnh điều kiện, biến, phép toán, v.v. Ví dụ, đỉnh IASTDeclSpecifier tương ứng với kiểu trả về của hàm hay kiểu biến. Đỉnh IASTBinaryExpression tương ứng với dấu phép toán. Đỉnh IASTName đại diện tên biến, tên hàm. IASTReturnStatement chính là câu lệnh return. Hình 4.1 minh họa cây AST tương ứng với câu lệnh return x*3. Tùy vào yêu cầu phân tích mà độ sâu cây AST là khác nhau. Ở cấp độ xây dựng CFG từ mã nguồn thì cần phân tích đến khi mỗi một đỉnh trong AST tương ứng với câu lệnh gán/khởi tạo/điều kiện là đủ, thay vì phân tích sâu hơn đến mức biến/toán tử/tên hàm/... Trong thử nghiệm nêu ra ở [4], thời gian xây dựng cây AST từ mã nguồn có độ dài 25 000 dòng trên máy tính chạy Java 32 bit là 0.40 giây. CDT được coi là một trong những bộ phân tích cấu trúc mã nguồn C hiệu quả nhất và được sử dụng rộng rãi. 10 http://eclipse.org/cdt/
  • 44. 32 Hình 4.1. Minh họa cây AST ứng với mã nguồn return x*3 . 4.1.3. Giới thiệu về thư viện Jeval Jeval11 là một thư viện mã nguồn mở mạnh mẽ dùng tính toán giá trị biểu thức. Đầu vào của Jeval là một biểu thức logic và tập giá trị các biến trong biểu thức đó. Đầu ra là giá trị luận lý đúng/sai. Các hàm toán học với số nguyên và số thực, hàm kiểu xâu và biểu thức luận lý được tối ưu hóa với hiệu suất cao. Ngoài ra, Jeval hỗ trợ gần như đầy đủ các phép toán sử dụng trong lập trình C gồm phép so sánh, phép phủ định, phép tuyển, phép hội, phép lấy phần dư và các phép toán học cơ bản. Như vậy, sử dụng thư viện Jeval là một giải pháp hiệu quả đối với kĩ thuật sinh ngẫu nhiên để giải hệ ràng buộc. 4.2. Giới thiệu công cụ kiểm thử tự động hàm C 4.2.1. Tổng quan về công cụ CFT4CUnit CFT4CUnit được xây dựng theo phương pháp đề xuất nêu trong chương 3. Công cụ sử dụng thư viện SmtInterpol kết hợp với kĩ thuật sinh ngẫu nhiên để giải hệ ràng buộc sinh ca kiểm thử. Với kĩ thuật sinh ngẫu nhiên, người dùng cần xác định cận lặp [a,b] và số lần sinh ngẫu nhiên. Công cụ cung cấp khả năng xuất kết quả kiểm thử ra tệp excel. Công cụ được xây dựng bằng ngôn ngữ Java sử dụng các thư viện hỗ trợ gồm CDT giúp phân tích hàm C xây dựng CFG, Jeval giúp tính toán giá trị biểu thức. Công cụ CFT4CUnit, tài liệu hướng dẫn sử dụng và tập ví dụ thử nghiệm được cung cấp ở địa chỉ 11 http://jeval.sourceforge.net/ IASTReturnStatement IASTBinaryExpression: * IASTLiteralExpression: 3IASTIdExpression IASTName: x
  • 45. 33 http://uet.vnu.edu.vn/~hungpn/CFT4CUnit/. Hình 4.2 mô tả giao diện tổng quan của công cụ CFT4CUnit. Hình 4.2. Giao diện công cụ CFT4CUnit. 4.2.1. Đầu vào công cụ Đầu vào công cụ CFT4CUnit là một hàm C chứa các biến số nguyên (kiểu int), số thực (kiểu double, float) và biến mảng một chiều hoặc hai chiều. Chỉ số biến mảng có thể là số nguyên hoặc biểu thức. Các khối lệnh điều khiển được xử lí bao gồm rẽ nhánh, for, while...do, do...while, switch...case. Hình 4.3 là một ví dụ đầu vào công cụ. Hình 4.3. Ví dụ đầu vào công cụ CFT4CUnit.
  • 46. 34 4.2.2. Đầu ra công cụ 4.2.2.1. Đồ thị dòng điều khiển Công cụ CFT4CUnit sẽ phân tích hàm đầu vào để sinh ra đồ thị dòng điều khiển thỏa mãn tiêu chí phủ câu lệnh, phủ nhánh và phủ điều kiện con. Người sử dụng nhấn một đường kiểm thử bất kì thì đường đi tương ứng trên CFG chuyển sang màu đỏ, ngoài ra thứ tự thực hiện từng câu lệnh được hiển thị. Hơn nữa, người dùng có thể tương tác với các đỉnh trong CFG để di chuyển sang vị trí mới. Thẻ Đồ thị CFG phủ câu lệnh/nhánh hiển thị CFG thỏa mãn tiêu chí phủ câu lệnh và phủ nhánh. Thẻ Đồ thị CFG phủ điều kiện con hiển thị CFG ứng với tiêu chí phủ điều kiện con. Hình 4.4 mô tả đồ thị CFG của hàm foo nêu ở Hình 4.3 thỏa mãn tiêu chí phủ câu lệnh và phủ nhánh. Hình 4.5 hiển thị đồ thị CFG hàm foo ứng với tiêu chí phủ điều kiện con. Đỉnh đầu tiên mang nhãn Bat dau ham, đỉnh kết thúc mang nhãn Ket thuc ham. Đường màu xanh lam ứng với nhánh đúng, đường màu xanh lá cây ứng với nhánh sai. Hình 4.4. Đồ thị CFG thỏa mãn tiêu chí phủ câu lệnh và phủ nhánh. Hình 4.5. Đồ thị CFG thỏa mãn tiêu chí phủ điều kiện con.
  • 47. 35 Hình 4.6. Đường đi tương ứng trên CFG chuyển sang màu đỏ khi người dùng nhấn vào một đường kiểm thử bất kì. 4.2.2.2. Tập đường kiểm thử Các đường kiểm thử tương ứng với từng độ phủ được sinh tự động và hiển thị ở các thẻ Phủ câu lệnh, Phủ nhánh và Phủ điều kiện con. Cụ thể, thẻ Phủ câu lệnh hiển thị tập đường kiểm thử thỏa mãn tiêu chí phủ câu lệnh. Thẻ Phủ nhánh hiện danh sách tập đường kiểm thử thỏa mãn tiêu chí phủ nhánh. Thẻ Phủ điều kiện con đưa ra tập đường kiểm thử thỏa mãn tiêu chí phủ điều kiện con. Ngoài ra, tập đường đi độc lập tương ứng với độ phủ câu lệnh và phủ nhánh hiển thị ở thẻ Tập đường đi độc lập. Hình 4.7. Tập đường kiểm thử thỏa mãn phủ câu lệnh hàm foo. Hình 4.8. Tập đường kiểm thử thỏa mãn phủ nhánh hàm foo.
  • 48. 36 Hình 4.9. Tập đường kiểm thử thỏa mãn phủ điều kiện con hàm foo. Hình 4.10. Tập đường đi độc lập để sinh tập đường kiểm thử phủ nhánh và phủ câu lệnh hàm foo. 4.2.2.3. Tập ca kiểm thử Người dùng nhấn vào nút Tìm ca kiểm thử để sinh ca kiểm thử trong thời gian thực. Tùy vào loại hệ ràng buộc cần giải mà công cụ sử dụng kĩ thuật sinh ngẫu nhiên hay tận dụng thế mạnh SMT-Solver. Thông tin về quá trình SE được hiển thị chi tiết ở thẻ Quá trình SE. Ví dụ minh họa ở Hình 4.11. Hình 4.11. Ca kiểm thử thỏa mãn đường đi màu đỏ sinh theo kĩ thuật ngẫu nhiên và dùng SMT-Solver.
  • 49. 37 4.2.2.4. Biểu thức chuẩn SMT-Lib Khi người dùng nhấn vào một đường kiểm thử, hệ ràng buộc thỏa mãn chuẩn SMT- Lib được sinh tự động và hiển thị ở thẻ Hệ ràng buộc chuẩn SMT-Lib. Trong quá trình chạy, chương trình sẽ tự động lưu hệ dạng chuẩn SMT-Lib vào ổ C để làm đầu vào thư viện SmtInterpol. Người dùng có thể cài đặt lại đường dẫn thư viện SmtInterpol theo ý mình. Hình 4.12 trình bày hệ ràng buộc chuẩn SMT-Lib ứng với đường đi màu đỏ ở thẻ Đồ thị CFG phủ câu lệnh/nhánh. Đường đi màu đỏ này là một trong hai đường kiểm thử thỏa mãn tiêu chí phủ câu lệnh. Hình 4.12. Hệ ràng buộc chuẩn SMT-Lib tương ứng với đường kiểm thử màu đỏ. 4.2.2.5. Kiểm thử vòng lặp đơn Để kiểm thử vòng lặp đơn, bước đầu tiên người dùng cần xác định biến lặp vòng lặp này. Sau đó, người dùng nhấn nút Tìm ca kiểm thử để sinh tập ca kiểm thử đánh giá tính đúng đắn vòng lặp. Tập các ca kiểm thử này hiển thị ở thẻ Kiểm thử vòng lặp đơn gồm các thông tin: số lần lặp, đường kiểm thử tương ứng số lần lặp, hệ ràng buộc, ca kiểm thử, giá trị trả về và thông tin quá trình giải hệ (sử dụng SMT-Solver hay sinh ngẫu nhiên). Hình 4.13 nêu ví dụ kiểm thử vòng lặp đơn hàm tinh_tong. Vòng lặp đơn vì không xác định số lần lặp tối đa nên vòng lặp được lặp lại 0 lần, 1 lần, 2 lần, một số ngẫu nhiên (9 lần).
  • 50. 38 Hình 4.13. Kiểm thử vòng lặp đơn hàm tinh_tong. 4.2.2.6. Kiểm thử vòng lặp lồng nhau Để kiểm thử đường kiểm thử chứa hai vòng lặp lồng nhau, đầu tiên người dùng cần xác định biến lặp vòng lặp trong và vòng lặp ngoài. Sau đó, người dùng nhấn nút Tìm ca kiểm thử để sinh các ca kiểm thử đánh giá tính đúng đắn vòng lặp. Thẻ Kiểm thử vòng lặp trong hiển thị tập ca kiểm thử kiểm tra vòng lặp trong. Thẻ Kiểm thử vòng lặp ngoài hiển thị tập ca kiểm thử kiểm tra vòng lặp bên ngoài. Hình 4.14. Kiểm thử một đường kiểm thử chứa hai vòng lặp lồng nhau trong hàm SelectionSort.
  • 51. 39 4.2.3. Thực nghiệm Để chỉ ra tính hiệu quả của phương pháp đề xuất, phần thực nghiệm đưa ra sự so sánh về khả năng sinh ca kiểm thử giữa ba công cụ: công cụ theo phương pháp đề xuất CFT4CUnit, công cụ đề xuất trong [5] và công cụ PathCrawler. Đầu vào ba công cụ là một hàm C với các biến số nguyên, số thực và biến mảng. Đầu ra ba công cụ là tập ca kiểm thử. Tập ví dụ thực nghiệm chia thành ba loại: tập ví dụ có câu lệnh điều kiện đơn giản, tập ví dụ có câu lệnh điều kiện phức tạp, tập ví dụ chứa vòng lặp, tập ví dụ có chỉ số biến mảng phức tạp. Các tập ví dụ được thực hiện trong máy hệ điều hành Window 7 32 bit, Intel(R) Core™ i5-2410M CPU @ 2.30GHz với 6GB Ram. Bảng 2 đưa ra sự so sánh giữa ba công cụ CFT4CUnit, công cụ đề xuất trong [5] và PathCrawler. Công cụ CFT4CUnit có độ phủ điều kiện con, công cụ đề xuất trong [5] và PathCrawler có độ phủ nhánh. Tiêu chí đánh giá là số lỗi phát hiện được trong hàm C. Trong ví dụ foo, PathCrawler gặp phải lỗi interrupted vì không thể sinh thành công ca kiểm thử đầu tiên. Ngược lại, kĩ thuật kiểm thử luồng điều khiển hướng tĩnh bộc lộ ưu điểm khi sinh tập ca kiểm thử thành công và phát hiện được lỗi. Công cụ đề xuất trong [5] phát hiện ít lỗi tiềm ẩn hơn so với CFT4CUnit do không sinh tập ca kiểm thử phủ điều kiện con. Với ví dụ UCLN, PathCrawler gặp phải lỗi interrupted vì ca kiểm thử đầu tiên dễ sinh ra hệ ràng buộc dài. Các hệ ràng buộc mới được xây dựng bằng cách phủ định hệ ràng buộc nêu trên khá phức tạp. Do đó, quá trình tìm ca kiểm thử kế tiếp từ các hệ ràng buộc mới trở nên khó khăn và mất thời gian. Kết quả, trong một khoảng thời gian giới hạn từ trước, PathCrawler không hoàn thành quá trình sinh ca kiểm thử. Ngược lại, CFT4CUnit và công cụ trong [5] đều sinh thành công 6 ca kiểm thử. Trong ví dụ Grade, PathCrawler sinh tới 12 ca kiểm thử trong khi hai công cụ còn lại sinh số ca kiểm thử ít hơn nhiều mà cùng phát hiện 1 lỗi. Xét ví dụ Average, CFT4CUnit phát hiện được 2 lỗi trong khi công cụ đề xuất trong [5] chỉ phát hiện được một lỗi. Ví dụ Average cho thấy khả năng phát hiện lỗi tốt hơn khi sinh tập ca kiểm thử thỏa mãn tiêu chí phủ điều kiện con thay vì phủ nhánh. Trong khi đó, PathCrawler sinh tới 21 ca kiểm thử nhưng không phát hiện được lỗi nào.
  • 52. 40 Cuối cùng, với ví dụ ComplexIndex chứa chỉ số biến mảng dạng biểu thức, PathCrawler và công cụ đề xuất trong [5] không giải quyết được vấn đề này. Ngược lại, vì CFT4CUnit có quá trình rút gọn chỉ số mảng dạng biểu thức nên phát hiện được một lỗi. Bảng 2. So sánh CFT4CUnit, công cụ đề xuất trong [5] và PathCrawler Hàm C CFT4CUnit Công cụ đề xuất trong [5] PathCrawler Số lỗi Số đường kiểm thử Số lỗi Số đường kiểm thử Số lỗi Số đường kiểm thử Foo 2 5 1 3 - - UCLN 0 6 0 6 - - Grade 1 6 1 6 1 12 Average 2 5 1 3 0 21 ComplexIndex 1 3 - - - - Bảng 3 nêu các ví dụ chứa vòng lặp đơn và tập ca kiểm thử đánh giá các vòng lặp đó được sinh bởi công cụ CFT4CUnit. Công cụ đề xuất trong [5] không sinh được ca kiểm thử cho vòng lặp. Kĩ thuật kiểm thử vòng lặp của PathCrawler có tư tưởng và hướng đến mục tiêu khác so với CFT4CUnit nên không nêu so sánh ở khóa luận này. Ở Bảng 3, các đỉnh đi vào vòng lặp và thoát khỏi vòng lặp được bôi đậm. Nếu các đường kiểm thử mới có vòng lặp sao chép một số lần cụ thể không có ca kiểm thử nào thỏa mãn, cột ca kiểm thử ghi dấu “-“. Bảng 3. Kiểm thử vòng lặp đơn sử dụng công cụ CFT4CUnit Mã nguồn Đường đi chứa vòng lặp trong tập đường đi độc lập Số lần lặp Ca kiểm thử UCLN !(m<0)#!(n<0)#!(m==0)#!(n==0)# (m!=n)#(m>n)#(m=m-n)# !(m!=n)#(return m) 0 n = 4, m = 4 1 n = 4, m = 8 2 n = 1, m = 3
  • 53. 41 6 n = 1, m = 7 !(m<0)#!(n<0)#!(m==0)#!(n==0)# (m!=n)#!(m>n)#(n=n-m)# !(m!=n)#(return m) 0 n = 6, m = 6 1 n = 4, m = 2 2 n = 9 , m = 3 8 n = 9, m = 1; LaSo NguyenTo (int i=2)#!((n%i)==0)#(i++)# (i<=n/2)#!((n%i)==0)#(i++)# !(i<=n/2)#(return 1) 1 n = 1 2 n = 7 5 - Average (int tcnt=0,vcnt=0,sum=0,i=0) #(value[i]!=-2&&tcnt<10)# (tcnt++)# (min<=value[i]&&value[i]<=max)# (sum=sum+value[i])#(vcnt++)# (i++)#!(value[i]!=-2&&tcnt<10)# !(vcnt<0)#(return sum/vcnt) 0 max = -4, min = 5, value[0] = -2 1 max = 3, min = 1, value[0] = 3, value[1] = -2 2 max = 5, min = -1, value[0] = 5, value[1] = 4 ,value[2] = -2 7 max = 4, min = -4, value[0] = -4, value[1] = -1, value[2] = 3, value[3] = 1, value[4] = 0, value[5] = 4, value[6] = 0, value[7] = -2 (int tcnt=0,vcnt=0,sum=0,i=0) #(value[i]!=-2&&tcnt<10)# (tcnt++)# !(min<=value[i]&&value[i]<=max) 0 max = 0, min = 5, value[0] = -2 1 max = -3, min = 5, value[0] = -4,
  • 54. 42 #(i++)#!(value[i]!=-2&&tcnt<10)# !(vcnt<0)#(return sum/vcnt) value[1] = -2 2 max = -1, min = 2, value[0] = 3, value[1] = 3, value[2] = -2 8 max = -1, min = 0, value[0] = -1, value[1] = 2, value[2] = -4, value[3] = 5, value[4] = -1, value[5] = -3, value[6] = -3, value[7] = 5, value[8] = -2 Bảng 4 trình bày các ca kiểm thử để kiểm thử tính đúng đắn vòng lặp hàm SelectionSort sử dụng công cụ CFT4CUnit. Công cụ đề xuất trong [5] không sinh ca kiểm thử cho hai vòng lặp lồng nhau. Bảng 4. Kiểm thử hai vòng lặp lồng nhau hàm SelectionSort sử dụng CFT4CUnit Đường đi chứa vòng lặp trong tập đường đi độc lập Số lần lặp Ca kiểm thử Kiểm thử vòng lặp trong (int i,j)#(i=0)# (i<size-1)# (int min=i)#(j=i+1)# (j<size) #!(a[j]<a[min])#(j++) # !(j<size)#(int tem=a[i])# (a[i]=a[min]) #(a[min]=tem)#(i++)# 1 size = 8, a[6] = -3, a[7] = 7 2 size = 9, a[6] = 6, a[7] = 18, a[8] = 14 4 size = 11, a[6] = -3, a[7] = 7, a[8] = 19, a[9] = 9, a[10] = 12 Kiểm thử vòng lặp ngoài 1 size = 2 ,a[0] = -2, a[1] = 5 2 size=3, a[0]=-5, a[1] =7, a[2] = 1
  • 55. 43 !(i<size-1) 7 size = 8, a[0] = -8, a[1] = 8, a[2] = 8, a[3] = 3, a[4] = -1, a[5] = 9, a[6] = 7, a[7] = -4 4.2.4. Ý nghĩa thực nghiệm Kết quả thực nghiệm cho thấy ưu điểm của phương pháp đề xuất so với công cụ đề xuất trong [5] và PathCrawler. Phương pháp đề xuất giải quyết tốt những hàm mà PathCrawler không thể sinh ca kiểm thử đầu tiên. Ngoài ra, phương pháp đề xuất kiểm thử hàm đến tiêu chí phủ điều kiện con nên phát hiện được nhiều vấn đề trong mã nguồn hơn so với công cụ đề xuất trong [5] như trong ví dụ Average. Về kiểm thử vòng lặp, PathCrawler có thể sinh số lượng ca kiểm thử rất lớn hoặc không xác định. Ví dụ, trong hàm Average, PathCrawler sinh tới 21 ca kiểm thử nhưng không phát hiện được lỗi nào. Công cụ đề xuất trong [5] không nêu chiến thuật kiểm thử tính đúng đắn của vòng lặp. Công cụ CFT4CUnit hướng đến tìm tập ca kiểm thử để kiểm tra tính đúng đắn của từng vòng lặp. Tùy vào loại vòng lặp, chúng tôi hoàn toàn xác định được số lượng ca kiểm thử tối đa sinh ra bởi CFT4CUnit. Trường hợp vòng lặp đơn biết số lần lặp tối đa, số lượng ca kiểm thử sinh bởi CFT4CUnit là 7 trong khi PathCrawler có thể hơn rất nhiều nếu số lần lặp lớn. Với vòng lặp đơn không biết số lần lặp tối đa, số ca kiểm thử sinh bởi PathCrawler có thể không xác định trong khi CFT4CUnit chỉ sinh tối đa 4 ca kiểm thử. Trong trường hợp hai vòng lặp lồng nhau, số ca kiểm thử tối đa mà CFT4CUnit sinh là 14 (gồm 7 ca kiểm thử đánh giá vòng lặp bên trong, 7 ca kiểm thử đánh giá vòng lặp bên ngoài). Ngược lại, số ca kiểm thử tối đa sinh bởi PathCrawler không xác định và bằng m*n, trong đó m là số lần lặp tối đa vòng lặp bên trong, n là số lần lặp tối đa vòng lặp bên ngoài. Trong trường hợp tệ nhất, PathCrawler sinh số lượng ca kiểm thử không xác định nếu số lần lặp tối đa vòng lặp bên trong và vòng lặp bên ngoài không xác định. Trong pha kiểm thử chất lượng phần mềm, nếu số lượng ca kiểm thử rất lớn hoặc không xác định sẽ gây rất nhiều khó khăn cho khâu quản lý. Về khả năng giải hệ ràng buộc, CFT4CUnit kết hợp sinh ngẫu nhiên và tận dụng thế mạnh công cụ SMT-Solver nên giải được nhiều hệ ràng buộc khác nhau. Ví dụ cụ thể, trong hàm Average, câu lệnh điều kiện có toán tử so sánh khác nên không thể giải được
  • 56. 44 trong SmtInterpol. Tuy nhiên, phép sinh ngẫu nhiên giải quyết hiệu quả vấn đề này. Một ví dụ khác, trường hợp hệ ràng buộc có biến mảng chỉ số phức tạp như trong ví dụ ComplexIndex, quá trình biến đổi hệ có biến mảng kiểu này về chuẩn SMT-Lib rất khó khăn và phức tạp nên sinh ngẫu nhiên được coi là một giải pháp thay thế khả thi. Đối với PathCrawler và công cụ đề xuất trong [5], vấn đề này rất khó giải quyết.