1. Trang chủ
  2. » Luận Văn - Báo Cáo

đồ án xây dựng công cụ kiểm thử dòng điền khiển tự động java

62 44 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 62
Dung lượng 1,61 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Sau đó, đồ thị này được phân tích để thu được một tập các đường thi hành sao cho sau khi thực hiện chúng tiêu chí phủ kiểm thử được thỏa mãn.. Tổng quan về kĩ thuật kiểm thử hộp trắng dò

Trang 1

ĐẠI HỌC QUỐC GIA HÀ NỘI TRƯỜNG ĐẠI HỌC CÔNG NGHỆ

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 - 2016

HÀ NỘI – 2016

Trang 2

ĐẠI HỌC QUỐC GIA HÀ NỘI TRƯỜNG ĐẠI HỌC CÔNG NGHỆ

KHÓA LUẬN TỐT NGHIỆP ĐẠI HỌC HỆ CHÍNH QUY

Ngành: Công Nghệ Thông Tin

Trang 3

Supervisor: Assoc Prof Dr Pham Ngoc Hung

HANOI - 2016

VIETNAM NATIONAL UNIVERSITY, HANOI UNIVERSITY OF ENGINEERING AND TECHNOLOGY

Trang 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 PGS TS 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 tham gia nghiên cứu khoa học và 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 K57 đã 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 27 tháng 05 năm 2016

Sinh viên

Dương Tuấn Anh

Trang 5

TÓM TẮT

Ngôn ngữ lập trình Java vẫn luôn là một trong những ngôn ngữ lập trình phổ biến nhất, có chỗ đứng lâu nhất, bền bỉ và có tầm ảnh hưởng nhất Java được sử dụng trong khoảng 97% máy tính để bàn và có khoảng 1 tỷ bản Java tải về mỗi năm Hơn nữa, Java không đứng yên mà còn phát triển với một phiên bản Java mới là Java 8 đã được phát hành năm ngoái và phiên bản Java 9 dự kiến được phát hành vào năm 2016 Vì sự phổ biến và phát triển không ngừng đó, quá trình kiểm thử trong các dự án Java ngày càng tốn nhiều công sức và chi phí hơn Lượng mã nguồn lớn và phức tạp gây rất nhiều khó khăn trong việc sinh các ca kiểm thử, đặc biệt là trong kĩ thuật kiểm thử hộp trắng Vì vậy, việc tự động hóa quá trình kiểm thử được xem như là một giải pháp để giảm bớt chi phí cho quá trình kiểm thử mà vẫn đảm bảo được chất lượng sản phẩm Hiện nay cũng đã có nhiều công cụ

hỗ trợ kiểm thử tự động cho ngôn ngữ Java nhưng đa số chỉ tập trung vào việc thực thi các

ca kiểm thử mà không chú trọng vào việc sinh ca kiểm thử tự động Một số công cụ hỗ trợ

tự động sinh ca kiểm thử nhưng còn chưa đủ tốt và còn có những hạn chế nhất định

Vì vậy, khóa luận đề xuất một phương pháp sinh ca kiểm thử tự động cho các đơn vị chương trình Java và cài đặt công cụ hỗ trợ CFT4JUnit Phương pháp sử dụng kĩ thuật kiểm thử tự động hộp trắng dòng điều khiển theo hướng tĩnh Đầu vào gồm một hàm Java có chứa các biến số nguyên, số thực, các biến mảng và tiêu chí phủ kiểm thử, số vòng lặp tối

đa Đầu ra gồm tập các ca kiểm thử đáp ứng được tiêu chí phủ kiểm thử và tập các ca kiểm thử cho kiểm thử các vòng lặp Cụ thể, ở bước đầu tiên, đồ thị dòng điều khiển ứng với tiêu chí phủ kiểm thử được xây dựng bằng cách phân tích mã nguồn hàm đầu vào Sau đó, đồ thị này được phân tích để thu được một tập các đường thi hành sao cho sau khi thực hiện chúng tiêu chí phủ kiểm thử được thỏa mãn Tiếp theo, các đường kiểm thử chứa vòng lặp được xử lí để sinh thêm các đường kiểm thử mới dùng kiểm thử tính đúng đắn của vòng lặp Kế tiếp, bằng kĩ thuật thực thi tượng trưng, các đường thi hành sẽ được phân tích thành

hệ ràng buộc tương ứng Cuối cùng, các ca kiểm thử sẽ được thực thi để thu được kết quả kiểm thử Cuối cùng, các ca kiểm thử được sinh ra từ việc giải hệ các ràng buộc Kết quả thực nghiệm cho thấy phương pháp có thể sinh tự động được các ca kiểm thử với số lượng tối thiểu nhưng vẫn đạt được độ phủ tối đa Ngoài ra, khả năng phát hiện lỗi tương đối cao, thời gian sinh các ca kiểm thử cũng được cải thiện đáng kể

Từ khóa: Kiểm thử tự động, hàm Java, đồ thị dòng điều khiển, đường thi hành, ca

kiểm thử, Symbolic Execution, SMT-Solver

Trang 6

Therefore, this thesis proposes a method of automated generating test cases for Java unit and install a supporting tool This method use automated testing techniques for white box control flow graph with static direction Inputs include a Java function contains integer variables, real numbers, variables and arrays tested negative criteria, the maximum number

of loops Output consists of a set of test cases to meet the criteria set of government testing and test cases for testing the loop Specifically, in the first step, the control flow graph with specific coverage criteria is built by analyzing the source code input function

