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

NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE

78 438 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 78
Dung lượng 1,34 MB

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

Nội dung

Kiểm thử phần mềm là một hoạt động rất tốn kém và mất thời gian.Vì thế việc để hỗ trợ nâng cao hiệu suất của quá trình kiểm thử phần mềm và kiểm tra được toàn vẹn hệ thống thì một phương

Trang 1

ĐẠI HỌC THÁI NGUYÊN TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG

ĐẶNG THANH TÙNG

NGHIÊN CỨU ÁP DỤNG JAVA PATHFINDER

TRONG TỰ ĐỘNG SINH TEST CASE

ĐỒ ÁN TỐT NGHIỆP ĐẠI HỌC NGÀNH CÔNG NGHỆ PHẦN MỀM

Trang 2

Thái Nguyên, năm 2016

Trang 3

ĐẠI HỌC THÁI NGUYÊN TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG

Trang 4

TRONG TỰ ĐỘNG SINH TEST CASE

Sinh viên thực hiện: Đặng Thanh Tùng

Lớp: CNPM - K10B Hệ chính quy

Giảng viên hướng dẫn: ThS Tô Hữu Nguyên

Thái Nguyên, năm 2016

Trang 5

LỜI CẢM ƠN

Tác giả đề tài mang tên Đặng Thanh Tùng, hiện đang là sinh viên năm thứ năm theo học chuyên ngành Công Nghệ Phần Mềm, tại lớp CNPM-K10 CNTT, trường Công Nghệ Thông Tin và Truyền Thông, trực thuộc Đại Học Thái Nguyên

Việc thực hiện đề tài là cả một quá trình đầu tư công sức và trí tuệ nhằm nghiên cứu, mở mang kiến thức đồng thời áp dụng những lý thuyết đã học vào thực tiễn Và một điều chắc chắn rằng, đề tài sẽ không thành công nếu không

có sự giúp đỡ nhiệt tình của các thầy cô và bạn bè, đó là những sự trợ giúp đắc lực và đáng trân trọng

Tôi xin bày tỏ sự cảm ơn chân thành tới ThS Tô Hữu Nguyên, giảng viên

bộ môn Công Nghệ Phần Mềm, Đại Học CNTT & TT, đồng thời đóng vai trò là người hướng dẫn tôi thực hiện đề tài này Trong quá trình thực tập thầy đã chỉ bảo

và hướng dẫn tận tình cho tôi những lý thuyết, cũng như các kĩ năng trong lập trình, cách giải quyết vấn đề, đặt câu hỏi…

Tôi xin chân thành biết ơn sự tận tình dạy dỗ của tất cả quý thầy cô ngành Công Nghệ Phầm Mềm – Khoa CNTT - Đại Học CNTT & TT

Trang 6

MỤC LỤC

CHƯƠNG 1 TRÌNH BÀY TỔNG QUAN VỀ KIỂM THỬ 2

1.1 Các khái niệm về kiểm thử 2

1.2 Các phương pháp kiểm thử2

1.2.1 Kiểm thử tĩnh – Static testing 2

1.2.2 Kiểm thử động – Dynamic testing 3

1.3 Các chiến lược kiểm thử 3

1.3.1 Kiểm thử hộp đen – Black box testing 3

1.3.2 Kiểm thử hộp trắng – White box testing 4

1.3.3 Kiểm thử hộp xám – Gray box testing 5

1.4 Các cấp độ kiểm thử6

1.4.1 Kiểm thử đơn vị - Unit test 6

1.4.2 Kiểm thử tích hợp – Intergration Test 7

CHƯƠNG 2 CÁC KĨ THUẬT SINH TỰ ĐỘNG CÁC TEST CASE 9

2.1 Giới thiệu 9

2.2 Kỹ thuật sinh Test case dựa trên đặc tả 11

2.2.1 Kỹ thuật tạo Test case cho đặc tả UML 12

Tạo ra Test case bằng việc sử dụng các biểu đồ cộng tác UML 12

Tạo Test case dựa trên Use case cải tiến 13

2.3 Kĩ thuật thực thi tượng trưng trong sinh tự động các Test case13

CHƯƠNG 3 KĨ THUẬT THỰC THI TƯỢNG TRƯNG VÀ CÔNG CỤ JUNIT

16

3.1 Thực thi tượng trưng (symbolic execution) 16

3.1.1 Những khái niệm cơ bản liên quan 16

Trang 7

3.1.2 Thực thi tượng trưng tĩnh 17

3.1.3 Thực thi tượng trưng động 21

3.2 Sinh dữ liệu từ thực thi tượng trưng 27

3.3.2 Các đặc trưng khi sử dụng JUnit 41

3.3.3 Các phương thức sử dụng trong JUnit 41

3.3.4 Ví dụ test chức năng của một lớp 42

3.3.5 Setup và tear down 45

3.4 Tổ chức các test vào các test suite 47

Trang 8

DANH MỤC HÌNH ẢNH

Hình 2.1: Kiểm thử dựa trên đặc tả 10

Hình 2.2: Kiểm thử dựa trên mô hình 10

Hình 2.3: Mô hình hóa các vùng trong thiết kế phần mềm 13

Hình 2.4: Thực thi tượng trưng 15

Hình 3.1: Cây thực thi tượng trưng 20

Hình 3.2: Cây thực thi tượng trưng được quản lý riêng 27

Hình 3.3: Hệ thống kiểm thử tổng quát 29

Hình 3.4: Gán giá trị tượng trưng cho tham số đầu vào 32

Hình 3.5: Thực thi tượng trưng với câu lệnh gán33

Hình 3.6: Thực thi tượng trưng với câu lệnh rẽ nhánh 34

Hình 3.7: Khởi tạo đối tượng làm đầu vào cho chương trình 37

Hình 3.8 Sinh ra các ràng buộc liên quan tới đối tượng38

Hình 3.9: Kiến trúc JPF 40

LỜI MỞ ĐẦU

Với sự phát triển như vũ bão của công nghệ thông tin nói chung và công nghệ phần mềm nói riêng, việc phát triển phần mềm ngày càng được hỗ trợ bởi nhiều công cụ tiên tiến, giúp cho việc xây dựng phần mềm đỡ mệt nhọc và hiệu quả hơn Tuy nhiên độ phức tạp của phần mềm và những giới hạn về thời gian và chi phí, cho dù các hoạt động đảm bảo chất lượng phần mềm nói chung và kiểm thử nói riêng ngày càng chặt chẽ và khoa học vẫn không đảm bảo được rằng sản phần mềm không có lỗi Lỗi vẫn luôn tiềm ẩn trong mọi sản phẩm phần mềm và có thể gây thiệt hại về kinh tế và xã hội to lớn

Kiểm thử phần mềm là một quá trình liên tục, xuyên suốt mọi giai đoạn phát triển phần mềm để đảm bảo rằng phần mềm thỏa mãn yêu cầu thiết kế và yêu cầu đó đáp ứng được nhu cầu của người sử dụng Các kỹ thuật kiểm thử phần mềm

Trang 9

đang được nghiên cứu và việc kiểm thử phần mềm trở thành quy trình bắt buộc trong các dự án phát triển phần mềm trên thế giới Kiểm thử phần mềm là một hoạt động rất tốn kém và mất thời gian.Vì thế việc để hỗ trợ nâng cao hiệu suất của quá trình kiểm thử phần mềm và kiểm tra được toàn vẹn hệ thống thì một phương pháp mới được phát hiện đó là kiểm thử dựa vào mô hình.Có rất nhiều mô hình kiểm thử và em chọn kiểm thử thực thi tượng trưng cho đề tài tốt nghiệp này

Bản báo cáo được hoàn thành dưới sự chỉ bảo tận tình của thầy giáo ThS

Tô Hữu Nguyên, sự giúp đỡ nhiệt tình của các thầy cô trong bộ môn Công nghệ

phần mềm, và tất cả các bạn Em hi vọng sẽ nhận được sự đóng góp ý kiến của các thầy cô và các bạn để bản báo cáo được hoàn thiện hơn.Những đóng góp đó sẽ là kinh nghiệm quý báu cho em

Em xin chân thành cám ơn!

Sinh viên

Đặng Thanh Tùng

