1. Trang chủ
  2. » Giáo Dục - Đào Tạo

Nghiên cứu phương pháp sinh dữ liệu kiểm thử từ mã nguồn và ứng dụng xây dựng hệ thống chấm bài tập lập trình

60 116 1

Đ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 60
Dung lượng 1,09 MB

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

Nội dung

Chương 2: Phương pháp sinh dữ liệu kiểm thử dòng điều khiển Chương này trình bày tổng quan về phương pháp kiểm thử dòng điều khiển từ đồ thị dòng điều khiển Control Flow Graph - CFG của

Trang 1

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

Trang 2

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

Mã số: 848 01 03.01

LUẬN VĂN THẠC SĨ Ngành: Kỹ Thuật Phần Mềm

NGƯỜI HƯỚNG DẪN KHOA HỌC: PGS TS Phạm Ngọc Hùng

HÀ NỘI – 2019

Trang 3

VIETNAM NATIONAL UNIVERSITY, HANOI UNIVERSITY OF ENGINEERING AND TECHNOLOGY

NGUYEN THI KHANH CHI

A METHOD FOR AUTOMATED TEST DATA GENERATION FROM SOURCE CODE AND APPLICATION IN BUILDING PROGRAMMING

MARKING SYSTEM

THE MS THESIS Major: InformationTechnology

Supervisor: Assoc Prof Pham Ngoc Hung

HANOI - 2019

Trang 4

MỤC LỤC

MỤC LỤC i

LỜI CẢM ƠN iii

TÓM TẮT iv

ABSTRACT v

LỜI CAM ĐOAN vi

DANH MỤC THUẬT NGỮ VIẾT TẮT vii

DANH MỤC HÌNH VẼ viii

DANH MỤC BẢNG x

Chương 1: Mở đầu 1

Chương 2: Phương pháp sinh dữ liệu kiểm thử dòng điều khiển 3

2.1Tổng quan về kiểm thử dòng điều khiển 3

2.2Các tiêu chí kiểm thử 4

2.3Xây dựng đồ thị dòng điều khiển 6

2.3.1.Xây dựng đồ thị dòng điều khiển ứng với tiêu chí phủ câu lệnh và phủ nhánh 8

2.3.2 Xây dựng CFG ứng với tiêu chí phủ điều kiện con 9

2.3.3 Phương pháp xây dựng CFG từ mã nguồn Java 10

2.4 Sinh đường đi kiểm thử từ đồ thị 12

2.4.1 Sinh đường đi thỏa mãn tiêu chí phủ câu lệnh 12

2.4.2 Sinh đường đi thỏa mãn tiêu chí phủ nhánh 13

2.4.3 Sinh đường đi thỏa mãn tiêu chí phủ điều kiện con 13

2.4.4 Phương pháp sinh đường đi kiểm thử trên đồ thị 14

2.5 Sinh ca kiểm thử từ đường đi 15

2.5.1 Sinh dữ liệu kiểm thử 15

2.5.2 Sinh đầu ra mong muốn 17

2.6 Sinh các ca kiểm thử giá trị biên và vòng lặp 17

2.6.1.Sinh ca kiểm thử giá trị biên 18

2.6.2 Sinh ca kiểm thử vòng lặp 19

Chương 3: Công cụ và thực nghiệm 22

Trang 5

3.1Đặc tả hệ thống chấm bài lập trình 22

3.1.1 Danh sách các tác nhân 22

3.1.2 Mô tả các ca sử dụng của hệ thống: 24

3.2 Kiến trúc tổng thể của hệ thống chấm bài lập trình 27

3.3Kiến trúc của mô-đun sinh ca kiểm thử tự động 28

3.4Giới thiệu công cụ sinh ca kiểm thử tự động 29

3.3.1.Giao diện công cụ sinh ca kiểm thử tự động 29

3.3.2.Đồ thị dòng điều khiển 29

3.3.3.Tập các đường kiểm thử 31

3.3.4 Tập các ca kiểm thử 31

3.5Kết quả thực nghiệm 33

Bài toán 1: Bài toán kiểm tra năm nhuận 33

Bài toán 2: Bài toán tính số ngày trong một tháng 35

Bài toán 3: Tìm ước số chung lớn nhất 40

3.6 Ý nghĩa của thực nghiệm 44

Chương 4: Kết luận 46

TÀI LIỆU THAM KHẢO 47

Trang 6

LỜI CẢM ƠN

Trước tiên, tôi xin gửi lời cảm ơn chân thành và sâu sắc đến người thầy đáng kính PGS TS Phạm Ngọc Hùng - người đã trực tiếp hướng dẫn, chỉ bảo và giúp đỡ tôi trong suốt quá trình tôi học tập và nghiên cứu tại trường Nhờ có lòng tốt của thầy,

sự say mê nghiên cứu khoa học, kiến thức uyên thâm và sự hướng dẫn tận tình, tôi đã vượt qua được những khó khăn từ phía gia đình để tiếp tục học tập, nghiên cứu và hoàn thiện luận văn này

Tôi xin chân thành cảm ơn các thầy cô giáo khoa Công nghệ thông tin, trường Đại học Công nghệ, Đại học Quốc Gia Hà Nội đã nhiệt tình giảng dạy, truyền đạt những kiến thức quý báu trong suốt quá trình tôi học tập và nghiên cứu tại trường Tôi xin chân thành cảm ơn những người thân trong gia đình, các bạn bè, đồng nghiệp luôn tạo điều kiện, giúp đỡ động viên tôi trong công tác nghiên cứu khoa học Cuối cùng, tôi xin cảm ơn ban giám hiệu trường THPT Ngô Gia Tự - Từ Sơn - Bắc Ninh nơi tôi công tác, các đồng nghiệp và các em học sinh khối 11 đã tạo điều kiện tối đa, đóng góp những nhận xét khách quan cho đề tài nghiên cứu để tôi có thể hoàn thành luận văn Thạc sỹ tại trường Đại học Công nghệ - Đại học Quốc Gia Hà Nội

Trang 7

TÓM TẮT

Luận văn tập trung nghiên cứu phương pháp sinh các ca kiểm thử từ mã nguồn

và ứng dụng trong việc tự động chấm các bài tập lập trình của học sinh viết bằng ngôn ngữ Java nhằm hỗ trợ các giáo viên Tin học tại các Trường Trung học phổ thông/Trung học cơ sở trong việc sinh các ca kiểm thử và chấm các bài tập lập trình của học sinh Với mỗi bài tập, giáo viên sẽ cung cấp mã nguồn mẫu (mã nguồn không

có lỗi) Dựa vào mã nguồn này, chúng ta sẽ tiến hành phân tích nhằm xây dựng đồ thị dòng điều khiển của mã nguồn Tiếp đến, các đường đi của đồ thị ứng với các dòng điều khiển có thể có của chương trình sẽ được sinh Từ các đường đi này, chúng ta sẽ xây dựng hệ ràng buộc chứa các điều kiện của các tham số Việc sinh dữ liệu kiểm thử trên đường thực thi chính là việc giải hệ ràng buộc trên đường đi tương ứng Khi có dữ liệu kiểm thử, chúng ta sẽ sử dụng đầu ra của mã nguồn chuẩn để sinh giá trị đầu ra mong muốn tương ứng Cùng với các ca kiểm thử đã được sinh ra, luận văn còn nghiên cứu các giải pháp để sinh các ca kiểm thử cho các vòng lặp và sinh các ca kiểm thử tại các biên của từng tham số ứng với miền giá trị và đặc tả của bài toán

