Tải bản đầy đủ (.pdf) (78 trang)

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

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (1.34 MB, 78 trang )

ĐẠ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

1


Thái Nguyên, năm 2016

2


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

ĐỒ ÁN
TỐT NGHIỆP ĐẠI HỌC
Ngành Công nghệ phần mềm
Đề tài:

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



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

4


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.


5


MỤC LỤC
LỜI CẢM ƠN
MỤC LỤC

1

4

LỜI MỞ ĐẦU

1

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
1.3. Các chiến lược kiểm thử

3

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 case 13
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)
3.1.1. Những khái niệm cơ bản liên quan
6

16

16


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

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

27

3.2. Thực thi tượng trưng với công cụ JPF
3.2.1. Kiến trúc JPF

27
39

39

3.3. Junit 41
3.3.1. Khái niệm

41

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.
3.3.4. Ví dụ test chức năng của một lớp
3.3.5. Setup và tear down

41

42

45


3.4. Tổ chức các test vào các test suite 47
3.5 Chạy các test lặp

49

3.6 Test Exception

49

3.7 Giới thiệu một số công cụ, thư viện hỗ trợ việc test phần mềm. 50
3.8. Các kết quả thực nghiệm. 51
KẾT LUẬN

55

TÀI LIỆU THAM KHẢO 56

7


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
Hình 2.4: Thực thi tượng trưng

13

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án 33
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ượng 38
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
8


đ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
9


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
10


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
11


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ử
12


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.
1.4. Các cấp độ kiểm thử
Kiểm thử phần mềm gồm có các cấp độ: Kiểm thử đơn vị, Kiểm thử tích
hợp, Kiểm thử hệ thống và Kiểm thử chấp nhận.
1.4.1. Kiểm thử đơn vị - Unit test
13


Một đơn vị là một thành phần phần mềm nhỏ nhất mà ta có thẻ kiểm thử
được. Ví dụ, các hàm ( Function), thủ tục (Procedure), lớp (Class) hay phương
phức (Method) đều có thể được xem là Unit.
Vì Unit được chọn để kiểm tra thường có kích thước nhỏ và chức năng hoạt
động đơn giản, chúng ta không khó khăn gì trong việc tổ chức kiểm thử, ghi nhận
và phân tích kết quả kiểm thử. Nếu phát hiện lỗi, việc xác định nguyên nhân và
khắc phục cũng tương đối dễ dàng vì chỉ khoanh vùng trong một đơn thể Unit
đang kiểm tra. Một nguyên lý đúc kết từ thực tiễn: thời gian tồn cho Unit Test sẽ
được đền bù bằng việc tiết kiệm rất nhiều thời gian và chi phí cho việc kiểm thử và
sửa lỗi ở các mức kiểm thử sau đó.
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
14


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
15


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.

16


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
17


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.

18


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
19



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
20



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.

21



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

22


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 đó.

23


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 “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.


24


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)
25


×