CHƯƠNG 1 TRÌNH BÀY TỔNG QUAN VỀ KIỂM THỬ 1.1 Các khái niệm về kiểm thử

IEEE: Kiểm thử là tiến trình vận hành hệ thống hoặc thành phần dưới những điều kiện xác định, quan sát hoặc ghi nhận kết quả và đưa ra đánh giá về hệ hống hoặc thành phần đó

Myers: Kiểm thử là tiến trình thực thi chương trình với mục đích tìm thấy lỗi (The art of software testing)

Kiểm thử phần mềm là quá trình một hệ thống hay thành phần dưới những điều kiện xác định, quan sát và ghi lại các kết quả, và đánh giá một khía cạnh nào

đó của hệ thống hay thành phần đó.( Theo bảng ghi chú giải thuật ngữ chuẩn IEEE của thuật ngữ kỹ nghệ phần mềm –IEEE Standard Glossary ò Software

Trang 10

Engineering Terminology).

Kiểm thử phần mềm là hoạt động khảo sát thực tiễn sản phẩm hay dịch vụ phần mềm trong đúng môi trường chúng dự định sẽ được triển khai nhằm cung cấp cho người có lợi ích liên quan những thông tin về chất lượng của sản phẩm hay dịch vụ phần mềm ấy Mục đích của kiểm thử phần mềm là tìm ra các lỗi hay khiếm khuyết phần mềm nhằm đảm bảo hiệu quả hoạt động tối ưu của phần mềm

trong nhiều ngành khác nhau (Theo Bách khoa toàn thư Wikipedia).

Có thể định nghĩa một cách dễ hiểu như sau: Kiểm thử phần mềm là một tiến trình hay một tập hợp các tiến trình được thiết kế để đảm bảo mã hóa các máy tính thực hiện theo cái mà chúng đã được thiết kế để làm, và không thực hiện bất cứ thứ gì không mong muốn Đây là một pha quan trọng trong quá trình phát triển hệ thống, giúp cho người xây dựng hệ thống và khách hàng thấy được hệ thống mới

đã đáp ứng yêu cầu đặt ra hay chưa?

1.2 Các phương pháp kiểm thử

Có 2 phương pháp kiểm thử chính là: Kiểm thử tĩnh và kiểm thử động

1.2.1 Kiểm thử tĩnh – Static testing

Là phương pháp kiểm thử phần mềm đòi hỏi phải duyệt lại các yêu cầu và các đặc tả bằng tay, thông qua việc sử dụng giấy, bút để kiểm tra logic, lần từng chi tiết mà không cần chạy chương trình Kiểm thử này thường được sử dụng bởi chuyên viên thiết kế - người viết mã lệnh một mình

Kiểm thử tĩnh cũng có thể được tự động hóa Nó sẽ thực hiện kiểm tra toàn

bộ bao gồm các chương trình được phân tích bỏi một trình thông dịch hoặc biên dịch mà xác nhận tính hợp lệ về cú pháp của chương trình

1.2.2 Kiểm thử động – Dynamic testing

Là phương pháp thử phần mềm thông qua việc dùng máy chạy chương trình

để điều tra trang thái tác động của chương trình Đó là kiểm thử dựa trên các ca kiểm thử xác định bằng sự thực hiện của đối tượng kiểm thử hay chạy các chương trình Kiểm thử tự động kiểm tra cách thức hoat động của mã lệnh, tức là kiểm tra

Trang 11

sự phản ứng vật lý từ hệ thống tới các biên luôn thay đổi theo thời gian Trong kiểm thử tự động, phần mềm phải thực sự được biên dịch và chạy Kiểm thử động thực sự bao gồm làm việc với phần mềm, nhập các giá trị đầu vào và kiểm tra xem liệu đầu ra có như mong muốn hay không Các phương pháp kiểm thử tự động

gồm có Unit – Unit Tests, Kiểm thử tích hợp – Intergration Tests, Kiểm thử hệ thống – System Tests, và Kiểm thử chấp nhận sản phẩm – Acceptance Tests.

1.3 Các chiến lược kiểm thử

Ba trong số những chiến lược kiểm thử thông dụng nhất bao gồm: Kiểm thử hộp đen, Kiểm thử hộp trắng, và Kiểm thử hộp xám

1.3.1 Kiểm thử hộp đen – Black box testing

Một trong những chiến lược kiểm thử quan trọng là kiểm thử hộp đen, hướng dữ liệu, hay hướng vào/ ra Kiểm thử hộp đen xem chương trình như là một

“hộp đen” Mục đích của bạn là hoàn toàn không quan tâm về cách cư xử và cấu bên trong của chương trình Thay vào đó, tập trung vào tìm các trường hợp mà chương trình không thực hiện theo đặc tả của nó

Theo hướng tiếp cận này, dữ liệu kiểm tra được lấy chỉ từ các đặc tả

 Các phương pháp kiểm thử hộp đen:

 Kiểm thử lớp tương đương – Equivalence partitioning

 Kiểm thử giá trị biên – Boundary value analysis

 Kiểm thử mọi cặp – All-pairs testing

 Kiểm thử fuzz – Fuzz testing

 Kiểm thử dựa trên mô hình – Model-based testing.

 Ma trận dấu vết –Traceability matrix.

 Kiểm thử thăm dò – Exploratory testing.

 Kiểm thử dựa trên đặc tả - Specification –base testing.

Kiểm thử dựa trên đặc tả tập trung vào kiểm tra tính thiết thực của phần mềm theo những yêu cầu thích hợp Do đó, kiểm thử viên nhập dữ liệu vào, và chỉ thấy

Trang 12

dữ liệu ra từ đối tượng kiểm thử Mức kiểm thử này thường yêu cầu các ca kiểm thử triệt để được cung cấp cho kiểm thử viên mà khi đó có thể xác minh là đối với

dữ liệu đầu vào đã cho, giá trị đầu ra (hay cách thức hoạt động) có giống với giá trị mong muốn đã được xác định trong ca kiểm thử đó hay không Kiểm thử dựa trên đặc tả là cần thiết, nhưng không đủ để ngăn, chặn những rủi ro chắc chắn

 Ưu, nhược điểm

 Kiểm thử hộp đen không có mối liên quan nào tới mã lệnh, và kiểm thử viên chỉ đơn giản tâm niệm là: Một mã lệnh phải có lỗi Sử dụng nguyên tắc “Hãy đòi hỏi và bạn sẽ được nhận”, những kiểm thử viên hộp đen tìm ra lỗi mà những lập trình viên đã không tìm ra Nhưng mặt khác, người ta cũng nói kiểm thử hộp đen “giống như là đi trong bóng tối mà không có đèn vậy”, bởi vì kiểm thử viên không biết các phần mềm được kiểm tra thực sự được xây dựng như thế nào Đó là lý do mà có nhiều trường hợp một kiểm thử viên hộp đen viết rất nhiều ca kiểm thử để kiểm tra một thứ gì đó mà đáng lẽ có thể chỉ cần bằng một ca kiểm thử duy nhất, và/hoặc một số phần của chương trình không được kiểm tra chút nào

 Do vậy, kiểm thử hộp đen có ưu điểm của “một sự đánh giá khách quan”, mặt khác nó lại có nhưng nhược điểm của “thăm dò mù”

1.3.2 Kiểm thử hộp trắng – White box testing

Là một chiến lược kiểm thử khác, trái ngược hoàn toàn với kiểm thử hộp đen, kiểm thử hộp trắng hay kiểm thử hướng logic cho phép bạn khảo sát cấu trúc bên trong của chương trình Chiến lược này xuất phát từ dữ liệu kiểm thử bằng sự kiểm thử tính logic của chương trình Kiểm thử viên sẽ truy cập vào cấu trúc dữ liệu và giải thuật bên trong chương trình (và cả mã lệnh thực hiện chúng)

 Các phương pháp kiểm thử hộp trắng

 Kiểm thử giao diện lập trình ứng dụng – API testing (application

programming interface): là phương pháp kiểm thử của úng dụng sử

Trang 13

dụng các API công khai và riêng tư.

 Bao phủ mã lệnh – Code voverage: tạo các kiểm tra để đáp ứng một số

tiêu chuẩn về bao phủ mã lệnh

 Các phương pháp gán lỗi – Fault injection

 Các phương pháp kiểm thử hoán chuyển – Mutation testing methods.

 Kiểm thử tĩnh – Static testing: kiểm thử hộp trắng bao gồm mọi kiểm