Luận văn cũng đã tiến hành xây dựng công cụ hỗ trợ và áp dụng thử nghiệm với các chương trình đơn giản nhằm minh chứng cho tính đúng đắn và tính hiệu quả của phương pháp đề xuất Tuy nhiên, công cụ cài đặt chưa được hoàn thiện và cần được tiếp tục phát triển nhằm có một công cụ hỗ trợ giáo viên như đã nêu ở trên

Từ khóa: Kiểm thử tự động, sinh dữ liệu kiểm thử, độ phủ kiểm thử, kiểm thử hộp

trắng

Trang 8

ABSTRACT

The thesis focuses on studying the method of testing data from source code and applying in automatically marking students' programming exercises written in Java language to support Informatics teachers at high schools information / junior high school in testing test cases and marking students' programming exercises For each teacher exercise, the teacher will provide sample source code (source code without errors) Based on this source code, we will conduct source code analysis to build control line graph of source code Next, we will generate the graph's paths corresponding to the possible control lines of the program From these paths, we will build the binding system without the conditions of the parameters Generating test data corresponding to the corresponding path is the finding of a solution of the corresponding system of equations Whenever there is test data, we will use the specification to generate the desired output values Along with the test cases as born, the thesis also studies solutions to generate test cases for loops and generate test cases

at the boundaries of each parameter corresponding to the value domain and specification of the problem

The thesis has also developed support tools and applied experiments with simple programs to demonstrate the correctness and effectiveness of the proposed method However, the installation tool has not been completed and needs to be further developed in order to have a teacher support tool as mentioned above

Keywords: Automated testing, test data generation, test coverage, white-box

testing

Trang 9

LỜI CAM ĐOAN

Tôi xin cam đoan luận văn Thạc sỹ Công nghệ thông tin "Phương pháp sinh dữ liệu kiểm thử từ mã nguồn và ứng dụng xây dựng hệ thống chấm bài tập lập trình" là công trình nghiên cứu của tôi dưới sự hướng dẫn của Thầy hướng dẫn, không sao chép lại của người khác Trong toàn bộ nội dung luận văn, những điều được trình bày là của

cá nhân tôi hoặc là được tổng hợp từ các nguồn tài liệu khác Tất cả các nguồn tài liệu tham khảo đều có trích dẫn cụ thể và hợp pháp

Tôi xin hoàn toàn chịu trách nhiệm và chịu mọi hình thức kỷ luật theo quy định của trường Đại học Công Nghệ - Đại học Quốc Gia Hà Nội cho lời cam đoan này

Hà Nội, ngày 26 tháng 03 năm 2019

Nguyễn Thị Khánh Chi

Trang 10

DANH MỤC THUẬT NGỮ VIẾT TẮT

7 SMT-Solver Satisfiability Modulo Theories

Solver

Trang 11

DANH MỤC HÌNH VẼ

Hình 2.1 Tổng quan quy trình kiểm thử dòng điều khiển 3

Hình 2.2 Mã nguồn hàm laNamNhuan 5

Hình 2.3 Các thành phần cơ bản của đồ thị dòng điều khiển 7

Hình 2.4 Các cấu trúc điều khiển cơ bản của đồ thị dòng điều khiển 7

Hình 2.5 Mã nguồn và CFG ứng với tiêu chí phủ câu lệnh hàm laNamNhuan 8

Hình 2.6 Mã nguồn và CFG ứng với tiêu chí phủ điều kiện con hàm laNamNhuan 9

Hình 2.7 Mã nguồn và CFG ứng với tiêu chí phủ câu lệnh hàm laNamNhuan 13

Hình 2.8 Mã nguồn và CFG ứng với tiêu chí phủ điều kiện con hàm laNamNhuan 14

Hình 2.9 Mã nguồn và CFG ứng với tiêu chí phủ nhánh hàm giaithua 20

Hình 3.1 Biểu đồ ca sử dụng của hệ thống chấm bài lập trình 23

Hình 3.2 Kiến trúc tổng thể của hệ thống chấm bài lập trình 27

Hình 3.3 Kiến trúc của mô-đun sinh ca kiểm thử tự động 28

Hình 3.4 Giao diện của công cụ sinh ca kiểm thử tự động 29

Hình 3.5 CFG ứng với tiêu chí phủ câu lệnh và phủ nhánh hàm laNamNhuan 30

Hình 3.6 CFG ứng với tiêu chí phủ điều kiện con hàm laNamNhuan 30

Hình 3.7 Chi tiết các đường kiểm thử cho tiêu chí phủ nhánh hàm laNamNhuan 31

Hình 3.8 Chi tiết các ca kiểm thử cho tiêu chí phủ câu lệnh của hàm laNamNhuan 32

Hình 3.9 Kết quả kiểm thử được xuất dưới dạng MS Excel hàm laNamNhuan 32

Hình 3.10 Mã nguồn chuẩn của hàm laNamNhuan 33

Hình 3.11 Chi tiết ca kiểm thử cho tiêu chí phủ điều kiện con ham laNamNhuan 33

Hình 3.12 Mã nguồn hàm laNamNhuan1 của học sinh thứ nhất 34

Hình 3.13 Mã nguồn hàm laNamNhuan2 của học sinh thứ hai 34

Hình 3.14 Mã nguồn chuẩn của hàm songay 36

Hình 3.15 Chi tiết ca kiểm thử cho tiêu chí phủ điều kiện con hàm songay 36

Hình 3.16 Mã nguồn hàm songayhs_1 của học sinh thứ nhất 37

Hình 3.17 Mã nguồn hàm songayhs_2 của học sinh thứ hai 37

Hình 3.18 Mã nguồn chuẩn của hàm timuscln 40

Hình 3.19 Chi tiết các ca kiểm thử cho tiêu chí phủ nhánh hàm timuscln 40

Trang 12

Hình 3.20 Chi tiết các ca kiểm thử phủ tất cả các nhánh hàm timuscln 41 Hình 3.21 Mã nguồn hàm timuscnl_1 của học sinh thứ nhất 41 Hình 3.22 Mã nguồn hàm timuscln_2 của học sinh thứ hai 41

Trang 13

DANH MỤC BẢNG

Bảng 2.1 Các ca kiểm thử cho tiêu chí phủ câu lệnh của hàm laNamNhuan 5

Bảng 2.2 Các trường hợp cần kiểm thử với tiêu chí phủ nhánh cho hàm laNamNhuan 5 Bảng 2.3 Các trường hợp cần kiểm thử với tiêu chí phủ điều kiện con của hàm laNamNhuan 6

Bảng 2.4 Các ca kiểm thử cho tiêu chí phủ điều kiện con hàm laNamNhuan 6

Bảng 2.5 Dữ liệu kiểm thử cho tiêu chí phủ điều kiện con hàm laNamNhuan 16

Bảng 2.6 Các ca kiểm thử cho tiêu chí phủ câu lệnh hàm laNamNhuan 17

Bảng 2.7 Các ca kiểm thử giá trị biên cho hàm laNamNhuan 18

Bảng 2.8 Các ca kiểm thử cho tiêu chí phủ nhánh hàm giaithua 20

Bảng 2.9 Các ca kiểm thử vòng lặp for hàm giaithua 21

Bảng 3.1 Danh sách tác nhân của hệ thống chấm bài lập trình 22

Bảng 3.2 Danh sách các ca sử dụng của hệ thống chấm bài lập trình 23

