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à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 LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com 2 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. 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. LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com 3 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.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.
Mã nguồn Xây dựng CFG Tiêu chí kiểm thử Sinh đường đi kiểm thử Sinh dữ liệu kiểm thử Sinh đầu ra mong muốn Thực thi ca kiểm thử Báo cáo kiểm thử Hình 2. Tổng quan quy trình kiểm thử dòng điều khiển LUAN VAN CHAT LUONG download : add luanvanchat@agmail.com 4 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. Đầ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 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].