thử tĩnh

Phương pháp kiểm thử hộp trắng cũng có thể được sử dụng để đánh giá sự hoàn thành của một bộ kiểm thử mà được tạo ra cùng với các phương pháp kiểm thử hộp đen Điều này cho phép các nhóm phần mềm khảo sát các phần của một hệ thống ít khi được kiểm tra và đảm bảo rằng những điểm chức năng quan trọng nhất

đã được kiểm tra

1.3.3 Kiểm thử hộp xám – Gray box testing

Kiểm thử hộp xám đòi hỏi phải có sự truy cập tới cấu trúc dữ liệu và giải thuật bên trong cho những mục đích thiết kế các ca kiểm thử, nhưng là kiểm thử ở mức người sử dụng hay mức hộp đen Việc thao tác tới dữ liệu đầu vào và định

dạng dữ liệu đầu ra là không rõ ràng, giống như một chiếc “hộp xám”, bởi vì đầu vào và đầu ra rõ ràng là ở bên ngoài “hộp đen” mà chúng ta vẫn gọi về hệ thống

được kiểm tra Sự khác biệt này đặc biệt quan trọng khi quản lý kiểm thử tích hợp

– Intergartion testing giữa 2 module mã lệnh được viết bởi hai chuyên viên thiết

kế khác nhau, trong đó chỉ giao diện được viết bởi hai chuyên viên thiết kế khác nhau, trong đó chỉ giao diện là được đưa ra để kiểm thử Kiểm thử hộp xám có thể cũng bao gồm cả thiết kế đối chiếu để quyết định, ví dụ: giá trị biên hay thông báo lỗi

Trang 14

Unit Test thường do lập trình viên thực hiện Công đoạn này cần được thực hiện càng sớm càng tốt trong giai đoạn viết code và xuyên suốt chu kỳ phát triển phần mềm Thông thường, Unit Test đòi hỏi kiểm thử viên có kiến thức về thiết kế

và code của chương trình Mục đích của Unit Test là bảo đảm thông tin được xử lý

và xuất (khỏi Unit) là chính xác, trong mối tương quan về dữ liệu nhập và chức năng của Unit Điều này thường đòi hỏi tất cả các nhánh bên trong Unit đều phải được kiểm tra để phát hiện nhánh phát sinh lỗi Một nhánh thường là một chuỗi các lệnh được thực thi trong một Unit Ví dụ: chuỗi các lệnh sau điều kiện If và nằm then … else là một nhánh Thực tế việc chọn lựa các nhánh để đơn giản háo việc kiểm thử và quét hết Unit đòi hỏi phải có kỹ thuật, đôi khi phải dùng thuật toán để chọn lựa

Cùng với các mục kiểm thử khác nhau, Unit Test cũng đòi hỏi phải chuẩn bị trước các ca kiểm thử ( Test case) hoặc kịch bản kiểm thử ( Test script), trong đó chỉ định rõ dữ liệu đầu vào, các bước thực hiện và dữ liệu đầu ra mong muốn Các Test case và Test script này nên được giữ lại để tái sử dụng

1.4.2 Kiểm thử tích hợp – Intergration Test

Integration test kết hợp các thành phần của một ứng dụng và kiểm thử như một ứng dụng đã hoàn thành Trong khi Unit Test kiểm tra các thành phần

Trang 15

và Unit riêng lẻ thì Integration Test kết hợp chúng lại với nhau và kiểm tra sự giao tiếp giữa chúng.

Hai mục tiêu chính của Integration Test:

 Phát hiện lỗi giao tiếp xảy ra giữa các Unit

 Tích hợp các Unit đơn lẻ thành các hệ thống nhỏ (Subsystem) và cuối cùng là nguyên hệ thống hoàn chỉnh (System) chuẩn bị cho kiểm thử

ở mức hệ thống (System).

Trong Unit Test, lập trình viên cố gắng phát hiện trên những Unit đã được kiểm tra cẩn thận trước đó bằng Unit Test, và tất cả các lỗi mức Unit đã được sửa chữa Một số người hiểu sai rằng Unit một khi đã qua giai đoạn Unit Test với các giao tiếp giả lập thì không cần phải thực hiện Integration Test nữa Thực tết về tích hợp giữa các Unit dẫn đến những tình huống hoàn toàn khác Một chiến lược cần quan tâm trong Integration Test là nên tích hợp dần từng Unit Một Unit tại một thời điểm tích hợp vào một nhóm các Unit khác đã tích hợp trước đó và đã hoàn tất các đợt Integration Test trước đó Lúc này, ta chỉ cần kiểm thử giao tiếp của Unit mới them vào với hệ thống các Unit đã tích hợp trước đó, điều này sẽ làm cho số lượng ca kiểm thử giảm đi rất nhiều, và sai sót sẽ giảm đáng kể

Có 4 loại kiểm thử trong Integration Test:

 Kiểm thử cấu trúc (Structure Test): Tương tự White Box Test, kiểm

thử cấu trúc nhằm bảo đảm các thành phần bên trong đó của một chương trình chạy đúng và chú trọng đến hoạt động của các thành phần cấu trúc nội tại của chương trình chẳng hạn các câu lệnh và nhánh bên trong

 Kiểm thử chức năng ( Functional Test): Tương tự Black Box Test,

kiểm thử chức năng chỉ chú trọng đến chức năng của chương trình,

mà không quan tâm đến cấu trúc bên trong chỉ khảo sát chức năng của chương trình theo yêu cầu kỹ thuật

 Kiểm thử hiệu năng (Performance Test): Kiểm thử việc vận hành

Trang 16

của hệ thống.

 Kiểm thử khả năng chịu tải (Stress Test): Kiểm thử các giới hạn

của hệ thống

Trang 17

CHƯƠNG 2 CÁC KĨ THUẬT SINH TỰ ĐỘNG CÁC TEST CASE

2.1 Giới thiệu

Kiểm thử phần mềm tốn nhiều chi phí nhân công, thời gian Trong một số dự

án, kiểm thử phần mềm tiêu hao trên 50% tổng giá trị phát triển phẩn mềm Nếu cần ứng dụng an toàn hơn, chi phí kiểm thử còn cao hơn nữa Do đó một trong các mục tiêu của kiểm thử là tự động hóa nhiều như có thể, nhở đó mà giảm chi phí rất nhiều và tối thiểu hóa các lỗi do người dùng gây ra, đặc biệt là giúp việc kiểm thử hồi quy dễ dàng, nhanh chóng hơn

Tự động hóa việc kiểm thử là dùng phần mềm điều khiển việc thi hành kiểm thử, so sánh kết quả có được với kết quả kỳ vọng, thiết lập các điều kiện đầu vào, các kiểm soát kiểm thử và các chức năng báo cáo kết quả

Test phần mềm là công việc chạy một chương trình trên một bộ các Test case

và so sánh kết quả thực tế với kết quả mong muốn Test và thiết kế test là các giai đoạn để đảm bảo chất lượng phần mềm, tập trung vào việc phát hiện lỗi Chúng ta nên tìm các nguyên nhân để có thể phát hiện ra các triệu chứng được gây ra các lỗi Cuối cùng, khi test nên cung cấp chẩn đoán rõ ràng để các lỗi có thể dễ dàng được sửa chữa

Vậy trong quá trình test phần mềm “tiêu chuẩn test là gì?” Một tiêu chuẩn test

là một quy tắc hoặc một tập hợp các quy tắc mà áp đặt các yêu cầu vào một bộ của các Test case Có nhiều cách để phân loại các tiêu chuẩn phù hợp Một trong những cách thông dụng nhất là bằng nguồn thông tin được sử dụng để xác định các yêu cầu test và sự phù hợp của test Do đó, một tiêu chuẩn phù hợp có thể là được dựa trên đặc tả hoặc dựa trên chương trình

Một tiêu chuẩn dựa trên đặc tả xác định công việc test được yêu cầu trong điều kiện của các chức năng khác nhau của các đặc tả phần mềm, vì vậy một bộ test là phù hợp nếu tất cả các chức năng được xác định đã được đưa ra đầy đủ vào các

Trang 18