Then this graph is analyzed to obtain a set of lines that execution after execution they test negative criteria are met Next, the test contains a loop road is processed to generate additional new tests used road testing the correctness of the loop Next, using symbolic execution techniques, the implementation of the road will be analyzed in the corresponding binding system Then, the test cases are executed in order to obtain test results Finally, the test cases are generated by solving the system of constraints Experimental results show that the method can be automatically generated test cases with the minimum amount but still achieve maximum coverage In addition, the possibility of a relatively high error detection, time of birth of test cases has also improved significantly

Keywords: automatic testing, Java method, control flow graph, test path, test case,

Symbolic Execution, SMT-Solver

Trang 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 các đơn vị chương trình Java đượ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

Sinh viên

Trang 8

MỤC LỤC

Đặt vấn đề 1

Tổng quan kĩ thuật kiểm thử tự động hộp trắng dòng điều khiển 4

2.1 Tổng quan về kĩ thuật kiểm thử hộp trắng dòng điều khiển 4

2.1.1 Đồ thị dòng điều khiển 4

2.1.2 Các tiêu chí phủ kiểm thử 5

2.1.3 Tự động hóa quy trình kiểm thử hộp trắng dòng điều khiển 6

2.2 Tổng quan về kiểm thử tự động hộp trắng dòng điều khiển theo hướng động 7

2.3 Tổng quan về kiểm thử tự động hộp trắng dòng điều khiển theo hướng tĩnh 8

2.4 So sánh kiểm thử tự động hộp trắng dòng điều khiển theo hướng tĩnh và động 9

Phương pháp sinh ca kiểm thử tự động dòng điều khiển cho các đơn vị của chương trình Java 11

3.1 Tổng quan về phương pháp kiểm thử đề xuất 11

3.2 Sinh đồ thị CFG 12

3.2.1 Tổng quan phương pháp sinh đồ thị CFG 15

3.2.2 Phân tích mã nguồn 16

3.2.3 Phân tích cây AST từ mã nguồn 16

3.2.4 Xây dựng đồ thị dòng điều khiển CFG 18

3.2.4.1 Tổng quan thuật toán sinh đồ thị CFG từ cây AST 18

3.2.4.2 Xử lí các nút đơn giản 20

3.2.4.2 Xử lý nút khối 20

3.2.4.2 Xử lý nút câu lệnh if else 21

3.2.4.2 Xử lý nút câu lệnh for 22

3.2.4.2 Xử lý nút câu lệnh while 23

3.2.4.2 Xử lý nút câu lệnh do…while 24

Trang 9

3.2.4.2 Xử lý nút câu lệnh đặc biệt 24

3.2.4.2 Liên kết các câu lệnh thực, xóa câu lệnh ảo 25

3.2.5 Chuẩn hóa biểu thức 26

3.3 Xây dựng đường kiểm thử từ đồ thị CFG 27

3.3.1 Sinh tập đường đi độc lập 27

3.3.2 Sinh tập đường kiểm thử cho các tiêu chí phủ 29

3.3.3 Sinh tập đường kiểm thử cho vòng lặp 29

3.3.3.1 Sinh tập đường kiểm thử cho vòng lặp đơn 30

3.3.3.2 Sinh tập đường kiểm thử cho vòng lặp lồng nhau 31

3.4 Sinh ca kiểm thử từ tập đường kiểm thử 32

3.4.1 Xây dựng hệ ràng buộc 32

3.4.2 Sinh ca kiểm thử từ hệ ràng buộc 34

3.4.2.1 Phương pháp giải hệ ràng buộc bằng kĩ thuật sinh giá trị ngẫu nhiên 34

3.4.2.2 Phương pháp giải hệ ràng buộc bằng công cụ SMT-Solver 35

Công cụ và thực nghiệm 38

4.1 Giới thiệu về công cụ 38

4.1.1 Tổng quan về công cụ 38

4.1.2 Đồ thị dòng điều khiển CFG 39

4.1.3 Tập các đường kiểm thử 41

4.1.4 Tập các ca kiểm thử 41

4.1.5 Các thư viện hỗ trợ 42

4.1.5.1 Giới thiệu bộ giải Z3 42

4.1.5.2 Giới thiệu công cụ JDT 42

4.2 Thực nghiệm 43

4.2.1 Kiểm thử hàm đơn giản 43

Trang 10

4.2.2 Kiểm thử hàm phức tạp 44

4.2.3 Kiểm thử hàm có lỗi tiềm ẩn 45

4.2.4 Ý nghĩa của thực nghiệm 46

Kết luận 47

Trang 11

DANH SÁCH KÝ HIỆU, CHỮ VIẾT TẮT

AST Abstract Syntax Tree Cây cấu trúc trừu tượng

JDT Java Development Tooling Thư viện phân tích hỗ phân tích

mã nguồn file Java SMT-

Solver Satisfiability Modulo Theories Solver Bộ giải hệ các phương trình SAT Scholastic Aptitude Test Logic mệnh đề

SE Symbolic Execution Kĩ thuật thực thi tượng trưng

Trang 12

DANH SÁCH HÌNH VẼ

Hình 2.1 Các loại đỉnh cơ bản trong đồ thị CFG 5

Hình 2.2 Các cấu trúc điều khiển phổ biến của chương trình 5

Hình 2.3 Quy trình kiểm thử đơn vị chương trình dựa trên độ đo 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 động 8

Hình 2.5 Quy trình chung của kiểm thử tự động hộp trắng dòng điều khiển 9

Hình 3.1 Quy trình kiểm thử một hàm java theo phương pháp đề xuất 11

Hình 3.2 Đồ thị CFG của hàm average tiêu chuẩn phủ câu lệnh 14

Hình 3.3 Mã nguồn hàm average 15

Hình 3.4 Tổng quan phương pháp sinh đồ thị CFG từ mã nguồn 15

Hình 3.5 Xử lí nút AST đơn giản 20