Bảng 3.3 Kết quả kiểm thử bài tập kiểm tra năm nhuận của hai học sinh 34

Bảng 3.4 Các ca kiểm thử giá trị biên cho hàm laNamNhuan 35

Bảng 3.5 Kết quả kiểm thử giá trị biên bài tập kiểm tra năm nhuận của hai học sinh 35 Bảng 3.6 Kết quả kiểm thử bài tập tính số ngày trong tháng của hai học sinh 38

Bảng 3.7 Các ca kiểm thử giá trị biên cho hàm songay 39

Bảng 3.8 Kết quả kiểm thử giá trị biên bài tập tính số ngày trong tháng của hai học sinh 39

Bảng 3.9 Kết quả kiểm thử bài tập tìm ước số chung lớn nhất của hai học sinh 42

Bảng 3.10 Các ca kiểm thử giá trị biên cho hàm timuscln 43

Bảng 3.11 Kết quả kiểm thử giá trị biên bài tập tìm uscln của hai của học sinh 43

Bảng 3.12 Các ca kiểm thử vòng lặp while cho hàm timuscln 44

Bảng 3.13 Kết quả kiểm thử vòng lặp while cho hàm tìm uscln của hai học sinh 44

Trang 14

Chương 1: Mở đầu

Hiện nay, môn học lập trình đã được đưa vào giảng dạy ở các trường Trung học phổ thông (THPT) trên toàn quốc, giúp các em học sinh làm quen với công việc lập trình và làm quen dần với tư duy thiết kế các thuật toán Ngôn ngữ lập trình được sử dụng để giảng dạy trong hầu hết các trường THPT là Pascal Tuy nhiên, theo chương trình giáo dục THPT mới, trên cơ sở định hướng lập trình và tùy chọn ngôn ngữ, nhiều trường THPT đã bước đầu đưa các ngôn ngữ lập trình phổ biến như C, Java, v.v vào giảng dạy Trong quá trình giảng dạy, công việc chấm bài tập lập trình đối với người giáo viên thường diễn ra thủ công và tiềm ẩn nhiều sai sót Do thời gian chấm bài có hạn nên việc không phát hiện ra các lỗi trong bài lập trình là không tránh khỏi Điều này dẫn đến điểm chấm chưa thực sự chính xác và công bằng Làm thế nào để công việc chấp bài lập trình được dễ dàng hơn với các giáo viên, cũng như đảm bảo tính chính xác, rút ngắn thời gian chấm bài là mục tiêu cần hướng tới

Đối với các bài tập lập trình, việc chấm bài chính là rà soát để phát hiện các lỗi

có thể có trên mã nguồn của bài tập học sinh Khi chương trình xuất hiện lỗi cú pháp, các lỗi sẽ được trình biên dịch phát hiện để người lập trình sửa lỗi Tuy nhiên, ngay cả khi một chương trình không có lỗi cú pháp thì chương trình vẫn chưa chắc đã đúng vì lỗi có thể xảy ra trong quá trình thiết kế giải thuật Làm thế nào để hỗ trợ giáo viên kiểm tra xem chương trình có thực hiện đúng với đặc tả yêu cầu của bài toán hay không, hoặc đúng bao nhiêu phần so với đặc tả của bài toán chính là mục tiêu của quá trình chấm bài Hơn nữa, việc giáo viên cung cấp các cơ chế cho phép học sinh tự làm bài và tương tác qua các ứng dụng nhằm nâng cao khả năng tự học và tăng cường chất lượng là một xu hướng tất yếu trong hệ thống giáo dục thời gian tới Vì vậy, nhu cầu

về bài toán này càng cấp thiết hơn

Để giải quyết vấn đề này, ứng với mỗi bài toán, giáo viên phải sinh ra một bộ ca kiểm thử đủ tốt (có khả năng phát hiện tất cả các lỗi có thể có của bài lập trình của học sinh) Bộ ca kiểm thử này sau đó sẽ được sử dụng để chấm các chương trình cho học sinh nộp (tự động hoặc thủ công tùy thuộc vào phương pháp và công cụ mà giáo viên

sử dụng) Hiện tại, việc sinh ra các bộ ca kiểm thử như vậy là vượt ngoài khả năng của các giáo viên Trung học phổ thông Vì vậy, có một công cụ tự động hỗ trợ giáo viên giải quyết bài toán này là một vấn đề cấp thiết, có ý nghĩa thực tiễn cao Một trong những giải pháp để giải quyết vấn đề này là sinh dữ liệu kiểm thử từ mã nguồn sử dụng phương pháp kiểm thử dòng dữ liệu [2, 3, 4, 8, 9, 11] Trong phương pháp này, ứng với đặc tả của mỗi bài toán, thay vì yêu cầu giáo viên phải sinh bộ ca kiểm thử,

họ sẽ phải cung cấp mã nguồn mẫu (mã nguồn của bài toán tương ứng mà không có lỗi) Phương pháp này sẽ tự động sinh các ca kiểm thử (bao gồm dữ liệu kiểm thử và giá trị đầu ra mong muốn tương ứng) từ mã nguồn được giáo viên cung cấp Sau khi

Trang 15

hoàn tất quá trình này, giáo viên sẽ có một bộ dữ liệu kiểm thử bao quát hết các nhánh của mã nguồn Tuy nhiên, phương pháp này [2, 3] chỉ cho phép phát hiện những lỗi tiềm ẩn trong mã nguồn (có đặc tả và được lập trình hoặc không có đặc tả và được lập trình) Phương pháp này không kiểm tra được các lỗi ứng với tình huống có đặc tả và không được lập trình (thường được phát hiện bởi các phương pháp kiểm thử hộp đen) Phương pháp đề xuất trong [2] mới sinh được các dữ liệu kiểm thử, chưa sinh được đầu ra mong muốn, do đó không hỗ trợ được giáo viên trong việc sinh các ca kiểm thử mẫu Trong [3] đã sinh được các ca kiểm thử cho mã nguồn Java nhưng chưa hỗ trợ xây dựng hệ thống chấm bài

Mục tiêu của luận văn này là hướng đến nghiên cứu giải pháp và xây dựng bộ công cụ hỗ trợ giáo viên chấm bài lập trình một cách tự động nhằm giải quyết các vấn

đề như mô tả ở trên Mấu chốt của giải pháp này là phương pháp sinh dữ liệu kiểm thử

từ mã nguồn Bản chất của các phương pháp này là phụ thuộc vào ngôn ngữ lập trình được sử dụng (mỗi ngôn ngữ lập trình thường có kỹ thuật sinh dữ liệu kiểm thử khác nhau vì chúng ta cần phải phân tích mã nguồn) Mặc dù ngôn ngữ lập trình được dùng phổ biến nhất trong các trường Trung học phổ thông là Pascal nhưng ngôn ngữ này chưa có công cụ phân tích cây cú pháp (nền tảng cho việc xây dựng đồ thị dòng điều khiển) Vì vậy, phương pháp sinh dữ liệu kiểm thử từ mã nguồn Pascal rất khó thực hiện trong luận văn này Ngôn ngữ C/C++ đã được quan tâm nghiên cứu với giải pháp khá tốt trong [2] Vì vậy, luận văn này tập trung nghiên cứu giải pháp cho ngôn ngữ Java Trong [3] đã nghiên cứu giải pháp tương tự cho Java nhưng chỉ dừng lại với các đơn vị chương trình (hàm, phương thức) Phương pháp này có thể sử dụng khi chương trình được viết bằng phương pháp hướng đối tượng Tuy nhiên, học sinh tại các trường Trung học phổ thông thường viết chương trình theo phương pháp hướng cấu trúc nên giải pháp này không sử dụng được Cùng với phương pháp này, luận văn cũng sẽ nghiên cứu các kỹ thuật kiểm thử hộp đen nhằm sinh bổ sung các ca kiểm thử cho phương pháp trên Một công cụ hỗ trợ cũng sẽ được phát triển và thực nghiệm với một