Test case Ở đây các đặc tả được sử dụng để tạo ra các Test case, cũng như tạo ra một chương trình Một cái nhìn trừu tượng về quá trình test dựa trên đặc tả được đưa ra trong Hình số 1.

Hình 2.1: Kiểm thử dựa trên đặc tả

Một tiêu chuẩn dựa trên chương trình xác định các yêu cầu test trong điều kiện chương trình đang test và quyết định nếu một bộ test là phù hợp theo chương trình

đã được thử nghiệm kỹ lưỡng hay không Một quan điểm trừu tượng về quá trình test được dựa trên chương trình được cho thấy ở Hình số 2

Chú ý rằng cả test dựa trên chương trình và test dựa trên đặc tả, tính chính xác của các kết quả chương trình phải được kiểm tra với các yêu cầu hoặc đặc tả Tuy nhiên, trong cả hai trường hợp, đánh giá sự phù hợp của các test không phụ thuộc vào các kết quả của kiểm tra này Thêm vào đó, sự định nghĩa về các tiêu chuẩn được dựa trên đặc tả đã đưa trước đó không được coi là sự tồn tại của đặc tả chuẩn

Trang 19

Hình 2.2: Kiểm thử dựa trên mô hình.

2.2 Kỹ thuật sinh Test case dựa trên đặc tả

Kiểm thử dựa trên đặc tả lấy được các thông tin test từ một đặc tả của phần mềm khi test Tuy nhiên, khi việc thực hiện được phát triển không chuẩn mực từ một đặc tả chuẩn mực, đặc tả có thể đóng vai trò chủ yếu trong quá trình test bằng cách cho phép chúng ta thu được các đầu vào test và các kết mong đợi từ các đầu vào này Có hai vai trò chính một đặc tả có thể đóng vai trò trong test phần mềm Đầu tiên cung cấp các thông tin cần thiết để kiểm tra hoặc là đầu ra của chương trình có đúng không Thứ hai là cung cấp các thông tin để lựa chọn Test case và để đánh giá sự phù hợp của các test

Kiểm thử dựa trên đặc tả đưa ra nhiều ưu điểm trong test phần mềm Đặc tả chuẩn của một sản phẩm phần mềm có thể được sử dụng như một sự hướng dẫn cho việc thiết kế các test chức năng cho sản phẩm Đặc tả xác định chính xác các khía cạnh cơ bản của phần mềm, trong khi thông tin cấu trúc và chi tiết bị loại bỏ

Do đó, tester có các thông tin thiết yếu về tính năng của sản phẩm không phải triết

Trang 20

xuất nó ra từ các chi tiết thiết yếu.

Kiểm thử dựa trên đặc tả từ các đặc tả chuẩn đưa ra một cách tiếp cận chuẩn hơn, được cấu trúc đơn giản hơn cho sự phát triển của các test chức năng hơn là các kĩ thuật test không dựa trên đặc tả Mối quan hệ mạnh mẽ giữa đặc tả và test giúp phát hiện ra các lỗi và có thể đơn giản quá trình hồi quy Đặc tả là một bản

mô tả thẩm quyền của hành vi hệ thống và có thể được sử dụng để lấy được các kết quả mong muốn cho các dữ liệu test Các lợi ích khác của kiểm thử dựa trên đặc tả gồm phát triển test cùng lúc với việc thực hiện và thiết kế, sử dụng các test đã lấy được để phê chuẩn đặc tả gốc, và kiểm định đã được đơn giản của quá trình test Đặc tả có thể cũng được phân tích tương ứng với khả năng test ổn định

Có ba cách tiếp cận chính tới các đặc tả chức năng phần mềm chuẩn: (1) các đặc tả dựa trên mô hình, (2) các đặc tả định hướng đến thuộc tính chẳng hạn các đặc tả thuật toán và có nhiều ngôn ngữ, và (3) các đặc tả dựa trên trạng thái

Các ngôn ngữ đặc tả dựa trên mô hình, cố gắng để có được các đặc tả chuẩn của phần mềm dựa trên các mô hình của các đối tượng thực tế Ngôn ngữ đặc tả thuật toán mô tả phần mềm bằng việc đưa ra các câu lệnh chuẩn, về các mối quan

hệ trong số các thao tác và các chức năng mà có tác dụng lên chúng Các đặc tả dựa trên trạng thái mô tả phần mềm trong điều kiện của các chuyển tiếp trạng thái Các đặc tả được dựa trên trạng thái tiêu biểu xác định điều kiện trước trên các chuyển tiếp, mà là các giá trị mà các biến xác nhận phải có cho các chuyển tiếp có thể được phép, các thay đổi trong các giá trị biến đổi mà khiến các chuyển tiếp được diễn ra

2.2.1 Kỹ thuật tạo Test case cho đặc tả UML

UML có thể được sử dụng để xác định một vùng rộng các khía cạnh của một hệ thống Các biểu đồ trạng thái là một nơi rõ ràng nhất để bắt đầu với việc tạo

ra dữ liệu kiểm thử Các biểu đồ UML được dựa trên các máy trạng thái hạn chế sử dụng một ký hiệu biểu đồ trạng thái được mở rộng, và được sử dụng để đưa hành

vi của một đối tượng Hành vi gắn kết cấu trúc của một đối tượng với các thuộc

Trang 21

tính của nó và các mối quan hệ để đối tượng có thể đáp ứng được những trách nhiệm của nó Các phương pháp của một đối tượng thực hiện hành vi của nó Bằng việc test mỗi phương pháp, chúng ta có thể kiểm thử một vài mục của hành vi của một đối tượng, nhưng không phải là toàn bộ các hành vi Các máy trạng thái mô tả toàn bộ hành vi của một đối tượng, do vậy Test case được tạo ra từ các máy trạng thái kiểm thử toàn bộ hành vi của một đối tượng Lợi thế khác của biểu đồ UML

đó là chúng có cùng ngữ nghĩa như các đặc tả được dựa trên trạng thái khác Điều này làm cho nó có thể sinh ra mô hình thế hệ Test case được miêu tả ở các biểu đồ UML Để sửa mô hình tới các biểu đồ UML, chúng ta phải giải thích cùng ngữ nghĩa và cú pháp của biểu đồ trạng thái trong các đặc tả UML

Tạo ra Test case bằng việc sử dụng các biểu đồ cộng tác UML

Các Test case được tạo ra bằng cách sử dụng các biểu đồ cộng tác UML là một trong những cách tiêu biểu trong kỹ thuật sinh Test case dựa trên mô hình Các biểu đồ cộng tác UML cho thấy một chú ý quan trọng cho việc sinh Test case bởi vì chúng mô tả chính xác các chức năng phần mềm được thực hiện như thế nào, các biểu đồ này cung cấp một kết nối trong một hình thức mà có thể dễ dàng được vận dụng bởi các phương pháp tự động Phần này còn đưa ra các tiêu chuẩn test mới mà dựa trên các biểu đồ cộng tác UML Các tiêu chuẩn được xác định cho

cả việc test tĩnh và động của một sự tích hợp chính thức các test được dựa trên các chú giải thiết kế ở mức độ cao, làm cho phần mềm đáng tin cậy hơn

Tạo Test case dựa trên Use case cải tiến

Các nguyên tắc cơ bản

Trong phần này, có ba khái niệm chính liên quan trong cách tiếp cận đã được mô tả chi tiết Mỗi khái niệm tương ứng với một bước làm mô hình xác định, như trong Hình 23

Trang 22

Hình 2.3: Mô hình hóa các vùng trong thiết kế phần mềm

Cách tiếp cận được mô tả trong tài liệu này tập trung vào việc hệ thống hóa hoặc thậm chí tự động hóa các bước đã được chỉ ra trong quá trình để thực hiện được sự mở rộng một cách tối đa ( việc phát hiện lỗi được thiết lập trong phần ngoặc đơn bởi vì kiểm thử sử dụng thống kê tập trung vào các thước đo tin cậy và

có thể xác định chỉ các lỗi kém)

2.3 Kĩ thuật thực thi tượng trưng trong sinh tự động các Test case

Một trong những phương pháp đơn giản nhất để sinh tự động các ca kiểm thử