Hình 3.6 Xử lí nút AST khối 21

Hình 3.7 Xử lí nút AST lệnh if else 22

Hình 3.8 Xử lí nút AST câu lệnh for 22

Hình 3.9 Xử lý nút AST câu lệnh while 23

Hình 3.10 Xử lý nút AST câu lệnh do while 24

Hình 3.11 Quy trình ghép nối: beforeStm -> R -> END 25

Hình 3.12 Câu lệnh continue: beforeStm -> continueStm 25

Hình 3.13 Câu lệnh break: beforeStm -> breakStm 25

Hình 3.14 Những loại biểu thức được chuẩn hóa 26

Hình 3.15 Quá trình giải hệ ràng buộc bằng kĩ thuật sinh ngẫu nhiên 34

Hình 3.16 Quá trình giải hệ ràng buộc bằng công cụ SMT-Lib 35

Hình 3.17 Cây biểu thức của biểu thức trung tố 2*a + b < c 37

Hình 4.1 Sơ đồ kiến trúc của công cụ CFT4Junit 38

Hình 4.2 Giao diện chính của công cụ 39

Hình 4.3 Đồ thị CFG thỏa mãn tiêu chỉ phủ câu lệnh, phủ nhánh và phủ điều kiện con 40

Trang 13

Hình 4.4 Mã nguồn hàm foo 40

Hình 4.5 Tập đường đi thỏa mãn phủ nhánh của hàm foo 41

Hình 4.6 Chi tiết ca kiểm thử ứng với một đường đi trong hàm foo 41

Hình 4.7 Thí dụ về đầu vào và đầu ra của công cụ Z3 42

Hình 4.8 Minh họa cây AST ứng với mã nguồn return x*3 43

Hình 4.9 Mã nguồn hàm min 43

Hình 4.10 Mã nguồn hàm SelectionSort 44

Hình 4.11 Mã nguồn hàm divide 45

Trang 14

DANH SÁCH BẢNG

Bảng 4.1 Kết quả kiểm thử hàm min 44

Bảng 4.2 Kết quả kiểm thử hàm SelectionSort 44

Bảng 4.3 Kết quả kiểm thử hàm divide 45

DANH SÁCH THUẬT TOÁN Thuật toán 1 CFG_Generation(f, t) 12

Thuật toán 2 CFG_Generation(AST, t) 19

Thuật toán 3 Path_Generation(CFG) 28

Thuật toán 4 Path_Loop_Generation(path, n) 30

Thuật toán 5 Path_Test_InsideLoop_Generation(path, n) 31

Thuật toán 6 Path_Test_InsideLoop_Generation(path, n) 32

Thuật toán 7 Constraints_Generation(path) 33

Thuật toán 8 Infix_To_Postfix(infixExp) 36

Trang 15

1

Đặt vấn đề

Ngôn ngữ lập trình Java vẫn luôn là một trong những ngôn ngữ lập trình phổ biến nhất, có chỗ đứng lâu nhất, bền bỉ và có tầm ảnh hưởng nhất Nó đã trở thành một nền tảng thống lĩnh, có mặt tại các ứng dụng trong và ngoài môi trường web, chạy trên tất cả các hệ điều hành nhờ hỗ trợ của cơ chế ảo hóa Java (Java Virtual Machine) bất chấp sự xuất hiện của nhiều ngôn ngữ lập trình mới nổi sau này Java được sử dụng trong khoảng 97% máy tính để bàn và có khoảng 1 tỷ bản Java tải về mỗi năm Hơn nữa, Java không đứng yên mà còn phát triển với một phiên bản Java mới là Java 8 đã được phát hành năm ngoái và phiên bản Java 9 dự kiến được phát hành vào năm 2016 Vì sự phổ biến và phát triển không ngừng

đó, quá trình kiểm thử trong các dự án Java ngày càng tốn nhiều công sức và chi phí hơn Lượng mã nguồn lớn và phức tạp gây rất nhiều khó khăn trong việc sinh các ca kiểm thử, đặc biệt là trong kĩ thuật kiểm thử hộp trắng Vì thế, kiểm thử tự động được xem như là một giải pháp hiệu quả để giải quyết vấn đề này Việc tự động hóa quá trình kiểm thử giúp 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 Đồng thời, nó còn giúp kiểm thử viên giảm bớt nhàm chán và áp lực trong công việc 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

Kiểm thử hộp trắng cho phép phát hiện các lỗi, khiếm quyết tiềm ẩn bên trong chương trình phần mềm[1] Tuy nhiên, để áp dụng các 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ử[1] Hơn nữa, người kiểm thử và người lập trình thường là hai người khác nhau Vì vậy, việc áp dụng các kĩ thuật kiểm thử hộp trắng thường tốn rất nhiều 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 Do đó, 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ị

Kĩ thuật kiểm thử hộp trắng có hai phương pháp phổ biến là kiểm thử dòng điều khiển

và kiểm thử dòng dữ liệu Kiểm thử dòng dữ liệu (data flow testing) là kĩ thuật được dùng

để phát hiện lỗi liên quan đến việc khai báo và sử dụng các biến trong chương trình Phương

pháp kiểm thử dòng điều khiển (control flow testing) tập trung kiểm thử tính đúng đắn của

Trang 16

kĩ thuật kiểm thử theo hướng động Theo hướng tiếp cận này, mã nguồn sẽ được thực thi với một bộ giá trị đầu vào ngẫu nhiên để đánh dấu một đường thi hành đầu tiên Bằng cách phủ định đường thi hành hiện tại, một đường thi hành mới sẽ được tạo ra Các ràng buộc phân tích từ đường thi hành mới sẽ được giải để sinh được ca kiểm thử tiếp theo Việc kiểm thử hộp trắng dòng điều khiển theo hướng động này còn có một số hạn chế nhất định Thứ nhất, nếu ca kiểm thử đầu tiên không thực thi được thì việc sinh ra các ca kiểm thử tiếp theo