số chương trình đơn giản ở bậc Trung học phổ thông nhằm minh chứng cho kết quả của luận văn

Phần còn lại của đề tài nghiên cứu sẽ gồm những nội dung sau Chương 2 trình bày tổng quan phương pháp sinh dữ liệu kiểm thử dòng điều khiển từ mã nguồn Đây

là phương pháp chung, có thể áp dụng cho nhiều ngôn ngữ lập trình khác nhau, trong chương này cũng đề xuất phương pháp phân tích mã nguồn Java nhằm sinh ca kiểm thử cho các hàm Java Chương 3 giới thiệu công cụ hỗ trợ sinh ca kiểm thử tự động và kết quả thực nghiệm bằng cách áp dụng công cụ, cài đặt với một số chương trình đơn giản Cuối cùng, kết luận và các hướng nghiên cứu của luận văn sẽ được mô tả trong Chương 4

Trang 16

Chương 2: Phương pháp sinh dữ liệu kiểm thử dòng điều khiển

Chương này trình bày tổng quan về phương pháp kiểm thử dòng điều khiển từ đồ thị dòng điều khiển (Control Flow Graph - CFG) của chương trình nhằm sinh ca kiểm thử cho mã nguồn ứng với tiêu chí kiểm thử yêu cầu Phương pháp trình bày trong chương này có thể áp dụng cho hầu hết các ngôn ngữ lập trình

2.1 Tổng quan về kiểm thử dòng điều khiển

Kiểm thử dòng điều khiển là phương pháp kiểm thử hộp trắng nhằm phát hiện các lỗi tiềm ẩn xảy ra trên mã nguồn [1, 6] Phương pháp này dựa vào việc phân tích

mã nguồn nhằm xây dựng đồ thị dòng điều khiển ứng với các tiêu chí kiểm thử cho trước Dựa vào đồ thị này, một bộ dữ liệu kiểm thử sẽ được sinh ra đáp ứng 100% tiêu chí kiểm thử yêu cầu Người sử dụng sẽ sử dụng đặc tả của bài toán để sinh ra các ca kiểm thử từ bộ dữ liệu kiểm thử đã được sinh ra Bộ ca kiểm thử này sau đó sẽ được sử dụng để làm bộ kiểm thử mẫu thực hiện kiểm thử trên bài tập lập trình của học sinh phục vụ cho quá trình chấm bài

Hình 2.1 Tổng quan quy trình kiểm thử dòng điều khiển

Xây dựng CFG

Sinh đường đi kiểm thử

Sinh dữ liệu kiểm thử

Sinh đầu ra mong muốn

Trang 17

Quy trình kiểm thử dòng điều khiển của một hàm được mô tả như Hình 2.1 Đầu vào của quy trình là mã nguồn và tiêu chí kiểm thử yêu cầu Đầu ra của quy trình là báo cáo kiểm thử chứa các kết quả kiểm thử (ca kiểm thử nào phát hiện được lỗi và ca kiểm thử nào không phát hiện được lỗi) Chi tiết phương pháp bao gồm các bước sau:

- Bước 1: Sinh đồ thị dòng điều khiển Mã nguồn được phân tích dựa trên các tiêu chí

kiểm thử để xây dựng đồ thị dòng điều khiển Với mỗi tiêu chí kiểm thử là phủ câu lệnh, phủ nhánh và phủ điều kiện con, sẽ có một đồ thị dòng điều khiển tương ứng

- Bước 2: Sinh các đường đi kiểm thử Từ đồ thị dòng điều khiển, luận văn đề xuất

thuật toán duyệt đồ thị sao cho các đường đi kiểm thử được sinh ra đạt độ phủ thỏa mãn các tiêu chí đã đề ra

- Bước 3: Sinh ca kiểm thử Ca kiểm thử bao gồm bộ giá trị đầu vào được chọn để

thực hiện kiểm thử trên mỗi đường đi và giá trị đầu ra mong muốn tương ứng (Expected Output – EO) Ca kiểm thử được sinh ra bằng cách các hệ ràng buộc trên mỗi đường kiểm thử Giá trị đầu ra mong muốn được sinh từ đặc tả bài toán Kết thúc bước này, một tập các ca kiểm thử được sinh ra

- Bước 4: Thực thi các ca kiểm thử Thực thi các ca kiểm thử nhằm tạo ra báo cáo

kiểm thử trong đó chỉ ra ca kiểm thử nào phát hiện được lỗi, ca kiểm thử nào không phát hiện được lỗi

2.2 Các tiêu chí kiểm thử

Tiêu chí kiểm thử là chuẩn mực để đánh giá độ bao phủ của một tập ca kiểm thử

so với mã nguồn Nhằm tối ưu các ca kiểm thử, tiêu chí kiểm thử được đưa ra để thiết

kế các ca kiểm thử sao cho số ca kiểm thử là ít nhất những vẫn có thể kiểm tra được tối

đa các trường hợp (có thể mắc lỗi) xảy ra trên mã nguồn Các thành phần cần kiểm tra bao gồm câu lệnh, các đỉnh quyết định, các điều kiện con, đường thi thành hoặc sự kết hợp giữa chúng [1]

Có rất nhiều tiêu chí kiểm thử được áp dụng trong thực tế, dưới đây là ba tiêu chí kiếm thử đang được sử dụng rộng rãi [1, 2]:

- Phủ câu lệnh: Sau khi thực hiện các ca kiểm thử, mỗi dòng lệnh trên mã nguồn

phải được duyệt qua ít nhất một lần Giả sử, ta cần sinh các ca kiểm thử cho hàm

laNamNhuan có mã nguồn được hiển thị ở Hình 2.2 Để đạt được 100% tiêu chí

phủ câu lệnh cho hàm, ta cần thực hiện ba ca kiểm thử như Bảng 2.1 Giá trị EO (Expected Output) trên bảng là giá trị đầu ra mong muốn khi chạy ca kiểm thử,

RO (Real Output) là giá trị đầu ra thực tế (giá trị này sẽ được điền khi chạy các ca kiểm thử trong môi trường thực)

Trang 18

Hình 2.2 Mã nguồn hàm laNamNhuan

Bảng 2.1 Các ca kiểm thử cho tiêu chí phủ câu lệnh của hàm laNamNhuan

- Phủ nhánh: Sau khi thực hiện ca kiểm thử, các điểm quyết định trên mã nguồn

được duyệt theo cả hai nhánh đúng và sai Ví dụ, với hàm laNamNhuan, để đạt

được 100% tiêu chí phủ nhánh, ta cần thực hiện các ca kiểm thử để kiểm tra các điều kiện như Bảng 2.2 để các điểm quyết định ở câu lệnh 1 và câu lệnh 3 được duyệt qua cả hai nhánh đúng và sai

Bảng 2.2 Các trường hợp cần kiểm thử với tiêu chí phủ nhánh cho hàm laNamNhuan

Hàm laNamNhuan là một trường hợp đặc biệt, ba ca kiểm thử thỏa mãn tiêu chí