đó là kiểm thử ngẫu nhiên (random testing) Với kiểm thử ngẫu nhiên các đầu vào cho hệ thống được sinh ngẫu nhiên Để thực hiện, một luồng các bits được sinh ngẫu nhiên để thể hiện cho các giá trị của tham số đầu vào Giả sử với một hàm nhận tham số đầu vào có kiểu string thì chỉ cần sinh ngẫu nhiên một luồng các bits

để thể hiện giá trị cho một chuỗi Kiểm thử ngẫu nhiên có ưu điểm là dễ dàng sinh các đầu vào ngẫu nhiên và hệ thống kiểm thử ngẫu nhiên không yêu cầu nhiều tài nguyên bộ nhớ lúc thực thi Nhưng hạn chế của nó là kiểm tra cùng một hành vị thực thi của chương trình nhiều lần với những đầu vào khác nhau và chỉ có thể kiểm tra được một số trường hợp thực thi của chương trình Thêm vào đó, kiểm thử ngẫu nhiên khó xác định được khi nào việc kiểm thử nên được dừng lại và nó không biết tại điểm nào không gian trạng thái đã được thám hiểm hết Để xác định khi nào việc kiểm thử dừng lại thì hệ thống kiểm thử ngẫu nhiên được kết hợp với các adequacy criterion [5] Giả sử adequacy criterion là bao phủ lệnh (statement

Trang 23

coverage)[5] thì việc kiểm thử chỉ dừng lại khi tất cả các câu lệnh của chương trình

được thực thi ít nhất một lần

Một phương pháp khác đang rất phổ biến giúp khắc phục được hạn chế của kiểm thử ngẫu nhiên đó là thực thi tượng trưng Thực thi tượng trưng chính là việc xây dựng các ràng buộc dựa vào các giá trị tượng trưng và giải quyết các ràng buộc đó để sinh ra các giá trị làm đầu vào chương trình mà có thể thực thi chương trình theo các đường đi thực thi khác nhau Ý tưởng chính của thực thi tượng trưng

đó là thực thi một chương trình với những giá trị tượng trưng Có hai cách tiếp cận đối với thực thi tượng trưng đó là cách tiếp cận dựa trên phân tích tĩnh và phân tích động chương trình

Một trong những ứng dụng chính của nó là tự động sinh ra các bộ dữ liệu kiểm thử đầu vào có độ bao phủ mã nguồn cao (ví dụ: bao phủ nhánh) Các ứng dụng khác bao gồm việc phát hiện lỗi trong các chương trình lấy dữ liệu vào từ các miền vô hạn

Phần mở rộng kết hợp giữa thực thi tượng trưng với kiểm thử mô hình (model checking) và giải quyết ràng buộc để sinh ra các dữ liệu vào Trên công cụ này, các chương trình được thực thi trên các bộ dữ liệu vào bao phủ toàn bộ các yếu tố đầu vào có thể Các giá trị của các biến được thể hiện dưới dạng các biểu thức số và các ràng buộc được tổng hợp từ việc phân tích cấu trúc mã nguồn Việc giải thích các ràng buộc này sẽ cho ra những bộ dữ liệu kiểm thử đảm bảo đạt được một phần mã nguồn đó

Trang 24

Hình 2.4: Thực thi tượng trưng

Ví dụ trong Hình 20, điều kiện đường đi (Path Condition - PC) được khởi tạo

là True Nếu chương trình thực hiện theo nhánh “then” của biểu thức “if”, điều kiện đường đi sẽ là X <Y Nếu chương trình thực hiện nhánh “else” của biểu thức

“if”, điều kiện đường đi sẽ là X ≥ Y

Để thực hiện một phương pháp tượng trưng, người sử dụng cần xác định

rõ các đối số nào của phương thức là tượng trưng hoặc cụ thể Nhìn chung (các trường) cũng có thể được xác định rõ là tượng trưng, thông qua những chú thích đặc biệt

Trang 25

CHƯƠNG 3

KĨ THUẬT THỰC THI TƯỢNG TRƯNG VÀ CÔNG CỤ JUNIT

3.1 Thực thi tượng trưng (symbolic execution)

3.1.1 Những khái niệm cơ bản liên quan

Một chương trình P có thể xem xét như một hàm, P : S→ R , trong đó S là tập hợp các đầu vào (input) có thể và R là tập hợp các đầu ra (output) có thể S có thể được biểu diễn bởi vector I=(x1,…,xk,…,xn), trong đó xk là tham số đầu vào thứ

k của P với k N Một bộ giá trị i=(d1, ,dk,…,dn) biểu thị cho một đầu vào của P, i

S, trong đó dk là các giá trị cụ thể sao cho dk Dxk với Dxk là miền giá trị của tham

số đầu vào xk Sự thực thi của chương trình P với đầu vào i S được biểu thị bởi P(i)

Biểu đồ luồng điều khiển (CFG) của một chương trình P là một bộ G=(N, E,

s, e), trong đó G là một đồ thị có hướng, với N là tập hợp các nút (node), E = {(n,m) | n,m N} là tập hợp các cạnh, s là nút vào và e là nút ra, s và e là duy nhất

Mỗi nút được định nghĩa như một khối cơ bản (basic block) là một dãy liên tục các

chỉ thị(câu lệnh) sao cho luồng điều khiển khi đi vào nút và ra khỏi nút không bị ngưng lại (halt) Điều này có nghĩa là nếu bất cứ câu lệnh nào của block được thực thi thì toàn bộ block được thực thi Mỗi cạnh của CFG nối 2 nút với nhau và được gán nhãn với một biểu thức điều kiện rẽ nhánh Nếu cạnh không được gán nhãn có nghĩa là điều kiện luôn đúng

Một đường đi (path) cụ thể là dãy các nút: p=(p1, p2,…,pn) với pn là nút cuối của đường đi p và (pi,pi+1) E (1 < i < n-1) Nếu tồn tại i S sao cho sự thực thi P(i)

đi theo đường đi p thì p gọi là đường đi khả thi, ngược lại p là đường đi không khả thi Một đường đi bắt đầu tại nút vào và kết thúc tại nút ra gọi là đường đi đầy đủ, nếu kết thúc tại nút không phải là nút ra thì gọi là đường đi không đầy đủ (path segment)

Một chương trình P cũng có thể xem gồm tập hợp các câu lệnh (statements)

Trang 26

là thành phần nhỏ nhất trong một chương trình mà có thể được thực thi riêng rẽ Bằng việc thực thi một câu lệnh chương trình có thể chuyển đổi trạng thái thực thi của nó từ trạng thái hiện thời tới trạng thái mới Một đường đi thực thi của chương trình P là một dãy các câu lệnh mà có thể được thực thi theo thứ tự từ điểm bắt đầu của chương trình Đoạn đường đi đầu tiên (path prefix) có độ dài n của đường đi thực thi p là một dãy bao gồm n câu lệnh đầu tiên của p

Do đó việc sinh dữ liệu kiểm thử là sinh một tập hợp tối thiểu các đầu vào i Є

S sao cho có thể thực thi tất cả các đường đi trong CFG của chương trình

3.1.2 Thực thi tượng trưng tĩnh

Ý tưởng chính của thực thi tượng trưng (SE)[6] là thực thi chương trình với các giá trị tượng trưng (symbolic values) thay vì các giá trị cụ thể (concrete values) của các tham số đầu vào

Với mỗi tham số đầu vào một giá trị tượng trưng được đưa ra để kết hợp với

nó Mỗi biến trong chương trình P mà giá trị của nó phụ thuộc vào giá trị của các tham số đầu vào thì trong quá trình thực thi tượng trưng một giá trị tượng trưng sẽ được tính toán để kết hợp cùng với nó Mỗi giá trị tượng trưng biểu thị cho một tập hợp các giá trị cụ thể mà một biến hoặc một tham số đầu vào có thể nhận Kết quả trả về của một chương trình được thực thi tương trưng nếu có cũng được biểu thị bởi biểu thức của các giá trị tượng trưng

Giá trị tượng trưng của biến x có thể được biểu thị bởi:

(a) Một ký hiệu đầu vào(input symbol)

(b) Một biểu thức kết hợp giữa các giá trị tượng trưng bởi các toán tử

(c) Một biểu thức kết hợp giữa giá trị tượng trưng và giá trị cụ thể bởi toán tử