sẽ không thực hiện được Thứ hai, số lượng bộ giá trị kiểm thử có thể rất lớn do việc các đường thi hành có thể bị trùng lặp, hoặc do số lượng các ràng buộc lớn từ việc thực thi các vòng lặp Thứ ba, thời gian sinh ca kiểm thử lâu hơn do mỗi khi sinh một ca kiểm thử, mã nguồn lại phải thực thi một lần Thứ tư, số lượng các ràng buộc sinh ra từ đường thi hành

là rất lớn và phức tạp nên việc giải hệ ràng buộc gặp nhiều khó khăn khi dùng kĩ thuật sinh ngẫu nhiên

Khóa luận này đề xuất một phương pháp sinh ca kiểm thử tự động cho các đơn vị chương trình Java để khắc phục những hạn chế nêu trên Phương pháp sử dụng kĩ thuật kiểm thử hộp trắng dòng điều khiển theo hướng tĩnh Tư tưởng chính của phương pháp là

phân tích mã nguồn để sinh ra đồ thị dòng điều khiển CFG (Control Flow Graph) Các

đường thi hành sẽ được phân tích từ đồ thị CFG Do đó, số lần thực thi mã nguồn được giảm bớt rất nhiều giúp giảm thời gian sinh các ca kiểm thử Hơn nữa, số lượng ca kiểm thử ít hơn mà vẫn đảm bảo được độ phủ tối đa Phương pháp không chỉ kết hợp các thế mạnh của kĩ thuật sinh ngẫu nhiên và công cụ SMT-Solver mà còn đề xuất một kĩ thuật phân loại các ràng buộc để giải Vì thế, phương pháp có thể giải được nhiều loại hệ ràng buộc một cách nhanh hơn

Phần còn lại của khóa luận được trình bày như sau Đầu tiên, chương 2 sẽ giới thiệu tổng quan về kĩ thuật kiểm tự động thử hộp trắng dòng điều khiển Tiếp theo, phương pháp

đề xuất sẽ được trình bày chi tiết trong chương 3 Sau đó, chương 4 sẽ giới thiệu về công

cụ được cài đặt và phát triển dựa trên phương pháp đề xuất cùng với những kết quả thực

Trang 17

3 nghiệm thu được 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

Trang 18

là theo hướng tĩnh và hướng động

2.1 Tổng quan về 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 được sử dụng để kiểm tra tính đúng đắn và phát hiện các lỗi tiềm ẩn trong mã nguồn của dự án phần mềm Đầu vào là mã nguồn của chương trình cùng với tiêu chí phủ kiểm thử Đầu ra sẽ là tập các ca kiểm thử thỏa mãn tiêu chí phủ kiểm thử

2.1.1 Đồ thị dòng điều khiển

Trong kĩ thuật kiểm thử hộp trắng dòng điều khiển, đồ thị dòng điều khiển CFG

(Control Flow Graph) là một phần rất quan trọng Đồ thị này thể hiện một cách tổng quát

và trực quan về các luồng điều khiển trong mã nguồn chương trình Từ đó, người kiểm thử

có thể dễ dàng sinh các ca kiểm thử cho các tiêu chí phủ cũng như đánh giá độ tốt của các

ca kiểm thử Đồ thị CFG của một hàm là một đồ thị có hướng được xây dựng từ mã nguồn của chương trình Đỉnh đầu vào đỉnh cuối đồ thị lần lượt tượng trưng cho trạng thái bắt đầu

và kết thúc của hàm Các đỉnh còn lại, mỗi đỉnh tượng trưng cho một hoặc một nhóm câu

lệnh Nếu câu lệnh tương ứng với đỉnh j được thực hiện ngay sau câu lệnh ứng với đỉnh i thì sẽ tồn tại một cạnh nối từ đỉnh i đến đỉnh j Các cạnh tượng trưng cho dòng điều khiển

giữa các câu lệnh hoặc nhóm câu lệnh

Hình 2.1 mô tả kí hiệu năm loại đỉnh trong đồ thị dòng điều khiển [1] Trong đó:

- Đỉnh bắt đầu, đỉnh kết thúc: Là đỉnh tượng trưng cho trạng thái bắt đầu và kết thúc

của hàm

- Đỉnh xử lí: Là đỉnh tương ứng với các câu lệnh thực thi như câu lệnh gán, câu lệnh

khai báo, khởi tạo, v.v

- Đỉnh quyết định: Là đỉnh tương ứng với các câu lệnh chữa các điều kiện rẽ nhánh như câu lệnh if, do…while, while…do, v.v

Trang 19

5

- Đỉnh nối: Là đỉnh mà có nhiều hơn một đỉnh khác chỉ đến mà không phải là đỉnh

quyết định

Hình 2.1 Các loại đỉnh cơ bản trong đồ thị CFG

Hình 2.2 mô tả các cấu trúc điều khiển phổ biến của chương trình: tuần tự, if…else,

do…while, while…do, for trong đồ thị dòng điều khiển [1]

Hình 2.2 Các cấu trúc điều khiển phổ biến của chương trình

2.1.2 Các tiêu chí phủ kiểm thử

Khi kiểm thử hộp trắng dòng điều khiển, một trong các đầu vào là tiêu chí phủ kiểm thử Tiêu chí phủ kiểm thử ở đây là một thước đo để đánh giá độ tốt của bộ ca kiểm thử Tập các ca kiểm thử tốt hay không không dựa vào số lượng các ca kiểm thử mà dựa vào độ phủ mà nó đạt được Độ phủ càng lớn thì tập các ca kiểm thử đó càng tốt Độ phủ này được tính bằng tỉ lệ các thành phần kiểm thử được sau khi thực hiện các ca kiểm thử so với tổng