phủ câu lệnh cũng đồng thời thỏa mãn tiêu chí phủ nhánh Trong nhiều trường hợp khác, số ca kiểm thử ứng với tiêu chí phủ nhánh thường nhiều hơn số ca kiểm thử của tiêu chí phủ câu lệnh do các ca kiểm thử của tiêu chí phủ câu lệnh không phủ được hết các nhánh đúng và sai trên mã nguồn

- Phủ điều kiện con: Với các điểm quyết định có chứa điều kiện phức hợp (từ hai

điều kiện con trở lên), sau khi thực hiện các ca kiểm thử, tất cả các điều kiện con đều được duyệt qua cả hai nhánh đúng và sai Ví dụ, trong câu lệnh 3 của hàm

laNamNhuan có chứa điều kiện phức hợp là (year%400==0)|| ((year%4==0)&&(year%100!=0)) Nếu chỉ thực hiện kiểm thử với tiêu chí phủ

Trang 19

nhánh thì chỉ có điều kiện (year%400==0)được kiểm tra, còn hai điều kiện con

(year%4==0) và (year%100!=0) thì chưa được kiểm tra tới Chúng ta cần phải kiểm tra tất cả các nhánh trên các điều kiện trên mã nguồn thì mới đạt được tiêu chí phủ điều kiện con Bảng 2.3 là các trường hợp cần kiểm tra để mọi điều kiện

con trên hàm laNamNhuan đều được "ghé thăm".

Bảng 2.3 Các trường hợp cần kiểm thử với tiêu chí phủ điều kiện con của hàm

Bảng 2.4 Các ca kiểm thử cho tiêu chí phủ điều kiện con của hàm laNamNhuan

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

Đồ thị dòng điều khiển (CFG) là một phần rất quan trọng trong phương pháp kiểm thử dòng điều khiển CFG mô tả cấu trúc của mã nguồn thông qua một đồ thị có hướng với mỗi đỉnh tương ứng là một câu lệnh/nhóm lệnh CFG cho người dùng quan sát một cách trực quan các luồng điều khiển của mã nguồn Từ đó, chúng ta dễ dàng thiết kế các ca kiểm thử sao cho nó phủ hết các nhánh trên đồ thị này

Để xây dựng được CFG từ mã nguồn, ta quy ước mỗi câu lệnh/ nhóm lệnh trên

mã nguồn tương ứng là một đỉnh của đồ thị Nếu một câu lệnh j thực hiện ngay sau câu

Trang 20

lệnh i thì sẽ tồn tại một đường đi từ đỉnh i đến đỉnh j Mỗi tiêu chí kiểm thử, chúng ta

xây dựng được một CFG tương ứng [1]

Một CFG được xây dựng từ đỉnh bắt đầu (ứng lời khai báo hàm), đi qua các đỉnh

(các câu lệnh khai báo, câu lệnh gán, câu lệnh điều kiện, câu lệnh lặp, các khối xử lý )

theo thứ tự thực hiện trên mã nguồn và đi đến đỉnh kết thúc (ứng với điểm kết thúc

hàm) Các thành phần để xây dựng CFG được mô tả ở Hình 2.3 [1]

Hình 2.3 Các thành phần cơ bản của đồ thị dòng điều khiển

Ngoài đỉnh bắt đầu và đỉnh kết thúc, mỗi đỉnh là duy nhất trong đồ thị, các đỉnh

khác trong đồ thị tương ứng với một câu lệnh của mã nguồn, được đặt tên theo chức

năng của câu lệnh Đỉnh xử lý ứng với câu lệnh khai báo, gán giá trị hoặc các câu lệnh tính toán Đỉnh quyết định ứng với câu lệnh rẽ nhánh hoặc biểu thức điều kiện trong câu lệnh lặp Đỉnh nối là đỉnh tiếp theo được thực hiện ngay sau khi câu lệnh rẽ nhánh

hoặc lặp kết thúc [1, 2, 6]

Trong Java, các cấu trúc điều khiển bao gồm: cấu trúc tuần tự, cấu trúc rẽ nhánh

if…else, cấu trúc rẽ nhánh switch case, các cấu trúc lặp while do, do while Riêng

vòng lặp for, chúng ta sử dụng cấu trúc while do để thay thế (vì for là một trường hợp đặc biệt của while do với số lần lặp biết trước) Các ký hiệu đại diện cho mỗi cấu trúc

điều khiển được minh họa trên Hình 2.4 [1, 2] Chúng ta sẽ sử dụng các thành phần và cấu trúc ở Hình 2.3, Hình 2.4 cùng với các tiêu chí kiểm thử để xây dựng đồ thị dòng điều khiển cho mã nguồn

Hình 2.4 Các cấu trúc điều khiển cơ bản của đồ thị dòng điều khiển

Đỉnh quyết định

Đỉnh nối

Đỉnh kết thúc

Cấu trúc while do

Cấu trúc do while

Cấu trúc switch…case

Trang 21

2.3.1 Xây dựng đồ thị dòng điều khiển ứng với tiêu chí phủ câu lệnh và phủ nhánh

Chúng ta sẽ thực hiện xây dựng CFG từ mã nguồn theo các bước như sau: Đầu

tiên, ta đánh số thứ tự cho các câu lệnh trên mã nguồn Từ đỉnh bắt đầu ứng với lời gọi

hàm ta lần lượt nối các đỉnh theo thứ tự thực hiện câu lệnh trên mã nguồn [1, 2] Do tiêu chí phủ câu lệnh và phủ nhánh có các đường đi phủ toàn bộ các câu lệnh trên mã nguồn, nên CFG của hai tiêu chí này có hình dạng giống nhau CFG của tiêu chí phủ điều kiện con có cấu trúc phức tạp hơn do các đường đi trên đồ thị này phủ đến cả hai nhánh của các điều kiện con cơ bản

Hình 2.5 Mã nguồn và CFG ứng với tiêu chí phủ câu lệnh của hàm laNamNhuan

Giả sử, chúng ta xây dựng CFG ứng với tiêu chí phủ câu lệnh và phủ nhánh của hàm laNamNhuan có mã nguồn như Hình 2.5a Các câu lệnh được đánh số thứ tự cũng đồng thời là các đỉnh của đồ thị Đỉnh bắt đầu của đồ thị tương ứng với lời gọi hàm Đỉnh 1 là đỉnh quyết định tương ứng với câu lệnh 1 Đỉnh 2 là đỉnh xử lý ứng với câu

lệnh 2 (return -1) Nếu điều kiện tại đỉnh 1 (year<0) là đúng thì tồn tại đường đi

nối đỉnh 1 với đỉnh 2 rồi đi đến đỉnh kết thúc Ngược lại, nếu điều kiện tại đỉnh 1

(year<0) là sai thì đường đi sẽ nối từ đỉnh 1 tới đỉnh 3 tương ứng với câu lệnh 3

(year%400==0) || ((year%4==0) && (year%100!=0)) Đỉnh 3 là đỉnh quyết định

nên nếu điều kiện tại đỉnh 3 là đúng thì tồn tại đường đi nối đỉnh 3 với đỉnh 4 ứng với câu lệnh 4 (return 1) rồi nối đỉnh 4 đến đỉnh kết thúc Ngược lại, nếu điều kiện tại

đỉnh 3 là sai thì đường đi sẽ nối đỉnh 3 đến đỉnh 5 tương ứng với câu lệnh 5 (return 0) rồi nối đỉnh 5 đến đỉnh kết thúc Cuối cùng, ta dựng được đồ thị dòng điều khiển của hàm laNamNhuan thỏa mãn phủ toàn bộ các câu lệnh trên mã nguồn như Hình