Một ký hiệu đầu vào biểu thị cho giá trị tượng trưng của một tham số đầu vào lúc bắt đầu thực thi chương trình Các tham số đầu vào khác nhau của P được biểu thị bởi các ký hiệu đầu vào khác nhau Các toán tử (operator) là các phép toán như

Trang 27

cộng (+), trừ (), nhân (*), chia (/).

Nếu giá trị của một biến x không phụ thuộc vào các giá trị đầu vào thì không

có giá trị tượng trưng nào được tính toán để kết hợp với nó Giá trị tượng trưng của các biến và các tham số đầu vào được cập nhật như các giá trị cụ thể của nó trong quá trình thực thi Gán một giá trị cụ thể từ một biến tới biến khác dẫn đến giá trị tượng trưng cũng được sao chép nếu biến được gán tới một biến khác có một giá trị tượng trưng Giả sử với một câu lệnh gán x=e, nếu e là một tham số đầu vào, thì giá trị tượng trưng được gán cho x sẽ có dạng (a) Nếu e là một biểu thức tính toán gồm các toán hạng Các toán hạng đó có thể là biến, tham số đầu vào hoặc hằng thì giá trị tượng trưng của biến x sẽ là một biểu thức tượng trưng dạng (b) nếu mỗi toánl hạng trong biểu thức có một giá trị tượng trưng kết hợp với nó, hoặc là một biểu thức tượng trưng dạng (c) nếu có toán hạng là hằng số hoặc không có giá trị tượng trưng kết hợp với nó Giá trị cụ thể của một hằng hoặc một biến cũng được

sử dụng trong biểu thức tượng trưng nếu như hằng hoặc biến đó không có giá trị tượng trưng kết hợp với nó

Trạng thái của một chương trình được thực thi tương trưng bao gồm các giá trị của các biến trong chương trình, điều kiện đường đi (PC) và biến đếm chương trình (program counter) Biến đếm chương trình xác định chỉ thị (câu lệnh) tiếp theo sẽ được thực thi Mỗi PC là một biểu thức kết hợp bởi các ràng buộc mà các giá trị đầu vào chương trình cần thỏa mãn để chương trình được thực thi theo đường đi tương ứng với PC đó Mỗi ràng buộc là một biểu thức tượng trưng dạng

x o y trong đó x là giá trị tượng trưng, y là giá trị tượng trưng hoặc giá trị cụ thể và

o {≤, ≠, =, <, >, ≥} Các ràng buộc đó chính là biểu thức của điều kiện rẽ nhánh và biểu thức phủ định của điều kiện rẽ nhánh tương ứng với nhánh true và nhánh false Tại mỗi câu lệnh rẽ nhánh, các ràng buộc được tạo ra Các ràng buộc này được biểu thị bởi biểu thức của các giá trị tượng trưng hay biểu thức của giá trị tượng trưng và giá trị cụ thể phụ thuộc vào biến xuất hiện trong biểu thức điều kiện của câu lệnh rẽ nhánh có giá trị tượng trưng được tính toán để kết hợp với nó

Trang 28

hay không.

Trong quá trình thực thi tượng trưng, việc chương trình được thực thi theo một đường đi cụ thể nào đó không phụ thuộc vào các giá trị cụ thể của các biến và các tham số đầu vào Tại các điểm rẽ nhánh, cả hai nhánh ra sẽ được xem xét để điều hướng sự thực thi hiện thời đi theo SE chủ yếu liên quan tới việc thực thi hai loại câu lệnh đó là câu lệnh gán (assignment statments) và câu lệnh rẽ nhánh Tại các câu lệnh gán thì giá trị tượng trưng của các biến chương trình cũng như các tham số đầu vào có liên quan tới câu lệnh gán đó được cập nhật Tại các câu lệnh

rẽ nhánh, chương trình sẽ được điều hướng để thực thi theo cả hai nhánh Và hai ràng buộc đường đi tương ứng với hai nhánh sẽ được tạo ra Một ràng buộc là biểu thức điều kiện tại câu lệnh rẽ nhánh Còn ràng buộc kia là phủ định của biểu thức điều kiện rẽ nhánh Các ràng buộc này sẽ được cập nhật vào điều kiện đường đi tương ứng với các nhánh đó Đồng thời các PC này sẽ được đánh giá để xác định đường đi tương ứng với PC đó có khả thi Nếu PC được đánh giá trở thành false thì SE sẽ quay lui và chỉ thực thi theo nhánh khả thi Các PC được tạo ra bằng cách thu gom các ràng buộc trên các đường đi tương ứng và giải quyết các ràng buộc này sẽ sinh ra các giá trị cụ thể cho các tham số đầu vào

Để mô tả sự thực thi tượng trưng một chương trình Một cây thực thi tượng trưng (SET) được đưa ra để biểu thị cho các đường đi thực thi trong quá trình thực thi trượng trưng một chương trình Các nút biểu thị cho các trạng thái của chương trình thực thi tượng trưng và các cạnh biểu thị cho sự chuyển đổi trạng thái từ trạng thái này sang trạng thái khác

Trang 29

5: if (x - y > 0)

}

Hình 3.1: Cây thực thi tượng trưng

Cây thực thi tượng trưng (Hình 2) biểu thị cho việc thực thi tượng trưng hàm Swap Bắt đầu thực thi tượng trưng hàm Swap bằng cách gán giá trị tượng trưng cho các tham số đầu vào x và y lần lượt là X và Y, đồng thời khởi tạo PC là true Tới câu lệnh rẽ nhánh 1, cả hai nhánh đi của chương trình đều chọn để thực thi với các giá trị tượng trưng Tại câu lệnh này, biểu thức điều kiện rẽ nhánh và biểu thức phủ định của điều kiện rẽ nhánh được thêm vào PC theo các nhánh tương ứng Trong thực thi tượng trưng, nếu điều kiện rẽ nhánh được thêm vào PC thì PC đó

Trang 30

tương ứng với PC của nhánh mà điều kiện rẽ nhánh nhận giá trị true Sau khi thực thi câu lệnh 1, hàm Swap tiếp tục được thực thi theo nhánh mà điều kiện rẽ nhánh

ở câu lệnh 1 nhận giá trị true Khi thực thi các câu lệnh gán 2, 3, 4 thì giá trị của các biến được cập nhật với giá trị mới Khi tới câu lệnh rẽ nhánh 5, thêm 2 nhánh

đi mới được xem xét để thực thi với các giá trị tượng trưng PC tiếp tục được cập nhật theo các nhánh tương ứng

Tại đây, PC được cập nhật với điều kiện rẽ nhánh ở 5 trở thành false do không tồn tại bộ giá trị nào thỏa mãn PC Vì vậy hàm Swap chỉ thực thi theo nhánh

mà PC được cập nhật với biểu thức phủ định của điều kiện rẽ nhánh tại 5 Và câu lệnh 6 sẽ không bao giờ được thực thi

Tại mỗi điểm rẽ nhánh, PC được cập nhật và một bộ xử lý ràng buộc được sử dụng để xác định nhánh tương ứng với PC đó có khả thi hay không để điều hướng việc thực thi hiện thời đi theo nhánh đó Nếu PC được đánh giá tới false thì SE sẽ quay lui và chỉ thực thi chương trình theo nhánh mà PC được đánh giá tới true

3.1.3 Thực thi tượng trưng động

Thực thi tượng trưng động[14, 25] là kỹ thuật thực thi tương trưng dựa trên phân tích chương trình động Thực thi tượng trưng động chính là sự kết hợp giữa thực thi cụ thể và thực thi tượng trưng Trong thực thi tượng trưng động, chương trình được thực thi nhiều lần với những giá trị khác nhau của tham số đầu vào Bắt đầu bằng việc chọn những giá trị tùy ý cho các tham số đầu vào và thực thi chương trình với những giá trị cụ thể đó Với những giá trị cụ thể này thì chương trình sẽ được thực thi theo một đường đi xác định Thực thi chương trình với các giá trị cụ thể của tham số đầu vào và thu gom các ràng buộc trong quá trình thực thi theo đường đi mà sự thực thi cụ thể này đi theo, đồng thời suy ra các ràng buộc mới từ những ràng buộc đã thu gom được

Tại các câu lệnh rẽ nhánh, biểu thức điều kiện rẽ nhánh sẽ được đánh giá phụ thuộc vào các giá trị cụ thể của các tham số đầu vào Nếu biểu thức điều kiện rẽ nhánh nhận giá trị là True thì biểu thức của điều kiện rẽ nhánh sẽ được thu gom