số các thành phần cần kiểm thử của chương trình Các thành phần sẽ được phân chia cụ thể theo từng tiêu chí phủ Trong khóa luận, ba tiêu chí được sử dụng để đánh giá chất lượng

mã nguồn, bao gồm:

- Phủ câu lệnh: Mỗi câu lệnh hay mỗi đỉnh trong đồ thị CFG phải được đi qua thi ít

nhất một lần sau khi thực thi các ca kiểm thử

Đỉnh bắt

đầu Đỉnh xử lí Đỉnh quyết định Đỉnh nối Đỉnh kết thúc

Trang 20

6

- Phủ nhánh: Các đỉnh quyết định đều được đi qua cả nhánh đúng và nhánh sai sau

khi thực thi các ca kiểm thử

- Phủ điều kiện con: Các đỉnh quyết định đều được đi qua cả nhánh đúng và nhánh

sai, trong đó điểm quyết định có chứa nhiều điều kiện con sẽ được phân tách thành các câu lệnh điều kiện đơn

Quy trình kiểm thử đơn vị chương trình dựa trên các tiêu chí phủ kiểm thử được mô tả như trong Hình 2.3 Đầu tiên, đồ thị dòng điều khiển CFG ứng với mỗi tiêu chí phủ được xây dựng Sau đó, đồ thị này được phân tích để thu được một tập các đường thi hành sao cho sau khi thực hiện chúng tiêu chí phủ kiểm thử được thỏa mãn Tiếp theo, mỗi đường thi hành sẽ được sinh ra một ca kiểm thử tương ứng Cuối cùng, các ca kiểm thử sẽ được thực thi để thu được kết quả kiểm thử

Hình 2.3 Quy trình kiểm thử đơn vị chương trình dựa trên độ đo

2.1.3 Tự động hóa quy trình kiểm thử hộp trắng dòng điều khiển

Hiện nay, lượng mã nguồn lớn và phức tạp gây rất nhiều khó khăn trong việc sinh các

ca kiểm thử, đặc biệt là trong kĩ thuật kiểm thử hộp trắng Vì thế, kiểm thử tự động được xem như là một giải pháp hiệu quả để giải quyết vấn đề này Việc tự động hóa quá trình kiểm thử giúp 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 Đồng thời, nó còn giúp kiểm thử viên giảm bớt nhàm chán và áp lực trong công việc 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 Nhìn chung, việc tự động hóa quy trình kiểm thử hộp trắng có ba nguyên nhân chính:

- Với một lượng mã nguồn lớn và có độ phức tạp cao thì việc kiểm thử hộp trắng bằng tay khá tốn thời gian, công sức và dễ dẫn đến sai sót Cũng vì lí do đó mà, kiểm thử hộp trắng yêu cầu cao về trình độ chuyên môn và khả năng chịu áp lực của kiểm thử viên

Xây dựng đồ thị luồng điều khiển CFG

Thực thi các

ca kiểm thử

Xác định các đường thi hành

Sinh các ca kiểm thử

Mã nguồn

Tiêu chí

phủ

Trang 21

7

- Như đã nói ở nguyên nhân trước, kiểm thử hộp trắng yêu cầu kiểm thử viên phải có trình độ chuyên môn sâu rộng về ngôn ngữ cần kiểm thử Vì thế, chi phí tuyển dụng

và đào tạo nguồn nhân lực khá là tốn kém

- Theo như các thống kê thì chi phí dành cho quá trình kiểm thử trong các dự án phần mềm thường chiếm từ 40% đến 60% tổng chi phí Trong khí đó, phần mềm bây giờ thường đòi hỏi yêu cầu cao về chất lượng Hơn nữa, quá trình bảo trì và phát triển phiên bản mới khi được tiến hành sẽ càng làm tăng chi phí kiểm thử

Nhiều phương pháp và công cụ đã được đề xuất để hỗ trợ kiểm thử tự động hộp trắng dòng điều khiển Trong đó, hai phương pháp phổ biến được sử dụng trong kiểm thử tự động dòng điều khiển là theo hướng động vào hướng tĩnh Cả hai kĩ thuật này đều có mục tiêu là sinh các ca kiểm thử để đạt được độ phủ tối đa Mỗi kĩ thuật đều có những điểm mạnh và điểm yếu riêng Kĩ thuật kiểm thử theo hướng tĩnh thích hợp trong việc kiểm thử các mã nguồn dễ phân tích như hàm đơn vị, hàm được viết theo một chuẩn nào đó v.v Trong khi

đó, kĩ thuật kiểm thử theo hướng động phù hợp với các mã nguồn chương trình có độ phức tạp cao, khó phân tích hơn Trong phần tiếp theo, khóa luận sẽ trình bày quy trình chung của từng phương pháp

2.2 Tổng quan về kiểm thử tự động hộp trắng dòng điều khiển theo hướng động

Kĩ thuật kiểm thử tự động hộp trắng dòng điều khiển theo hướng động thường được

sử dụng với những mã nguồn có độ phức tạp cao, khó phân tích Tư tưởng của kĩ thuật là tận dụng thế mạnh của trình biên dịch để phân tích mã nguồn chương trình bằng cách chèn thêm các câu lệnh đánh dấu vào mã nguồn Hình 2.4 mô tả quy trình chung của kĩ thuật này Cụ thể, kĩ thuật gồm các bước sau:

Bước 1 Sinh ngẫu nhiên một bộ giá trị đầu vào hợp lệ

Bước 2 Thực thi chương trình với bộ đầu vào vừa tìm được và đánh dấu đường thi

hành tương ứng

Bước 3 Sinh hệ ràng buộc từ việc phân tích đường thi hành hiện tại

Bước 4 Sinh hệ ràng buộc mới tượng trưng cho đường thi hành tiếp theo bằng cách

phủ định hệ ràng buộc tìm được ở bước 2 Nếu không sinh được hệ ràng buộc mới thì thuật toán kết thúc

Bước 5 Giải hệ ràng buộc thu được ở bước 4 để sinh được bộ giá trị đầu vào mới Nếu

hệ vô nghiệm, quay lại bước 4 Ngược lại, quay lại bước 2

Trang 22

Source code Tiêu chí phủ

Sinh bộ đầu vào ngẫu nhiên

Thực thi chương trình

Đánh dấu đường thi hành

Sinh hệ ràng buộc

Tạo đường thi hành mới

Tìm được ca kiểm thử mới

True

False

Kết thúc

Trang 23

9

Hình 2.5 Quy trình chung của kiểm thử tự động hộp trắng dòng điều khiển

2.4 So sánh kiểm thử tự động hộp trắng dòng điều khiển theo hướng tĩnh và động

Hai kĩ thuật kiểm thử tự động hộp trắng dòng điều khiển theo hướng tĩnh và động đều

có những điểm mạnh vào điểm yếu riêng Chúng có thể hỗ trợ cho nhau để sinh được những

ca kiểm thử tốt nhất Sau đây, khóa luận sẽ đưa ra sự so sánh giữa hai kĩ thuật dựa theo những tiêu chí cụ thể

- Về số ca kiểm thử: Kĩ thuật kiểm thử theo hướng động sẽ phải sinh ra nhiều ca kiểm

thử hơn so với theo hướng tính Trong kĩ thuật kiểm thử theo hướng động, các đường thi hành sẽ được sinh từng cái một từ đường thi hành trước đó nên khả năng trùng lặp giữa các đường thi hành là rất cao Hơn nữa, nếu có sự xuất hiện của vòng lặp,

số lần lặp khi thực thi bộ đầu vào càng nhiều, số lượng các ràng buộc sinh ra từ đường thi hành sẽ càng lớn, dẫn đến số lượng đường thi hành mới có thể được sinh

ra từ đường thi hành này rất là nhiều Nhìn chung, kĩ thuật kiểm thử theo hướng tĩnh

có số lượng đường thi hành và các ca kiểm thử để đạt được độ phủ tối đa là xác định được, còn theo hướng động thì là chưa xác định được cụ thể trước khi kết thúc quá trình kiểm thử

- Về thời gian kiểm thử: Thời gian sinh ca kiểm thử trong kĩ thuật kiểm thử theo hướng

động sẽ lâu hơn so với theo hướng tĩnh Điều đó là do hai lí do Thứ nhất, số lượng

ca kiểm thử cấn sinh ra khi sử dụng kĩ thuật kiểm thử theo hướng tĩnh là lớn hơn,

Mã nguồn 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

Trang 24

10

trong khi thời gian sinh mỗi ca kiểm thử của cả 2 kĩ thuật là tương đương nhau Thứ hai, với việc kiểm thử theo hướng động, mỗi lần sinh ra ca kiểm thử mới, chương trình sẽ lại phải thực thi thêm một lần

- Khả năng kiểm thử vòng lặp: Kĩ thuật kiểm thử theo hướng tĩnh cho phép chúng ta

có thể kiểm thử từng vòng lặp một trong các vòng lặp lồng nhau với số lần lặp có thể tùy ý Trong khi đó, kĩ thuật kiểm thử theo hướng động chỉ hỗ trợ kiểm thử các vòng lặp một cách đồng thời thay vì riêng rẽ, và số lần lặp là ngẫu nhiên, không xác định theo ý muốn của người kiểm thử

- Tính phức tạp mã nguồn: Hiện nay, các mã nguồn ngày càng phức tạp và được viết

với nhiều quy tắc, phong cách lập trình khác nhau Do đó, việc phân tích mã nguồn trong kĩ thuật kiểm thử theo hướng tĩnh rất là khó khăn và còn có thể không phân tích được Nhưng kĩ thuật kiểm thử theo hướng động hoàn toàn có thể bỏ qua những

sự phức tạp đó Nguyên nhân chính do kiểm thử theo hướng động tận dụng được thế mạnh trình biên dịch để sinh ca kiểm thử mới Kĩ thuật này không làm việc trực tiếp với mã nguồn mà thông qua trình biên dịch nên nó có thể bỏ qua được độ phức tạp

mã nguồn để sinh các ca kiểm thử

Trang 25

11

Phương pháp sinh ca kiểm thử tự động dòng điều khiển cho các đơn vị của chương trình Java

3.1 Tổng quan về phương pháp kiểm thử đề xuất

Khóa luận đề xuất một phương pháp sinh ca kiểm thử tự động cho các đơn vị chương trình Java Phương pháp sử dụng kĩ thuật kiểm thử tự động hộp trắng dòng điều khiển theo hướng tĩnh Đầu vào bao gồm một hàm Java có chứa các biến số nguyên, số thực, các biến mảng và tiêu chí phủ kiểm thử, số vòng lặp tối đa Đầu ra là tập các ca kiểm thử đáp ứng được tiêu chí phủ kiểm thử và tập các ca kiểm thử cho kiểm thử các vòng lặp

Hình 3.1 Quy trình kiểm thử một hàm java theo phương pháp đề xuất

Quy trình kiểm thử một hàm đơn vị Java được mô tả chi tiết trong Hình 3.1 Phương pháp gồm những bước chính sau:

Bước 1 Sinh đồ thị dòng điều khiển CFG bằng kĩ thuật phân tích mã nguồn hàm đầu

vào

Trang 26

12

Bước 2 Sinh tập các đường đi độc lập từ đồ thị CFG bằng thuật toán duyệt theo chiều

sâu Các đường đi độc lặp là các đường đi từ điểm bắt đầu đến điểm kết thúc của đồ thị dòng điều khiển

Bước 3 Phân tích các đường đi độc lập để thu được tập các đường kiểm thử có thể

đạt được độ phủ thỏa mãn tiêu chí kiểm thử

Bước 4 Các đường kiểm thử có chứa vòng lặp được xử lí để sinh tập đường kiểm

thử cho các vòng lặp

Bước 5 Sử dụng kĩ thuật thực thi tượng trưng SE để sinh được các hệ ràng buộc từ

các đường thi hành Mỗi đường thi hành sẽ có một hệ ràng buộc tương ứng

Bước 6 Giải các hệ ràng buộc để sinh các ca kiểm thử tương ứng Ở bước này, có

hai kĩ thuật phổ biến để giải hệ ràng buộc là SMT-Solver và sinh ngẫu nhiên

Bước 7 Thực thi các ca kiểm thử và đưa ra báo cáo kết quả kiểm thử

3.2 Sinh đồ thị CFG

Thuật toán 1 CFG_Generation(f, t)

Đầu vào: f: một khối các câu lệnh viết bằng ngôn ngữ Java; t:

tiêu chí phủ

Đầu ra: CFG: đồ thị dòng điều khiển của khối lệnh f ứng với độ

phủ t, CFG là biến toàn cục với khởi tạo là đồ thị rỗng

1: s := các khối lệnh con trong khối lệnh đầu vào f 2: for (mỗi câu lệnh con c trong s)

3: if (c là câu lệnh điều khiển) 4: node := đỉnh điều khiển của c

5: Thêm node vào CFG

6: Tạo liên kết giữa node với các đỉnh khác

7: true_node := khối lệnh của nhánh true

Trang 27

13

15: CFG_Generation (c, t)

16: else 17: //c là đỉnh thông thường

18: node := đỉnh đại diện cho c

19: Thêm node vào CFG

20: Tạo liên kết giữa node với các đỉnh khác

21: end if 22: end for

Đồ thị CFG là một phần rất quan trọng trong phương pháp kiểm thử tự động hộp trắng dòng điều khiển theo hướng tĩnh Nó biểu diễn mã nguồn một cách chi tiết và trực quan nhất Theo phương pháp này, chúng ta tập trung phân tích và xử lí trên đồ thị CFG để sinh các ca kiểm thử chứ không làm việc trực tiếp với mã nguồn

Chi tiết thuật toán sinh đồ thị dòng điều khiển của hàm Java thỏa mãn một tiêu chuẩn phủ kiểm thử cho trước được trình bày ở Đầu vào thuật toán gồm một khối đoạn mã Java đượ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 CFG Đầu tiên, toàn bộ khối mã nguồn của hàm được truyền vào để xử lý, nó bao gồm một danh sách các câu lệnh bên trong Sau đó, thuật toán duyệt qua từng câu lệnh này và xem xét kiểu của câu lệnh và đưa ra các loại xử lý phù hợp (dòng 2) Đối với các câu lệnh có điều kiện (thí dụ if, for, while, v.v.), điểm điều kiện được đưa vào đồ thị và tạo liên kết (dòng 5, 6) Khi tiêu chí phủ là phủ điều kiện con, điểm điều kiện này sẽ được tách ra thành các điều kiện con trước khi được đưa vào đồ thị Tiếp đó, thuật toán xác định các câu lệnh ứng với nhánh true và false của điều kiện, tiếp tục quá trình xây dựng đồ thị từ các câu lệnh này (dòng 8, 10) Đối với các câu lệnh đặc biệt, thuật toán sẽ xác định đích đến tiếp theo của chúng và liên kết với nhau trong đồ thị (dòng 12, 13) Thí

dụ, câu lệnh return sẽ liên kết tới đỉnh cuối cùng của đồ thị thay vì câu lệnh tiếp theo của

nó trong mã nguồn Đối với câu lệnh thường (thí dụ khởi tạo, gán giá trị, v.v.), đỉnh đại diện cho câu lệnh sẽ được đưa vào đồ thị và liên kết với các câu lệnh khác (dòng 19, 20) Cuối cùng, ta thu được một đồ thị CFG hoàn chỉnh sau khi tất cả các câu lệnh đã được duyệt

Ví dụ cụ thể, Hình 3.2 mô tả đồ thị CFG của hàm average có mã nguồn như Hình 3.3

thỏa mãn tiêu chí phủ nhánh Đầu tiên, mã nguồn sẽ được chia làm bốn phần: câu lệnh khai

báo (dòng 1), khối câu lệnh while (dòng 2 đến 9), khối câu lệnh if (dòng 10, 11) và câu lệnh

Trang 28

14

return dòng 12 Với câu lệnh khởi tạo vào câu lệnh return, một đỉnh trên đồ thị CFG được

khởi tạo để đại diện cho chúng Các khối lệnh while và if sẽ tiếp tục được phân chia thành các khối nhỏ hơn Đối với khối câu lệnh while, nó được chia thành hai phần nhỏ hơn nữa

là câu lệnh điều kiện dòng 2 và khối câu lệnh ở phần thân (dòng 3 đến 8) Sau đó, khối câu lệnh từ dòng 3 đến dòng 8 tiếp tục được phân chia thành 4 phần là câu lệnh gán dòng 3,