2.5b Đây chính là CFG cho tiêu chí phủ câu lệnh và cũng là CFG cho tiêu chí phủ nhánh

Trang 22

2.3.2 Xây dựng CFG ứng với tiêu chí phủ điều kiện con

Trên các mã nguồn có chứa câu lệnh mang điều kiện phức hợp, chúng ta cần xây dựng CFG ứng với tiêu chí phủ điều kiện con Các điều kiện con thuộc điều kiện phức

hợp sẽ được tách các đỉnh con tương ứng trên CFG Cách xây dựng CFG với tiêu chí

phủ điều kiện con cũng tương tự như xây dựng CFG ứng với tiêu chí phủ câu lệnh

Hình 2.6 Mã nguồn và CFG ứng với tiêu chí phủ điều kiện con của hàm laNamNhuan

Ví dụ, ta cần xây dựng CFG với tiêu chí phủ điều kiện con của hàm laNamNhuan

như Hình 2.6a Trên mã nguồn, câu lệnh 3 chứa ba điều kiện con là

(year%400==0);(year%4==0) và (year%100!=0) nên ta tách đỉnh 3 thành các đỉnh

con 3a, 3b, 3c Đỉnh 1 là đỉnh quyết định, ứng với câu lệnh 1 Nếu điều kiện tại đỉnh 1

(year<0) là đúng thì tồn tại đường đi nối đỉnh 1 với đỉnh 2 tương ứng với câu lệnh 2

(return -1) rồi nối đến đỉnh kết thúc Nếu điều kiện tại đỉnh 1 (year<0) là sai thì đường đi sẽ nối đỉnh 1 với đỉnh 3a (year%400==0) Từ câu lệnh 3, toán tử kết hợp giữa điều kiện con 3a và điều kiện con 3b, 3c là toán tử hoặc "||" Do đó, nếu điều kiện tại đỉnh 3a(year%400==0)là đúng thì ta không cần xét đến các điều kiện còn lại

Ta sẽ có đường đi nối đỉnh 3a với đỉnh 4(return 1) rồi nối đến đỉnh kết thúc

Ngược lại, nếu điều kiện tại đỉnh 3a là sai thì ta cần xét tiếp các điều kiện tại đỉnh 3b

(year%4==0) và 3c (year%100!=0), ta có đường đi nối từ đỉnh 3a với 3b theo nhánh sai của đỉnh 3a Toán tử kết hợp giữa điều kiện con 3b (year%4==0) và 3c

(year%100!=0)là toán tử "&&", nên nếu điều kiện tại hai đỉnh 3b và 3c là đúng thì ta

có đường đi nối các đỉnh 3a(T), 3b(T)và nối với đỉnh 4 (return 1) rồi đi đến đỉnh

kết thúc Nếu một trong hai điều kiện tại đỉnh 3a (year%4==0) hoặc 3b

(year%100!=0) là sai thì đường đi sẽ nối một trong hai đỉnh theo nhánh sai của 3a và 3b nối với đỉnh 5(return 0) rồi nối đỉnh 5 đến đỉnh kết thúc Cuối cùng, ta dựng

được CFG ứng với tiêu chí phủ điều kiện con của hàm như Hình 2.6b

T

T 3b

Trang 23

2.3.3 Phương pháp xây dựng CFG từ mã nguồn Java

Để xây dựng CFG từ mã nguồn cho mã nguồn Java trong môi trường thực, chúng

ta cần có cấu trúc dữ liệu của mã nguồn tương ứng Cấu trúc này thường được sinh ra bằng cách sử dụng công cụ hỗ trợ JDT(Java Development Tooling) Công cụ này sẽ

phân tích các hàm đầu vào thành các cây cú pháp trừu tượng (Abstract Syntax Tree – AST) Trong bước này, phương pháp tập trung vào việc lấy được danh sách các khai báo hàm số có trong mã nguồn, sử dụng theo API của plugin JDT [3] Khi có được cây AST, chúng ta tiến hành phân tích cây cú pháp trừu tượng để xây dựng CFG cho mã nguồn Java Cuối cùng, chuẩn hóa định dạng các biểu thức trong cây cú pháp trừu tượng để phục vụ cho việc phân tích và quản lý

2.3.3.1 Phân tích mã nguồn

Cây cú pháp trừu tượng (AST) là một cấu trúc mô tả mối quan hệ giữa các thành phần trên mã nguồn Trên cây AST, một lớp (class) bao gồm các thành phần như sau:

- Định nghĩa lớp: Là nút bao gồm các nút con về phạm vi truy cập (public, private,

v.v.), tên lớp và thân lớp Phần thân lớp gồm các nút khai báo thuộc tính và các nút

- Định nghĩa phương thức: là một cây AST con bao gồm các thành phần: định nghĩa

phương thức, khai báo hằng số, biến toàn cục/cục bộ, struct, các câu lệnh trong thân hàm, v.v được thể hiện theo quan hệ cha - con Mỗi AST của một phương thức sẽ có cấu trúc như sau:

o Tên phương thức: Tên được sử dụng để tìm kiếm một phương thức khi nó

được gọi (invoke) trong một câu lệnh ở thân một phương thức khác

o Kiểu trả về: Được sử dụng để sinh loại dữ liệu đầu ra

o Danh sách đối số: Dùng để xác định chính xác phương thức cần gọi tới trong

trường hợp có nhiều hàm trùng tên

o Phần thân phương thức: là một cây AST con tương ứng với từng câu lệnh và

các biểu thức tương ứng trên trong

Trang 24

2.3.3.2 Xây dựng CFG từ cây cấu trúc trừu tƣợng

Từ cấu trúc cây AST, chúng ta sử dụng một thuật toán để biến đổi cây AST sang dạng đồ thị dòng điều khiển, được mô tả ở Thuật toán 2.1

Thuật toán 2.1: Sinh_G(AST, t)

Đầu vào: AST: cây AST môt tả cấu trúc của hàm cần kiểm thử;

t: tiêu chí kiểm thử

Đầu ra: G: đồ thị dòng điều khiển ứng với độ phủ t,

G là biến toàn cục được khởi tạo là rỗng

Liên kết node với các đỉnh của G

T_AST := các đỉnh thuộc cây AST theo nhánh đúng Sinh_G(T_AST, t)

F_AST :=các đỉnh thuộc cây AST theo nhánh sai Sinh_G(F_ AST, t)

elseif(c là các câu lệnh break, continue, return, goto ) N_ AST := đỉnh liên kết tiếp theo sau c thuộc cây AST

L

L

Trang 25

Đầu vào của thuật toán là cây AST môt tả cấu trúc mã nguồn và tiêu chí kiểm thử

t Đầu ra của thuật toán là một đồ thị G mô tả dòng điều khiển của mã nguồn

Đầu tiên, với từng nút c của cây AST được duyệt theo thứ tự top-down (dòng 1) Nếu nút c là đỉnh quyết định (dòng 2) (if…else, for, do…while, v.v.) thì tạo một node mới của G tương ứng với nút c trên cây AST và cập nhật node vào G (dòng 3, 4) Tiếp theo, liên kết node với các đỉnh khác trong đồ thị G (dòng 5) Sau đó, gọi đệ quy (dòng

7, 9) cây AST là T_AST và F_AST của các khối lệnh ứng với nhánh đúng vào nhánh sai (dòng 6, 8) Nếu c là các từ khóa (return, break, continue, …) thì cây AST N_AST được gọi đệ quy (dòng 11, 12) Còn nếu c là một khối các câu lệnh thì cây AST c_AST của c được gọi đệ quy (dòng 14, 15) Nếu c là câu lệnh gán hoặc khai báo thì thì một đỉnh node mới của G được khởi tạo đại diện cho c và thêm các liên kết với các đỉnh khác trong đồ thị (dòng 17, 18, 19) Thuật toán kết thúc khi nút cuối cùng của cây AST được duyệt, ta dựng được đồ thị G mô tả cấu trúc điều khiển của mã nguồn Java