Trang 31

vào ràng buộc của PC và được ghi nhớ, đồng thời phủ định của điều kiện rẽ nhánh

sẽ được sinh ra và được thêm vào một PC tương ứng với nhánh còn lại mà sự thực thi cụ thể đó không đi theo Một bộ xử lý ràng buộc (Constraint Solver) sẽ được sử dụng để giải quyết các ràng buộc mới sinh ra này để sinh ra các giá trị cụ thể của tham số đầu vào Ngược lại, nếu là False thì biểu thức phủ định của điều kiện rẽ nhánh sẽ được thu gom vào ràng buộc của PC tương ứng với nhánh đi mà sự thực thi hiện thời đang đi theo và được ghi nhớ Đồng thời điều kiện rẽ nhánh sẽ được sinh ra và thêm vào PC tương ứng với nhánh đi còn lại mà sự thực thi hiện thời không đi theo Các giá trị mới được sinh ra của các tham số đầu vào sẽ tiếp tục được thực thi và quá trình này sẽ được lặp lại cho tới khi chương trình được thực thi theo tất cả các đường đi

Do các chương trình được thực thi với những giá trị cụ thể nên có thể thấy rằng tất cả các đường đi phân tích được trong quá trình thực thi tượng trưng động đều là các đường đi khả thi

Thuật toán 2.1: DSE

S : Tập hợp tất cả các câu lệnh của chương trình P

s : Tập con của S (s S)

I : Tập hợp các đầu vào của P

P(i): Thực thi chương trình với đầu vào i I, sao cho s được thực thi

J : Tập hợp các đầu vào của P được thực thi (J={i | P(i)})

C(i): Ràng buộc thu gom được từ việc thực thi P(i), hay còn gọi là điều kiện đường đi

C’(i): Điều kiện đường đi suy ra từ C(i)

Trang 32

Tiếp tục thực thi chương trình với giá trị a={} Với a={} khi tới câu lệnh rẽ nhánh 3, biểu thức a.length > 0 nhận giá trị false, ràng buộc C(i): (a!=null) && !(a.length >0) được ghi nhớ Ràng buộc C’(i):(a!=null && a.length > 0) được sinh

ra, solve (C’(i)) ta được giá trị mới của tham số đầu vào là {0}

Tiếp tục thực thi hàm DSE với giá trị a={0} Với giá trị a={0} khi đi tới câu lệnh rẽ nhánh 4, thì biểu thức điều kiện rẽ nhánh nhận giá trị false đo đó ràng buộc C’(i):( a!=null && a.length>0 && a[0]!=123456789) được ghi nhớ Điều kiện C’(i): (a!=null && a.length>0 && a[0]==123456789) được sinh ra, solve (C’(i)) ta được giá trị a={12345678} Đến đây thì không còn đường đi nào của hàm DSE mà chưa được thực thi và qua trình thực thi sẽ được dừng lại

Trang 33

Bảng 3.1: Ví dụ về thực thi tượng trưng độngRàng buộc C’(i) Input i Ràng buộc được ghi nhớ C(i)

a!=null {} a!=null && !(a.length>

0)a!=null&& a.length>

a!=null && a.length>0

&& a[0]!=123456789a!=null &&

a.length>0 && a[0]!=

Với những hệ thống này, mã nguồn chương trình cần được sửa đổi để cho phép thực thi tượng trưng được thực hiện dọc theo việc thực thi cụ thể Chương trình được thực thi với những giá trị ngẫu nhiên với một chiều sâu (depth) định trước của SET Chiều sâu được sử dụng để giúp cho việc thực thi một chương trình được dừng lại trong trường hợp chương trình có vòng lặp vô tận hoặc các hàm đệ quy Khi chương trình bắt đầu được thực thi thì một cây thực thi tương trưng tương ứng cũng được khởi tạo Trong quá trình thực thi, các giá trị tượng trưng của các biến sẽ đươc tính toán và các ràng buộc đường đi sẽ được sinh ra từ các giá trị tượng trưng đó Với mỗi ràng buộc được sinh ra thì SET sẽ được thêm vào một đỉnh (node) tương ứng với ràng buộc đó Việc xây dựng SET tiến hành trong suốt quá trình thực thi Có thể xem mỗi lần thực thi là mỗi lần duyệt một đường đi của

Trang 34

Khi các câu lệnh rẽ nhánh được thực thi, các đường đi trong SET cũng được

mở rộng theo các nhánh đó Với những giá trị cụ thể việc thực thi sẽ đi theo một nhánh cụ thể Nhánh còn lại mà sự thực thi cụ thể đó không đi theo sẽ có một đỉnh mới được tạo ra và được đánh dấu là chưa được thăm Đỉnh mới được tạo ra sẽ lưu các ràng buộc tương ứng với nhánh mà đỉnh đó được thêm vào Sau mỗi lần thực thi, một đỉnh mà chưa được thăm trong SET sẽ được chọn và ràng buộc đường đi tương ứng với đoạn đường đi từ đỉnh gốc (root) của SET tới đỉnh được chọn đó sẽ được thu gom và ràng buộc đường đi này sẽ được đưa tới một bộ xử lý ràng buộc (Constraint Solver) để xử lý Nếu ràng buộc đường đi này không thỏa mãn, một đỉnh khác của SET mà chưa được thăm sẽ được chọn, còn nếu ràng buộc đường đi này thỏa mãn thì bộ xử lý ràng buộc sẽ sinh ra các giá trị đầu vào cụ thể cho lần thực thi tiếp theo Khi các đỉnh tương ứng với các nhánh trong SET đều được thăm hết thì thuật toán sẽ tạm dừng (terminate) Và các giá trị đầu vào cụ thể được sinh

ra cùng với những thông tin phân tích được trong mỗi lần thực thi (method summary) sẽ được sử dụng để sinh ra các UT và cho mục đích báo cáo Các giá trị đầu vào cụ thể được trả về sau mỗi lần chạy được kết hợp với các thông tin về lỗi phát hiện được nếu lần thực thi đó chương trình ngưng lại vì một ngoại lệ chưa được xử lý, hoặc vì một lỗi nào đó

Ví dụ 2.3: Thực thi tượng trưng với phương thức nhận đầu vào là đối tượng

Ta xét một phương thức nhận 2 tham số đầu vào, một tham số là đối tượng SimpleList và một tham số có kiểu int:

Trang 35