khối câu lệnh if (dòng 4, 5, 6) và câu lệnh gán dòng 8 Tiếp theo, khối câu lệnh if lại gồm câu lệnh điều kiện (dòng 4), hai câu lệnh gán (dòng 4, 5) Tương tự, khối câu lệnh if ở dòng

10, 11 được chia thành câu lệnh điều kiện (dòng 4) và câu lệnh gán dòng 5 Khi mã nguồn

đã được phân chia đến mức câu lệnh đơn, mỗi câu lệnh đơn được tạo một đỉnh tương ứng trong đồ thị CFG Cuối cùng, sau khi tạo liên kết giữa các đỉnh, một đồ thị CFG của hàm

average ứng với tiêu chí phủ câu lệnh được xây dựng xong

Hình 3.2 Đồ thị CFG của hàm average tiêu chuẩn phủ câu lệnh

Để có thể phân tích được mã nguồn chương trình một cách hiệu quả, thư viện JDT được sử dụng để chuyển đổi hỗ trợ mã nguồn thành định dạng cây cấu trúc trừu tượng

Trang 29

15

(Abstract Syntax Tree – AST) Sau đó, một thuật toán được sử dụng để phân tích trên cây AST này và sinh ra đồ thị CFG tương ứng

Hình 3.3 Mã nguồn hàm average

3.2.1 Tổng quan phương pháp sinh đồ thị CFG

Chi tiết quy trình phân tích mã nguồn một hàm viết bằng ngôn ngữ Java để xây dựng

đồ thị dòng điều khiển CFG được trình bày như Hình 3.4 Quy trình thực hiê ̣n gồm ba pha:

Hình 3.4 Tổng quan phương pháp sinh đồ thị CFG từ mã nguồn

 Pha 1: Sử du ̣ng JDT (Java Development Tooling) phân tích mã nguồn hàm java để

xây dựng cây cấu trúc trừu tượng AST tương ứng

 Pha 2: Xây dựng đồ thị CFG từ cây AST ứng với mã nguồn hàm Java

public double average(int value[], int min, int max){

Xây dựng đồ thị CFG

Chuẩn hóa biểu thức

Mã nguồn hàm Java

Trang 30

- Tên của hàm số: chương trình sẽ dùng tên này để tìm kiếm hàm số khi nó được gọi trong thân hàm của một hàm số khác

- Kiểu trả về của hàm số: được dùng để tạo giá trị cụ thể từ một chuỗi string đầu vào

- Danh sách các tham số cần được truyền vào hàm, đây là các biến số cần được tìm giá trị để kiểm tra sự đúng đắn của hàm số

- Phần thân hàm: là một cây cấu trúc AST chứa các câu lệnh cũng như các biểu thức bên trong từng câu lệnh Cấu trúc này được công cụ sử dụng cho việc sinh đồ thị CFG cũng như phục vụ phân tích hệ ràng buộc sau này

3.2.3 Phân tích cây AST từ mã nguồn

Với đầu vào là mã nguồn hàm Java, cây AST tương ứng với đầu vào này được sinh

ra bằng cách sử dụng plugin JDT Plugin này là một phần của IDE Eclipse và có thể chạy

độc lập (stand-alone)

Cấu trúc cây AST của một class Java các thành phần chính sau:

cập (public, private, v.v.), kiểu trả về, khai báo tên và tham số và thân hàm Phần

khai báo gồm có tên hàm và danh sách các khai báo tham số cho hàm Ví dụ: định

nghĩa hàm “public int min(int a, int b){…}” có nhãn giới hạn độ truy cập public,

1 Java Development Tooling: https://eclipse.org/jdt/

Trang 31

Khai báo class: Một khai báo class chứa nhãn giới hạn độ truy cập (public, private,

v.v.) , tên class và phần thân Phần thân class gồm các nút khai báo biến thuộc tính,

các nút định nghĩa hàm

Sau đó, cây AST của hàm cần kiểm thử được xây dựng Cây AST này sẽ được sử dụng để xây dựng đồ thị CFG dưới sự hỗ trợ của các Plugin JDT Hàm cần kiểm thử sẽ được chia thành các câu lệnh/khối câu lệnh, mỗi thành phần được biểu diễn bởi một nút trong cây AST Cấu trúc nút AST của các câu lệnh điển hình bao gồm:

 Câu lệnh khởi tạo: Cấu trúc của câu lệnh khởi tạo giống với cấu trúc của khai báo biến toàn cục, bao gồm tên kiểu khai báo và một danh sách các khai báo ứng với từng biến

 Câu lệnh gán: Một câu lệnh gán chứa một biểu thức gán bên trong nó Biểu thức

gán là một trường hợp của biểu thức 2 bên (BinaryExpression), gồm 2 biểu thức con và một phép toán ở giữa VD: biểu thử thức x+y gồm hai biểu thức x và y cùng với phép toán +

 Câu lệnh khối (được bao bởi cặp dấu ngoặc nhọn “{ }”) bao gồm danh sách các câu lệnh chứa bên trong nó

Câu lệnh if else: Nút câu lệnh if gồm ba thành phần là phần điều kiện, câu lệnh

nhánh đúng và câu lệnh nhánh sai

Câu lệnh for: Nút câu lệnh for bao gồm bốn thành phần: câu lệnh khởi tạo, biểu

thức điều kiện, biểu thức lặp bước, phần thân

Câu lệnh do while: Một nút câu lệnh do while bao gồm phần thân vòng lặp và

phần điều kiện lặp

Các câu lệnh đơn đặc biệt: Các câu lệnh như return, break, continue, v.v

Ngày đăng: 04/11/2020, 23:41

TỪ KHÓA LIÊN QUAN