2.4 Sinh đường đi kiểm thử từ đồ thị

Đường đi xuất phát từ đỉnh bắt đầu của CFG, đi qua các đỉnh trong đồ thị theo thứ tự thực hiện câu lệnh đến đỉnh kết thúc được gọi là một đường đi độc lập Một tập

đường đi độc lập trên đồ thị thỏa mãn các tiêu chí kiểm thử gọi là tập đường kiểm thử

Mục tiêu của quá trình sinh các đường kiểm thử là tìm được số đường kiểm thử ít nhất

nhưng đạt được độ phủ tối đa trên đồ thị

Trên mỗi CFG, tập đường kiểm thử được xác định sao cho nó phủ hết các nhánh của đồ thị Theo [7], số đường đi của chương trình ứng với đồ thị dòng điều khiển của

nó được tính bằng số đỉnh quyết định của CFG tương ứng cộng 1 hoặc bằng số cạnh trừ số đỉnh của CFG tương ứng cộng 2

2.4.1 Sinh đường đi thỏa mãn tiêu chí phủ câu lệnh

Để sinh các đường kiểm thử thỏa mãn tiêu chí phủ câu lệnh từ CFG tương ứng,

chúng ta tìm các đường đi sao cho mỗi đỉnh được "ghé thăm" ít nhất một lần (đồng nghĩa với mỗi câu lệnh được duyệt qua ít nhất một lần)

Ví dụ, ta cần sinh đường kiểm thử thỏa mãn tiêu chí phủ câu lệnh cho hàm

laNamNhuan có CFG được hiển thị ở Hình 2.7 Trên đồ thị, ta xác định được ba

đường đi để mỗi đỉnh của đồ thị được đi qua ít nhất một lần, các đường được liệt kê như sau:

p1: 1(T), 2

p2: 1(F), 3(T), 4

p3: 1(F), 3(F), 5

Trang 26

Hình 2.7 Mã nguồn và CFG ứng với tiêu chí phủ câu lệnh của hàm laNamNhuan

Rõ ràng, tất cả các đỉnh (tương ứng với câu lệnh từ 1 đến 5) đều xuất hiện trên tập đường đi này, nên đây chính là tập đường kiểm thử thỏa mãn tiêu chí phủ câu lệnh

2.4.2 Sinh đường đi thỏa mãn tiêu chí phủ nhánh

Sinh các đường kiểm thử thỏa mãn tiêu chí phủ nhánh từ CFG là tìm tập đường

đi sao cho các đỉnh quyết định trên CFG đều được duyệt qua cả hai nhánh đúng và sai

Ví dụ, CFG của hàm laNamNhuan ở Hình 2.7 có hai đỉnh quyết định là đỉnh 1 và đỉnh

3 Để đạt được tiêu chí phủ nhánh chúng ta cần 2+1=3 đường đi Thứ tự các đường đi

như sau:

p1: 1(T), 2

p2: 1(F), 3(T), 4

p3: 1(F), 3(F), 5

Ta thấy, các đường đi này đều đi qua hai nhánh của đỉnh 1 và đỉnh 3 Vậy đây

chính là tập đường đi kiểm thử thỏa mãn tiêu chí phủ nhánh của hàm laNamNhuan

2.4.3 Sinh đường đi thỏa mãn tiêu chí phủ điều kiện con

Với CFG của tiêu chí phủ điều kiện con, đường kiểm thử sẽ được xác định sao cho nó phủ hết các nhánh của mọi đỉnh quyết định trên đồ thị Ví dụ, trên CFG ứng

với tiêu chí phủ điều kiện con của hàm laNamNhuan mô tả Hình 2.8 có 4 đỉnh quyết định là 1, 3a, 3b, 3c nên ta cần 4+1=5 đường đi để đạt 100% tiêu chí phủ điều kiện

con Các đường đi được liệt kê như sau:

Trang 27

Hình 2.8 Mã nguồn và CFG ứng với tiêu chí phủ điều kiện con của hàm laNamNhuan

Tập các đường đi từ p1 đến p5 đều đã đi qua cả hai nhánh đúng và sai của các đỉnh quyết định 1, 3a, 3b, 3c nên đây chính là tập đường đi kiểm thử thỏa mãn tiêu chí phủ điều kiện con của hàm laNamNhuan

2.4.4 Phương pháp sinh đường đi kiểm thử trên đồ thị

Từ CFG đã xây dựng được ở Thuật toán 2.1, luận văn tiến hành nghiên cứu phương pháp sinh tập các đường kiểm thử trên đồ thị của mã nguồn Java trong môi trường thực dựa vào phương pháp sinh đường kiểm thử của Mc-Cabe đề xuất trong [7] Ý tưởng của phương pháp là tìm đường đi ngắn nhất trên CFG bằng các duyệt đồ

thị theo nhánh fasle tại các đỉnh quyết định Sau đó thay đổi đỉnh xuất phát và tìm

đường đi ngắn nhất tiếp theo Từng đường đi sẽ được đưa vào tập đường kiểm thử cho đến khi nó phủ hết toàn bộ các nhánh trên đồ thị Thuật toán sinh đường kiểm thử dựa trên phương pháp nghiên cứu được mô tả ở Thuật toán 2.2

Đầu vào của thuật toán là một đồ thị dòng điều khiển G mô tả cấu trúc của hàm cần kiểm thử Đầu ra của thuật toán là tập các đường kiểm thử trên đồ thị G Đầu tiên, khởi tạo biến Path để lưu các đường kiểm thử trên đồ thị (dòng 1) Duyệt đồ thị theo nhánh false qua các đỉnh quyết định của đồ thị và lưu vào tập Path (dòng 2, 3) Tiếp theo, gọi P là tập các đỉnh quyết định trên đường kiểm thử Path và Visited là tập các

đỉnh quyết định đã được duyệt theo cả hai nhánh (dòng 4,5) Với các đỉnh quyết định

thuộc P (dòng 6), từ một đỉnh u bất kỳ trên P và đỉnh v liền kề với u sao cho cạnh (u,v) chưa có trong Path (dòng 7,8), ta tìm đường đi ngắn nhất qua (u,v) và cập nhật vào tập đường kiểm thử Path (dòng 9, 10) ta được đường kiểm thử mới là d Bổ sung các đỉnh quyết định trên d vào P (dòng 11) Cuối cùng, giải phóng đỉnh u khỏi tập P và đánh

dấu là đỉnh u đã được duyệt qua cả hai nhánh (dòng 12,13) Lặp lại quá trình đến khi

các đỉnh quyết định thuộc P được duyệt hết Thuật toán kết thúc khi chúng ta thu được tập đường kiểm thử Path trên đồ thị G

T

T 3b

Trang 28

Thuật toán 2.2: Sinh_Path(G)

Đầu vào: G: đồ thị dòng điều khiển

Đầu ra: Path: tập các đường đi độc lập của đồ thị G

shortestPath := đường đi qua các nhánh false của G