1: void Simple(SimpleList o, int x){

số đầu vào được chọn ngẫu nhiên này Sau khi thực thi câu lệnh 2, giá trị tượng trưng của x là S(x)=sym+5, giá trị cụ thể của nó cũng được tính toán (x = -5) Tới câu lệnh rẽ nhánh 3, với giá trị x= -5 thì điều kiện rẽ nhánh được đánh giá tới false Ràng buộc S(x)=sym+5 <= 0 lưu vào đỉnh tương ứng của SET cho nhánh mà sự thực thi cụ thể đi theo và được đánh dấu là đã được thăm, đồng thời một đỉnh mới đại diện cho nhánh còn lại được tạo ra và ràng buộc sym+5 > 0 được lưu vào đỉnh này, đỉnh mới được tạo ra được đánh dấu là chưa được thăm Đến câu lệnh 7 thì một ngoại lệ NullPointerException được ném ra và việc thực thi sẽ dừng lại Cây thực thi tượng trưng được xây dựng tương ứng với lần chạy này (Hình 3(a)) Đỉnh mới được tạo ra của SET mà chưa được thăm được chọn để thu gom ràng buộc trên nhánh tương ứng với đỉnh chưa được thăm đó Ràng buộc thu gom được là sym+5 > 0 Giải quyết ràng buộc này ta được một giá trị cụ thể của x giả sử là x=0

Do không có ràng buộc liên quan tới đối tượng l được tạo ra nên giá trị của nó sẽ

Trang 36

được khởi tạo với phương thức khởi tạo mặc định cho lần thực thi tiếp theo

Sau khi khởi tạo đối tượng o và giải quyết ràng buộc, chương trình tiếp tục được thực thi với các giá trị đầu vào mới này đó là x=0, o=new simpleList() Đỉnh chưa được thăm tương ứng với nhánh thực thi này tạo ra từ lần thực thi trước trong SET sẽ được chọn để mở rộng Đến câu lệnh 4, trường value của đối tượng o được truy cập lần đầu tiên Một giá trị tượng trưng sẽ được kết hợp với nó, và giá trị tượng trưng này được cập nhật do giá trị của trường đó được gán với giá trị của biến x Tới câu lệnh 7, một đối tượng o.next sẽ được khởi tạo lười với một giá trị

cụ thể và một giá trị tượng trưng kết hợp với nó, o.next=new simpleList(), R(o.next)=obj2 Tại câu lệnh rẽ nhánh này, 2 ràng buộc tương ứng với 2 nhánh được tạo ra obj1=obj2, và obj1≠obj2. Ràng buộc obj1≠obj2 tương ứng với nhánh mà sự thực thi cụ thể hiện thời đang đi theo Với ràng buộc obj1=obj2 thì một đỉnh mới được tạo ra tương ứng với nhánh mà sự thực thi cụ thể hiện thời không đi theo để lưu ràng buộc obj1=obj2 và đỉnh mới này được đánh dấu là chưa được thăm Cây thực thi tượng trưng tương ứng với lần thực thi này được biểu thị trong Hình 3(b) Sau khi lần chạy này kết thúc đỉnh mới được tạo ra này lại được chọn để mở rộng

và ràng buộc thu gom được trên đường đi chứa đỉnh này là S(x)=sym+5 > 0 && obj1=obj2 && S(o.value)= sym+5 Ràng buộc đối tượng obj1=obj2 được giải quyết bằng phép gán tham chiếu giữa 2 đối tượng mà các giá trị tượng trưng này đại diện, o.next=o Đối tượng o lúc này được khởi tạo và giá trị của trường value được gán với giá trị sinh ra từ việc giải quyết ràng buộc Cây thực thi tương trưng tương ứng với lần thực thi chương trình với các giá trị đầu vào mới sinh ra này được biểu thị trong Hình 3(c)

Trang 37

Hình 3.2: Cây thực thi tượng trưng được quản lý riêng

3.2 Sinh dữ liệu từ thực thi tượng trưng

3.2.1 Xây dựng ràng buộc

Các công cụ như Pex[30], CUTE[9] được cài đặt dựa trên kỹ thuật thực thi tượng trưng động Tuy nhiên, cần có cơ chế để cho phép một chương trình có thể thực thi tượng trưng Để thực thi tượng trưng một chương trình thì mã nguồn của chương trình đó cần được sửa đổi (instrumented) để hỗ trợ việc thực thi tượng trưng Với một số công cụ như JCUTE[9] thì các chương trình Java được chuyển đổi thành một dạng ngôn ngữ có cấu trúc đơn giản hơn và thêm vào các phần mã

hỗ trợ việc thực thi tượng trưng với ngôn ngữ trung gian này Dạng ngôn ngữ trung gian thường được sử dụng cho ngôn ngữ Java đó là Jimple[17] Bảng 2 dưới minh

Trang 38

họa việc mã nguồn Java được chuyển thành dạng mã Jimple.

Bảng 3.2 Minh họa việc chuyển đổi từ mã nguồn Java sang mã Jimple

void call(int x){// bắt đầu hàm Begin

Trang 39

Việc thực thi tượng trưng một chương trình được biểu thị bằng cây thực thi tượng trưng Do đó một số hệ thống cài đặt thực thi tượng trưng xây dựng và quản

lý cây thực thi tượng trưng riêng để mô tả quá trình thực thi tượng trưng một chương trình Và các ràng buộc trên các đường đi của cây thực thi tượng trưng được quản lý sẽ được thu gom và giải quyết bởi bộ xử lý ràng buộc để sinh ra các đầu vào kiểm thử Cộng cụ Pex cũng xây dựng và quản lý cây thực thi tượng trưng

để sinh các đầu vào cho PUT Ví dụ 2.3 ở trên chính là một minh họa về hệ thống như thế

Ngày đăng: 20/12/2016, 10:15

Nguồn tham khảo

Tài liệu tham khảo Loại Chi tiết
[5] Saswat Anand, Corina S. Pasareanu, and Willem Visser. Symbolic execution with abstraction. International Journal on Software Tools for Technology Transfer (STTT) Volume 11 , Issue 1 Pages 53-67 , January 2009 Sách, tạp chí
Tiêu đề: Symbolic execution with abstraction
[6] Willem Visser, Corina S. Pasareanu, and Sarfraz Khurshid. Test input generation with Java PathFinder. In Proceedings of the ACM/SIGSOFT International Symposium on Software Testing and Analysis (ISSTA), pages 97- 107. ACM, 2004 Sách, tạp chí
Tiêu đề: Test input generation with Java PathFinder
[7] Symbolic Execution of Java Byte-code - Perot Systems/NASA Ames Research [8] http://babelfish.arc.nasa.gov/trac/jpf/wiki/projects/jpf-symbc/doc#no1[9] http://javapathfinder.sourceforge.net/ Sách, tạp chí
Tiêu đề: Symbolic Execution of Java Byte-code
[1] Báo cáo tốt nghiệp của Trần Bình Dương –K50CNPM, Đại học công nghệ - Đại học quốc gia Hà Nội Khác
[2] Kỹ thuật sinh test case tự động từ yêu cầu phần mềm: Luận văn ThS/ Vũ Thị Đào; Đại học công nghê – Đại học quốc gia Hà Nội Khác
[3] JPF - SE: A Symbolic Execution Extension to Java PathFinder - Saswat Anand, Corina S. Pasareanu and Willem Visser Khác
[4] Symbolic Execution of Java Byte-code - Corina Pãsãreanu - Perot Systems/NASA Ames Research Khác

HÌNH ẢNH LIÊN QUAN

Hình 2.1: Kiểm thử dựa trên đặc tả - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Hình 2.1 Kiểm thử dựa trên đặc tả (Trang 18)
Hình 2.2: Kiểm thử dựa trên mô hình. - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Hình 2.2 Kiểm thử dựa trên mô hình (Trang 19)
Hình 2.3: Mô hình hóa các vùng trong thiết kế phần mềm - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Hình 2.3 Mô hình hóa các vùng trong thiết kế phần mềm (Trang 22)
Hình 2.4: Thực thi tượng trưng - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Hình 2.4 Thực thi tượng trưng (Trang 24)
Hình 3.1: Cây thực thi tượng trưng - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Hình 3.1 Cây thực thi tượng trưng (Trang 29)
Bảng 3.1: Ví dụ về thực thi tượng trưng động Ràng buộc C’(i) Input i Ràng buộc được ghi nhớ C(i) - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Bảng 3.1 Ví dụ về thực thi tượng trưng động Ràng buộc C’(i) Input i Ràng buộc được ghi nhớ C(i) (Trang 33)
Hình 3.2: Cây thực thi tượng trưng được quản lý riêng - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Hình 3.2 Cây thực thi tượng trưng được quản lý riêng (Trang 37)
Bảng 3.2. Minh họa việc chuyển đổi từ mã nguồn Java sang mã Jimple - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Bảng 3.2. Minh họa việc chuyển đổi từ mã nguồn Java sang mã Jimple (Trang 38)
Hình 3.4: Gán giá trị tượng trưng cho tham số đầu vào - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Hình 3.4 Gán giá trị tượng trưng cho tham số đầu vào (Trang 42)
Hình 3.5: Thực thi tượng trưng với câu lệnh gán - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Hình 3.5 Thực thi tượng trưng với câu lệnh gán (Trang 43)
Bảng 3.3: Sửa đổi chương trình với câu lệnh liên quan tới đối tượng - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Bảng 3.3 Sửa đổi chương trình với câu lệnh liên quan tới đối tượng (Trang 45)
Hình 3.7: Khởi tạo đối tượng làm đầu vào cho chương trình - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Hình 3.7 Khởi tạo đối tượng làm đầu vào cho chương trình (Trang 47)
Hình 3.9: Kiến trúc JPF - NGHIÊN cứu áp DỤNG JAVA PATHFINDER TRONG tự ĐỘNG SINH TEST CASE
Hình 3.9 Kiến trúc JPF (Trang 51)

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

TÀI LIỆU LIÊN QUAN

w