Cập nhật shortestPath vào Path

P := tập các điểm quyết định thuộc shortestPath

Visited := Ø tập các điểm quyết định đã được ghé thăm

while (P != Ø) do

u := một đỉnh quyết định thuộc P

v := đỉnh liền kề với u sao cho cạnh (u,v) chưa có trong Path

d := đường đi ngắn nhất qua (u, v)

Bổ dung các đỉnh quyết định thuộc d vào P

Loại bỏ đỉnh u khỏi tập P

Bổ sung đỉnh u vào tập Visited

end while

2.5 Sinh ca kiểm thử từ đường đi

Để kiểm tra sự đúng đắn của các đường kiểm thử trên đồ thị, chúng ta tiến hành thực hiện ca kiểm thử trên mỗi đường đi bằng cách sinh các dữ liệu kiểm thử và phân tích mã nguồn để có được giá trị đầu ra mong muốn (EO) Nếu sau khi thực hiện các

ca kiểm thử trong môi trường thực, giá trị đầu ra thực tế (RO) trùng với giá trị đầu ra mong muốn thì ca kiểm thử ứng với đường đi là thực hiện được Ngược lại, ca kiểm

thử ứng với đường đi là có lỗi (fail), đường kiểm thử là không thực hiện được hoặc là

một phần của đường đi khác Dữ liệu kiểm thử được sinh ra dựa vào việc giải hệ ràng buộc bằng công cụ SMT-Solver như được mô tả chi tiết trong [5]

2.5.1 Sinh dữ liệu kiểm thử

Dữ liệu kiểm thử là bộ giá trị đầu vào được chọn để thực thi ca kiểm thử trên đường đi Với mỗi đường kiểm thử, để sinh bộ dữ liệu kiểm thử tương ứng, chúng ta

sẽ giải hệ ràng buộc với các biến là tham số của đối tượng cần kiểm thử sao cho giá trị các biến thỏa mãn các điều kiện trên đường đi

Ví dụ, để sinh dữ liệu kiểm thử cho tập đường kiểm thử ứng với tiêu chi phủ điều

kiện con của hàm laNamNhuan đã tìm được ở Mục 2.4.3, liệt kê như dưới đây, ta sẽ

Trang 29

phân tích và giải các hệ ràng buộc trên mỗi đường đi sao cho điều kiện tại các điểm quyết định được thỏa mãn Bảng 2.5 là dữ liệu kiểm thử cho mỗi đường đi

- Xét đường đi p1: 1(T), 2 Để đường đi này được thi hành thì nghiệm của hệ ràng

buộc ứng với đường đi này là các giá trị nguyên sao cho điều kiện tại đỉnh quyết định 1 (year<0) là đúng Giả sử ta chọn giá trị year = - 1 làm dữ liệu kiểm thử của đường đi này

- Xét đường đi p2: 1(F), 3a(T), 4 Để đường đi này được thi hành thì nghiệm của hệ

ràng buộc ứng với đường đi này là các giá trị nguyên thỏa mãn điều kiện tại đỉnh

quyết định 1(year<0) là sai và điều kiện tại đỉnh quyết định 3a - (year%400==0)

là đúng Giả sử ta chọn giá trị year = 2000 làm dữ liệu kiểm thử của đường đi này

- Xét đường đi p3: 1(F), 3a(F), 3b(T), 3c(T),4 tương tự với cách làm trên ta chọn year =1996 để các điều kiện tại đỉnh quyết định 1 và 3a là sai; điều kiện tại đỉnh

3b (year%4==0) và điều kiện tại đỉnh 3c (year%100!=0) là đúng Giả sử ta chọn year = 1996 làm dữ liệu kiểm thử của đường đi này

- Tương tự, với đường đi p4: 1(F), 3a(F), 3b(T), 3c(F), 5 Ta chọn giá trị year =

1200 làm dữ liệu kiểm thử để điều kiện tại đỉnh 3b (year%4==0) là đúng và điều

kiện tại các đỉnh 1, 3a, 3c là sai

- Cuối cùng, với đường đi p5: 1(F), 3a(F), 3b(F), 5 Để đường đi được thi hành thì

nghiệm của hệ ràng buộc ứng với đường đi này là giá trị nguyên sao cho điều kiện

tại các đỉnh đỉnh 1, 3a, 3b là sai Ta chọn giá trị year = 2001 làm dữ liệu kiểm thử

Bảng 2.5 Dữ liệu kiểm thử cho tiêu chí phủ điều kiện con của hàm laNamNhuan

Trang 30

2.5.2 Sinh đầu ra mong muốn

Đầu ra mong muốn (Expected Output - EO) của ca kiểm thử là giá trị đầu ra mà

ta mong muốn của ca kiểm thử sau khi ca kiểm thử được thực thi Với các phương pháp hiện tại, dựa trên đặc tả của bài toán, chúng ta phân tích giá trị đầu vào ứng với đường thi hành để xác định giá trị đầu ra mon muốn Quá trình này thường được tiến hành thủ công và rất khó tự động hóa Tuy nhiên, trong luận văn này, giá trị đầu ra mong muốn chính là giá trị thực tế có được ứng với đầu vào tương ứng vì mã nguồn

do giáo viên cung cấp là mã nguồn chuẩn (không có lỗi) Vì vậy, chúng ta dễ dàng tự động hóa việc sinh giá trị đầu ra mong muốn

Ví dụ, ta để tim đầu ra mong muốn cho các ca kiểm thử của hàm laNamNhuan ở bảng 2.5 Khi chạy các ca kiểm thử với các giá trị đầu vào là mã nguồn chuẩn, ta được

kết quả đầu ra mong muốn, được ghi lại trên Bảng 2.6

Bảng 2.6 Các ca kiểm thử cho tiêu chí phủ câu lệnh của hàm laNamNhuan

2.6 Sinh các ca kiểm thử giá trị biên và vòng lặp

Các ca kiểm thử ứng với ba tiêu chí kiểm thử là phủ câu lệnh, phủ nhánh, phủ điều kiện con đã đảm bảo phủ được tất cả các nhánh trên CFG Tuy nhiên, các ca kiểm thử này lại không kiểm tra được các lỗi ứng với các tình huống có đặc tả và không được lập trình (thương được phát hiện bởi phương pháp kiểm thử hộp đen) Chẳng hạn, trong khi lập trình, các học sinh thường viết sai câu lệnh điều kiện hoặc không viết câu lệnh kiểm tra các giá trị biên, chính vì vậy, để có một bộ dữ liệu kiểm thử đủ tốt, chúng ta cần thiết kế thêm các ca kiểm thử để kiểm thử các giá trị biên của hàm Thêm nữa, với mã nguồn có chứa vòng lặp, cho dù đã có được các ca kiểm thử thỏa mãn các tiêu chí phủ, thì lỗi vẫn có thể xảy ra bên trong vòng lặp Nguyên nhân là do, các đường đi ứng với các tiêu chí kiểm thử chỉ đi qua vòng lặp một lần nên không thể phát hiện và kiểm soát hết các lỗi khi vòng lặp thực thi nhiều lần Chính vì vậy, với những hàm có chứa vòng lặp, chúng ta cần sinh thêm các ca kiểm thử cho vòng lặp nhằm phát hiện lỗi

Ngày đăng: 14/10/2019, 23:50

TÀI LIỆU CÙNG NGƯỜI DÙNG

TÀI LIỆU LIÊN QUAN

🧩 Sản phẩm bạn có thể quan tâm

w