LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục...

96
LỜI CẢM ƠN Trong suốt quá trình học tập và làm luận văn, tôi đã nhận được sự hướng dẫn, giúp đỡ quý báu của quý thầy cô, các anh chị và các bạn. Với lòng kính trọng và biết ơn sâu sắc tôi xin được bày tỏ lời cảm ơn chân thành tới: Ban giám hiệu, Phòng đào tạo sau đại học trường Đại Học Khoa Học Tự Nhiên; Phó giáo sư - Tiến sĩ Đoàn Văn Ban - người thầy đã hết lòng giúp đỡ, dạy bảo, động viên và tạo mọi điều kiện thuận lợi cho tôi trong suốt quá trình học tập và hoàn thành luận văn tốt nghiệp. Cùng tất cả các thầy cô trong khoa, trong trường, các anh chị trong lớp. Xin chân thành cảm ơn các thầy cô trong hội đồng đã cho tôi những đóng góp quý báu để hoàn chỉnh luận văn này. Tác giả Phạm Thị Miên

Transcript of LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục...

Page 1: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

LỜI CẢM ƠN

Trong suốt quá trình học tập và làm luận văn, tôi đã nhận được sự hướng

dẫn, giúp đỡ quý báu của quý thầy cô, các anh chị và các bạn. Với lòng kính

trọng và biết ơn sâu sắc tôi xin được bày tỏ lời cảm ơn chân thành tới:

Ban giám hiệu, Phòng đào tạo sau đại học trường Đại Học Khoa Học

Tự Nhiên;

Phó giáo sư - Tiến sĩ Đoàn Văn Ban - người thầy đã hết lòng giúp đỡ,

dạy bảo, động viên và tạo mọi điều kiện thuận lợi cho tôi trong suốt quá

trình học tập và hoàn thành luận văn tốt nghiệp.

Cùng tất cả các thầy cô trong khoa, trong trường, các anh chị trong lớp.

Xin chân thành cảm ơn các thầy cô trong hội đồng đã cho tôi những

đóng góp quý báu để hoàn chỉnh luận văn này.

Tác giả

Phạm Thị Miên

Page 2: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

2

MỤC LỤC

LỜI CẢM ƠN ................................................................................................................... 1

MỤC LỤC ........................................................................................................................ 2

I) DANH MỤC CÁC TỪ VIẾT TẮT, THUẬT NGỮ........................................................ 5

II) DANH MỤC CÁC BẢNG BIỂU ................................................................................. 5

III) DANH MỤC CÁC HÌNH VẼ ..................................................................................... 5

LỜI MỞ ĐẦU ................................................................................................................... 6

CHƯƠNG 1 – KHÁI QUÁT VỀ KIỂM THỬ PHẦN MỀM............................................. 9

1.1. Khái niệm ............................................................................................................... 9

1.2. Các cấp độ kiểm thử phần mềm .............................................................................. 9

1.2.1. Kiểm thử đơn vị (Unit Test) ........................................................................... 10

1.2.2. Kiểm thử tích hợp (Integration Test) .............................................................. 10

1.2.3. Kiểm thử hệ thống (System Test) ................................................................... 11

1.2.4. Kiểm thử chấp nhận sản phẩm (Acceptance Test)........................................... 13

1.3. Kỹ thuật kiểm thử phần mềm ................................................................................ 13

1.3.1. Kỹ thuật kiểm thử hộp đen (Black – box Testing) ........................................... 13

1.3.1.1. Phân hoạch tương đương ......................................................................... 15

1.3.1.2. Phân tích giá trị biên ................................................................................ 17

1.3.2. Kỹ thuật kiểm thử hộp trắng (White – box Testing) ........................................ 18

1.3.2.1. Kiểm thử đường dẫn cơ sở....................................................................... 18

1.3.2.2. Kiểm thử cấu trúc điều khiển ................................................................... 23

1.4. Kết luận ............................................................................................................ 26

CHƯƠNG 2 – KỸ THUẬT KIỂM THỬ ĐỘT BIẾN ...................................................... 27

2.1. Một số khái niệm .................................................................................................. 27

2.1.1. Kiểm thử đột biến .......................................................................................... 27

2.1.2. Đột biến ......................................................................................................... 27

2.1.3. Toán tử đột biến ............................................................................................. 30

2.2. Cơ sở của kiểm thử đột biến .................................................................................. 30

2.3. Toán tử đột biến .................................................................................................... 30

2.4. Quy trình kiểm thử đột biến .................................................................................. 32

2.5. Hạn chế của kiểm thử đột biến .............................................................................. 34

2.6. Kết luận ................................................................................................................ 35

Page 3: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

3

CHƯƠNG 3 - MỘT SỐ CẢI TIẾN KỸ THUẬT KIỂM THỬ ĐỘT BIẾN ...................... 36

3.1. Giảm chi phí tính toán........................................................................................... 36

3.1.1. Phương pháp làm ít hơn (A “do fewer” approach) .......................................... 36

3.1.1.1. Lấy mẫu đột biến (Mutant Sampling) ..................................................... 37

3.1.1.2. Đột biến ràng buộc (Constrained Mutation) ............................................. 39

3.1.1.3. N - đột biến lựa chọn (N - Selective Mutation) ....................................... 40

3.1.2. Phương pháp làm nhanh hơn (A “do smarter” approach) ................................ 42

3.1.2.1. Phương pháp tạo lược đồ đột biến ........................................................... 43

3.1.2.2. Đột biến yếu (Weak Mutation) ................................................................ 45

3.2. Tăng tự động hóa .................................................................................................. 48

3.2.1. Tạo dữ liệu thử tự động .................................................................................. 48

3.2.2. Xác định các đột biến tương đương tự động ................................................... 50

3.3. Kết luận ............................................................................................................ 53

CHƯƠNG 4 - ỨNG DỤNG KỸ THUẬT KIỂM THỬ ĐỘT BIẾN ĐỂ KIỂM THỬ CÁC

CHƯƠNG TRÌNH C (C – Sharp) .................................................................................... 54

4.1. Tìm hiểu về NUnit ................................................................................................ 55

4.1.1. Định nghĩa ..................................................................................................... 55

4.1.2. Đặc điểm của NUnit ....................................................................................... 55

4.1.3. Thuộc tính hay dùng trong thư viện NUnit.Framework................................... 55

4.1.4. Phương thức tĩnh hay dùng trong NUnit.Framework.Assert ........................... 57

4.1.5. Cài đặt NUnit ................................................................................................. 59

4.1.6. Cách sử dụng NUnit ....................................................................................... 61

4.2. Công cụ Nester ..................................................................................................... 69

4.2.1. Điều kiện tiên quyết ....................................................................................... 69

4.2.2. Giải pháp cho đột biến ................................................................................... 69

4.2.3. Chạy Nester ................................................................................................... 70

4.2.4. Lựa chọn Nester.exe.config ........................................................................... 72

4.3. Quy trình ứng dụng kiểm thử đột biến để kiểm thử các chương trình C - Sharp ..... 72

4.3.1. Kiểm thử ........................................................................................................ 73

4.3.2. Tạo đột biến ................................................................................................... 74

4.4. Kết luận ................................................................................................................ 76

KẾT LUẬN..................................................................................................................... 77

TÀI LIỆU THAM KHẢO ............................................................................................... 79

Page 4: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

4

PHỤ LỤC 1 .................................................................................................................... 82

PHỤ LỤC 2 .................................................................................................................... 84

PHỤ LỤC 3 .................................................................................................................... 90

PHỤ LỤC 4 .................................................................................................................... 94

PHỤ LỤC 5 .................................................................................................................... 95

Page 5: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

5

I) DANH MỤC CÁC TỪ VIẾT TẮT, THUẬT NGỮ

- CBT (Constraint Based Testing): Kiểm thử dựa trên ràng buộc

- MSG (Mutation Analysis Using Mutant Schemata): Phương pháp tạo

lược đồ đột biến

- PUT (Program Unit Test): Chương trình gốc

II) DANH MỤC CÁC BẢNG BIỂU

Bảng 1.1. Ví dụ các lớp tương đương

Bảng 2.1. 22 toán tử chuẩn được sử dụng trong Mothra

Bảng 4.1. Lựa chọn Nester.exe.config

Bảng 4.2. Kết quả chạy NUnit

Bảng 4.3. Chất lượng các trường hợp kiểm thử chương trình cs – money

sau khi thực hiện Nester

III) DANH MỤC CÁC HÌNH VẼ

Hình 1.1. Bốn cấp độ cơ bản của kiểm thử phần mềm

Hình 1.2. Đồ thị luồng điều khiển

Hình 1.3. Ví dụ minh hoạ phát sinh các trường hợp kiểm thử theo đường

dẫn cơ sở

Hình 1.4. Các kiểu vòng lặp

Hình 2.1. Ví dụ về đột biến tương đương

Hình 2.2. Ví dụ về đột biến

Hình 3.1. Ba kịch bản có thể có cho quan hệ giữa các tập dữ liệu thử diệt

đột biến yếu và mạnh

Hình 3.2. Phân bố đột biến bằng toán tử đột biến cho Mothra

Hình 3.3. Ví dụ phương thức gốc (PUT)

Hình 3.4. Phiên bản đột biến của PUT gốc hình 3.3

Hình 4.1. Quy trình ứng dụng kiểm thử đột biến trong C#

Page 6: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

6

LỜI MỞ ĐẦU

Kiểm thử phần mềm là một hoạt động giữ vai trò rất quan trọng để bảo

đảm chất lượng phần mềm và là hoạt động mang tính sống còn trong các dự

án sản xuất hoặc gia công phần mềm. Vì vậy, kiểm thử phần mềm đã trở

thành qui trình bắt buộc trong các dự án phát triển phần mềm trên thế giới. Ở

Việt Nam, ngành công nghiệp phần mềm đang phát triển thì không thể xem

nhẹ việc kiểm thử phần mềm vì xác suất thất bại sẽ rất cao, hơn nữa, hầu hết

các công ty phần mềm có uy tín đều đặt ra yêu cầu nghiêm ngặt là nếu một

phần mềm không có tài liệu kiểm thử đi kèm thì sẽ không được chấp nhận.

Tuy nhiên, hoạt động kiểm thử thường gặp nhiều khó khăn:

Thứ nhất, kiểm thử các hệ thống phức tạp đòi hỏi rất nhiều nguồn

tài nguyên và chi phí cao.

Thứ hai, tiến trình phát triển phần mềm luôn trải qua nhiều hoạt

động biến đổi thông tin, sự mất mát thông tin trong quá trình biến

đổi là yếu tố chính làm cho hoạt động kiểm thử khó khăn.

Thứ ba, kiểm thử chưa được chú trọng trong đào tạo con người.

Cuối cùng, không tồn tại kỹ thuật kiểm thử cho phép khẳng định

một phần mềm hoàn toàn đúng đắn hay không chứa lỗi.

Với mục đích phát hiện lỗi, kiểm thử phần mềm thường phải trải qua các

bước: tạo dữ liệu thử, thực thi phần mềm trên dữ liệu thử và quan sát kết quả

nhận được. Trong các bước này, bước tạo dữ liệu đóng vai trò quan trọng nhất,

bởi vì chúng ta không thể tạo ra mọi dữ liệu từ miền vào của chương trình, mà

chúng ta chỉ có thể tạo ra các dữ liệu thử có khả năng phát hiện lỗi cao nhất.

Vấn đề đặt ra là làm thế nào để đánh giá được khả năng phát hiện lỗi của một

bộ dữ liệu thử?

Một kinh nghiệm để giúp giải quyết vấn đề này, đó là sử dụng khái niệm

chất lượng bộ dữ liệu thử như là một phương tiện để đánh giá bộ dữ liệu thử

như thế nào là “tốt” khi kiểm thử chương trình. Ở đây, “tốt” được đánh giá

Page 7: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

7

liên quan đến tiêu chuẩn chất lượng được định trước, thường là một số dấu

hiệu bao phủ chương trình. Ví dụ, tiêu chuẩn bao phủ dòng lệnh đòi hỏi bộ dữ

liệu thử thực hiện mọi dòng lệnh trong chương trình ít nhất một lần. Nếu bộ

dữ liệu thử được tìm thấy không chất lượng liên quan đến tiêu chuẩn (tức là

không phải tất cả các câu lệnh đều được thực hiện ít nhất một lần), thì kiểm

thử nữa là bắt buộc. Do đó, mục tiêu là tạo ra một tập các kiểm thử thực hiện

đầy đủ tiêu chuẩn chất lượng.

Tiêu chuẩn chất lượng tiêu biểu như bao phủ câu lệnh và kiểm thử quyết

định (thực hiện tất cả các đường dẫn đúng và sai qua chương trình) dựa vào

việc thực hiện chương trình với số lượng kiểm thử tăng dần để nâng cao độ

tin cậy của chương trình đó. Tuy nhiên, chúng không tập trung vào nguyên

nhân thất bại của chương trình - được gọi là lỗi. Kiểm thử đột biến là một tiêu

chuẩn như vậy. Tiêu chuẩn này tạo ra các phiên bản của chương trình có chứa

các lỗi đơn giản và sau đó tìm ra các kiểm thử để chỉ ra các dấu hiệu của lỗi.

Nếu có thể tìm thấy một bộ dữ liệu thử chất lượng làm lộ ra các dấu hiệu này

ở tất cả các phiên bản bị lỗi, thì sự tin tưởng vào tính đúng đắn của chương

trình sẽ tăng. Kiểm thử đột biến đã được áp dụng cho nhiều ngôn ngữ lập

trình như là một kỹ thuật kiểm thử hộp trắng.

Ý thức được đây là một lĩnh vực nghiên cứu có nhiều triển vọng ứng

dụng trong phát triển phần mềm, tôi đã chọn hướng nghiên cứu “ Các kỹ

thuật kiểm thử đột biến và ứng dụng kiểm thử chương trình C” cho đề tài

luận văn của mình.

Luận văn được tổ chức thành 4 chương như sau:

Chương 1 – Trình bày khái quát về kiểm thử phần mềm như khái

niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử

phần mềm. Chương này cũng đề cập đến việc sử dụng các kỹ thuật

kiểm thử hộp trắng và hộp đen để thiết kế dữ liệu thử.

Page 8: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

8

Chương 2 - Mô tả chi tiết các thành phần chính của kỹ thuật kiểm thử

đột biến, giới thiệu các giả thuyết cơ bản cần thiết để thực hiện

phương pháp này. Chương này còn cung cấp quy trình để phân tích

đột biến, từ đó rút ra được những vấn đề còn hạn chế đối với kỹ thuật

kiểm thử đột biến, được cải tiến ở chương 3.

Chương 3 – Giới thiệu một số phương pháp cải tiến kỹ thuật kiểm

thử đột biến nhằm giảm chi phí tính toán và tăng tự động hóa.

Chương 4 – Tập trung vào ứng dụng kỹ thuật kiểm thử đột biến.

Phần đầu giới thiệu hai công cụ mã nguồn mở miễn phí là NUnit dùng

để kiểm thử đơn vị của chương trình C#, và Nester với chức năng

phân tích và tạo đột biến. Tiếp đó là ứng dụng kỹ thuật kiểm thử đột

biến để kiểm thử các chương trình C# sử dụng hai công cụ trên.

Page 9: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

9

CHƯƠNG 1 – KHÁI QUÁT VỀ

KIỂM THỬ PHẦN MỀM

1.1. Khái niệm

Kiểm thử phần mềm là quá trình thực thi một hệ thống phần mềm để xác

định xem phần mềm có đúng với đặc tả không và thực hiện trong môi trường

như mong đợi hay không.

Mục đích của kiểm thử phần mềm là tìm ra lỗi chưa được phát hiện, tìm

một cách sớm nhất và bảo đảm rằng lỗi sẽ được sửa.

Mục tiêu của kiểm thử phần mềm là thiết kế tài liệu kiểm thử một cách

có hệ thống và thực hiện nó sao cho có hiệu quả, nhưng tiết kiệm được thời

gian, công sức và chi phí.

1.2. Các cấp độ kiểm thử phần mềm

Cấp độ kiểm thử phần mềm được thể hiện ở hình 1.1 [25]:

Kiểm thử mức đơn vị lập trình

(Unit test)

Kiểm thử mức tích hợp các đơn vị (Integration test)

Kiểm thử mức hệ thống, sau khi tích hợp

(System test)

Kiểm thử để chấp nhận sản phẩm

(Acceptance test)

Các bộ phận đơn lẻ

Các nhóm bộ phận

Toàn bộ hệ thống

Toàn bộ hệ thống nhìn từ khách hàng

Hình 1.1- Bốn cấp độ cơ bản của kiểm thử phần mềm

Page 10: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

10

1.2.1. Kiểm thử đơn vị (Unit Test)

Một đơn vị (Unit) 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),

hoặc các phương thức (Method).

Kiểm thử đơn vị 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.

Mục đích của kiểm thử đơn vị là bảo đảm thông tin được xử lý và kết

xuất (khỏi Unit) là chính xác, trong mối tương quan với dữ liệu nhập và chức

năng xử lý 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.

Cũng như các mức kiểm thử khác, kiểm thử đơn vị cũng đòi hỏi phải

chuẩn bị trước các ca kiểm thử (hay trường hợp kiểm thử) (test case) hoặc

kịch bản (test script), trong đó chỉ định rõ dữ liệu vào, các bước thực hiện và

dữ liệu mong muốn sẽ xuất ra. Các test case và test script được giữ lại để sử

dụng sau này.

1.2.2. Kiểm thử tích hợp (Integration Test)

Kiểm thử tích hợp 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 kiểm thử đơn vị kiểm tra các

thành phần và Unit riêng lẻ thì kiểm thử tích hợp kết hợp chúng lại với nhau

và kiểm tra sự giao tiếp giữa chúng.

Kiểm thử tích hợp có hai mục tiêu chính là:

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 con (gọi là subsystem)

và cuối cùng là nguyên hệ thống hoàn chỉnh chuẩn bị cho kiểm thử ở

mức hệ thống (system test).

Có 4 loại kiểm thử trong kiểm thử tích hợp như sau:

Page 11: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

11

Kiểm thử cấu trúc (Structure test): Kiểm thử 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, 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 lệnh và nhánh bên trong.

Kiểm thử chức năng (Functional test): Kiểm thử chỉ chú trọng đến

chức năng của chương trình, 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 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.

1.2.3. Kiểm thử hệ thống (System Test)

Mục đích của kiểm thử hệ thống là kiểm thử xem thiết kế và toàn bộ hệ

thống (sau khi tích hợp) có thỏa mãn yêu cầu đặt ra hay không.

Kiểm thử hệ thống kiểm tra cả các hành vi chức năng của phần mềm lẫn

các yêu cầu về chất lượng như độ tin cậy, tính tiện lợi khi sử dụng, hiệu năng

và bảo mật.

Kiểm thử hệ thống bắt đầu khi tất cả các bộ phận của phần mềm đã được

tích hợp thành công. Thông thường loại kiểm thử này tốn rất nhiều công sức

và thời gian. Trong nhiều trường hợp, việc kiểm thử đòi hỏi một số thiết bị

phụ trợ, phần mềm hoặc phần cứng đặc thù, đặc biệt là các ứng dụng thời gian

thực, hệ thống phân bố, hoặc hệ thống nhúng. Ở mức độ hệ thống, người kiểm

thử cũng tìm kiếm các lỗi, nhưng trọng tâm là đánh giá về hoạt động, thao tác,

sự tin cậy và các yêu cầu khác liên quan đến chất lượng của toàn hệ thống.

Điểm khác nhau then chốt giữa kiểm thử tích hợp và kiểm thử hệ thống

là kiểm thử hệ thống chú trọng các hành vi và lỗi trên toàn hệ thống, còn kiểm

thử tích hợp chú trọng sự giao tiếp giữa các đơn thể hoặc đối tượng khi chúng

làm việc cùng nhau. Thông thường ta phải thực hiện kiểm thử đơn vị và kiểm

Page 12: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

12

thử tích hợp để bảo đảm mọi Unit và sự tương tác giữa chúng hoạt động chính

xác trước khi thực hiện kiểm thử hệ thống.

Sau khi hoàn thành kiểm thử tích hợp, một hệ thống phần mềm đã được

hình thành cùng với các thành phần đã được kiểm tra đầy đủ. Tại thời điểm

này, lập trình viên hoặc kiểm thử viên (Tester) bắt đầu kiểm thử phần mềm

như một hệ thống hoàn chỉnh. Việc lập kế hoạch cho kiểm thử hệ thống nên

bắt đầu từ giai đoạn hình thành và phân tích các yêu cầu. Đòi hỏi nhiều công sức, thời gian và tính chính xác, khách quan, kiểm

thử hệ thống được thực hiện bởi một nhóm kiểm tra viên hoàn toàn độc lập

với nhóm phát triển dự án để đảm bảo tính chính xác và khách quan.

Kiểm thử hệ thống thường có các loại kiểm thử sau:

Kiểm thử chức năng (Functional test): Bảo đảm các hành vi của hệ

thống thỏa mãn đúng yêu cầu thiết kế.

Kiểm thử khả năng vận hành (Performance test): Bảo đảm tối ưu việc

phân bổ tài nguyên hệ thống (ví dụ bộ nhớ) nhằm đạt các chỉ tiêu như

thời gian xử lý hay đáp ứng câu truy vấn,....

Kiểm thử khả năng chịu tải (Stress test hay Load test): Bảo đảm hệ

thống vận hành đúng dưới áp lực cao (ví dụ nhiều người truy xuất

cùng lúc). Stress test tập trung vào các trạng thái tới hạn, các "điểm

chết", các tình huống bất thường như đang giao dịch thì ngắt kết nối

(xuất hiện nhiều trong test thiết bị như POS, ATM),....

Kiểm thử cấu hình (Configuration test): Đảm bảo hệ thống hoạt động

tương thích với các loại phần cứng khác nhau.

Kiểm thử khả năng bảo mật (Security test): Bảo đảm tính toàn vẹn,

bảo mật của dữ liệu và của hệ thống.

Kiểm thử khả năng phục hồi (Recovery test): Bảo đảm hệ thống có

khả năng khôi phục trạng thái ổn định trước đó trong tình huống mất

Page 13: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

13

tài nguyên hoặc dữ liệu; đặc biệt quan trọng đối với các hệ thống giao

dịch như ngân hàng trực tuyến.

1.2.4. Kiểm thử chấp nhận sản phẩm (Acceptance Test)

Mục đích của kiểm thử chấp nhận là kiểm thử khả năng chấp nhận cuối

cùng để chắc chắn rằng sản phẩm là phù hợp và thỏa mãn các yêu cầu của

khách hàng và khách hàng chấp nhận sản phẩm.

Trong giai đoạn kiểm thử chấp nhận thì người kiểm tra là khách hàng.

Khách hàng sẽ đánh giá phần mềm với mong đợi theo những thao tác sử

dụng quen thuộc của họ. Việc kiểm tra ở giai đoạn này có ý nghĩa hết sức

quan trọng tránh cho việc hiểu sai yêu cầu cũng như sự mong đợi của khách

hàng.

Gắn liền với giai đoạn kiểm thử chấp nhận thường là một nhóm những

dịch vụ và tài liệu đi kèm, phổ biến như hướng dẫn cài đặt, sử dụng, v.v…Tất

cả tài liệu đi kèm phải được cập nhật và kiểm tra chặt chẽ.

1.3. Kỹ thuật kiểm thử phần mềm

Mục tiêu của kiểm thử là phải thiết kế các trường hợp kiểm thử có khả

năng cao nhất trong việc phát hiện nhiều lỗi với thời gian và công sức tối

thiểu. Do đó có thể chia các kỹ thuật kiểm thử thành hai loại:

Kỹ thuật kiểm thử hộp đen (Black – box Testing) hay còn gọi là kỹ

thuật kiểm thử chức năng (Functional Testing).

Kỹ thuật kiểm thử hộp trắng (White – box Testing) hay còn gọi là kỹ

thuật kiểm thử cấu trúc (Structural Testing).

1.3.1. Kỹ thuật kiểm thử hộp đen (Black – box Testing)

Kiểm thử hộp đen còn được gọi là kiểm thử hướng dữ liệu (data -

driven) hay là kiểm thử hướng vào/ra (input/output driven).

Trong kỹ thuật này, người kiểm thử xem phần mềm như là một hộp đen.

Người kiểm thử hoàn toàn không quan tâm đến cấu trúc và hành vi bên trong

Page 14: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

14

của chương trình. Người kiểm thử chỉ cần quan tâm đến việc tìm các hiện

tượng mà phần mềm không hành xử theo đúng đặc tả của nó. Do đó, dữ liệu

kiểm thử sẽ xuất phát từ đặc tả.

Như vậy, cách tiếp cận kiểm thử hộp đen tập trung vào các yêu cầu chức

năng của phần mềm. Kiểm thử hộp đen cho phép người kiểm thử xây dựng

các nhóm giá trị đầu vào sẽ thực thi đầy đủ tất cả các yêu cầu chức năng của

chương trình. Kiểm thử hộp đen không thay thế kỹ thuật kiểm thử hộp trắng,

nhưng nó bổ sung khả năng phát hiện các lớp lỗi khác với các phương pháp

hộp trắng.

Kiểm thử hộp đen cố gắng tìm các loại lỗi sau:

Các chức năng thiếu hoặc không đúng.

Các lỗi giao diện.

Các lỗi cấu trúc dữ liệu trong truy cập cơ sở dữ liệu bên ngoài.

Các lỗi thực hiện.

Các lỗi khởi tạo hoặc kết thúc.

Và các lỗi khác ...

Không giống với kiểm thử hộp trắng được thực hiện sớm trong quá trình

kiểm thử, kiểm thử hộp đen được áp dụng trong các giai đoạn sau của kiểm

thử. Vì kiểm thử hộp đen không để ý có chủ đích cấu trúc điều khiển, sự quan

tâm tập trung trên miền thông tin. Nếu người kiểm thử muốn sử dụng phương

pháp này để tìm tất cả các lỗi trong chương trình thì điều kiện bắt buộc là phải

kiểm thử tất cả các đầu vào, tức là mỗi một điều kiện đầu vào có thể có là một

trường hợp kiểm thử. Bởi vì nếu chỉ kiểm thử một số điều kiện đầu vào thì

không đảm bảo được chương trình đã hết lỗi. Vì thế, để đạt được mục tiêu

kiểm thử, người ta đã áp dụng một số phương pháp kiểm thử hộp đen như:

phân hoạch tương đương, phân tích giá trị biên.

Page 15: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

15

1.3.1.1. Phân hoạch tương đương

Do việc kiểm thử tất cả các đầu vào của chương trình là không thể. Vì

thế, khi kiểm thử chương trình nên giới hạn một tập con tất cả các trường hợp

đầu vào có thể có, sao cho có xác suất tìm ra được nhiều lỗi nhất.

Một tập con như vậy cần có hai tính chất sau:

Mỗi trường hợp kiểm thử nên gồm nhiều điều kiện đầu vào khác nhau

có thể để giảm thiểu tổng số các trường hợp cần thiết.

Cố gắng phân hoạch các miền đầu vào của một chương trình thành

một số xác định các lớp tương đương, sao cho có thể giả định hợp lý

rằng việc kiểm thử một giá trị đại diện của mỗi lớp là tương đương

với việc kiểm thử với một giá trị bất kỳ trong cùng lớp.

Thiết kế các trường hợp kiểm thử bằng phân hoạch tương đương được xử

lý theo hai bước: Phân hoạch các miền đầu vào/ra thành các lớp tương đương,

và thiết kế các trường hợp kiểm thử đại diện cho mỗi lớp.

a) Xác định các lớp tương đương

Các lớp tương đương được nhận dạng bằng cách lấy mỗi điều kiện đầu

vào (thông thường là một câu lệnh hoặc một cụm từ trong đặc tả) và phân

hoạch nó thành hai hay nhiều nhóm. Các lớp tương đương bao gồm một tập

các trạng thái hợp lệ hoặc không hợp lệ cho điều kiện đầu vào. Điều kiện đầu

vào là giá trị số xác định, hoặc là miền giá trị, tập giá trị có liên quan, hoặc

điều kiện logic. Để làm điều này, chúng ta sử dụng bảng liệt kê các lớp tương

đương.

Các lớp tương đương có thể được định nghĩa theo nguyên tắc sau:

1. Nếu điều kiện đầu vào xác định một khoảng giá trị [a,b], thì phân

hoạch thành một lớp tương đương hợp lệ và hai lớp tương đương

không hợp lệ. Chẳng hạn, nếu đầu vào x nằm trong khoảng [1,999],

lớp hợp lệ là: 1 <= x < = 999, các lớp không hợp lệ là x < 1 và x >

999.

Page 16: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

16

2. Nếu điều kiện đầu vào yêu cầu một giá trị xác định, phân hoạch thành

một lớp tương đương hợp lệ và hai lớp tương đương không hợp lệ.

Chẳng hạn, nếu đầu vào x = 3, thì lớp hợp lệ là x = 3, các lớp không

hợp lệ là x < 3 và x > 3.

3. Nếu điều kiện đầu vào xác định một phần tử của tập hợp, thì phân

hoạch thành một lớp tương đương hợp lệ và một lớp tương đương

không hợp lệ.

4. Nếu điều kiện đầu vào là Boolean, thì phân hoạch thành một lớp

tương đương hợp lệ và một lớp tương đương không hợp lệ tương ứng

với hai trạng thái true và false.

Ngoài ra, một nguyên tắc thứ năm được bổ sung là sử dụng khả năng

phán đoán, kinh nghiệm và trực giác của người kiểm thử.

Điều kiện vào/ra Các lớp tương đương hợp lệ

Các lớp tương đương không hợp lệ

Số ID của sinh viên Các thuộc tính khóa Không phải thuộc tính khóa

Tên sinh viên Ký tự chữ cái

Không rỗng

Không phải chữ cái

Rỗng

Giới tính sinh viên Ký tự chữ cái, “M’ hoặc “F” Không phải chữ cái

Không phải “M” hoặc “F”

Điểm của sinh viên Số

Từ 0 đến 100

Không phải số

Số nhỏ hơn 0

Số lớn hơn 100

Bảng 1.1 – Ví dụ các lớp tương đương

b) Xác định các trường hợp kiểm thử

Kế tiếp trong phân hoạch tương đương là thiết kế các trường hợp kiểm

thử dựa trên sự ước lượng của các lớp tương đương cho miền đầu vào. Tiến

trình này được thực hiện như sau:

1. Gán một giá trị duy nhất cho mỗi lớp tương đương

Page 17: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

17

2. Đến khi tất cả các lớp tương đương hợp lệ được phủ bởi các trường

hợp kiểm thử thì viết một trường hợp kiểm thử mới phủ nhiều nhất có

thể các lớp tương đương hợp lệ chưa được phủ.

3. Đến khi tất cả các lớp tương đương không hợp lệ được phủ bởi các

trường hợp kiểm thử thì hãy viết các trường hợp kiểm thử mới sao

cho mỗi trường hợp kiểm thử mới chỉ phủ duy nhất một lớp tương

đương không hợp lệ chưa được phủ.

1.3.1.2. Phân tích giá trị biên

Khi thực hiện kiểm thử phần mềm theo dữ liệu, chúng ta kiểm tra xem

đầu vào của người dùng, kết quả nhận được và kết quả tạm thời bên trong có

được xử lý chính xác hay không.

Các điều kiện biên là tình trạng trực tiếp ở phía trên và dưới của lớp

tương đương đầu vào và lớp đương đương đầu ra. Việc phân tích các giá trị

biên khác với phân hoạch tương đương theo hai điểm:

Từ mỗi lớp tương đương, phân hoạch tương đương sẽ chọn phần tử

bất kỳ làm phần tử đại diện, trong khi việc phân tích giá trị biên sử

dụng một hoặc một số phần tử. Như vậy, mỗi biên của lớp tương

đương chính là đích kiểm thử.

Không chỉ chú ý tập trung những điều kiện đầu vào, các trường hợp

kiểm thử cũng được suy ra từ việc xem xét các kết quả ra (tức là các

lớp tương đương đầu ra).

Có một số nguyên tắc phân tích giá trị biên như sau:

1. Nếu điều kiện đầu vào xác định một khoảng giá trị giữa a và b, các

trường hợp kiểm thử sẽ được thiết kế với giá trị a và b, các giá trị sát

trên và sát dưới a và b.

2. Nếu một điều kiện đầu vào xác định một số các giá trị, các trường hợp

kiểm thử sẽ được phát triển để thực hiện tại các giá trị cực đại, cực

Page 18: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

18

tiểu. Các giá trị sát trên và dưới giá trị cực đại, cực tiểu cũng được

kiểm thử.

3. Nguyên tắc 1 và 2 được áp dụng cho các điều kiện đầu ra.

4. Nếu cấu trúc dữ liệu chương trình bên trong được qui định các biên

(chẳng hạn, mảng được định nghĩa giới hạn 100 mục), tập trung thiết

kế trường hợp kiểm thử để thực thi cấu trúc dữ liệu tại biên của nó.

Ngoài ra, người kiểm thử có thể sử dụng sự suy đoán và sáng tạo của

mình để tìm các điều kiện biên.

Tóm lại, chúng ta phải kiểm thử mỗi biên của một lớp tương đương về

tất cả các phía. Một chương trình nếu vượt qua những trường hợp kiểm thử đó

có thể vượt qua các kiểm thử khác từ lớp đó.

1.3.2. Kỹ thuật kiểm thử hộp trắng (White – box Testing)

Kiểm thử hộp trắng hay còn gọi là kiểm thử hướng logic, cho phép kiểm

tra cấu trúc bên trong của phần mềm với mục đích bảo đảm rằng tất cả các

câu lệnh và điều kiện sẽ được thực hiện ít nhất một lần. Người kiểm thử truy

nhập vào mã nguồn chương trình và có thể kiểm tra nó, lấy đó làm cơ sở để

hỗ trợ việc kiểm thử.

1.3.2.1. Kiểm thử đường dẫn cơ sở

Kiểm thử đường dẫn cơ sở là một kỹ thuật kiểm thử hộp trắng do Tom

McCabe đề xuất. Phương pháp đường dẫn cơ sở cho phép người thiết kế

trường hợp kiểm thử thực hiện phép đo độ phức tạp logic của thiết kế thủ tục

và sử dụng phép đo này như một chỉ dẫn cho việc thiết kế một tập cơ sở các

đường dẫn thực hiện. Những trường hợp kiểm thử được suy diễn để thực hiện

tập cơ sở. Các trường hợp kiểm thử đó được đảm bảo để thực hiện mỗi lệnh

trong chương trình ít nhất một lần trong quá trình kiểm thử.

a) Đồ thị luồng điều khiển

Page 19: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

19

Trong thực tế, phương pháp đường dẫn cơ sở có thể được dùng không

cần sử dụng đồ thị luồng điều khiển. Tuy nhiên, đồ thị luồng điều khiển (minh

họa ở hình 1.2) là một công cụ hữu ích để hiểu các luồng điều khiển và minh

họa cho phương pháp này. Cấu trúc của đồ thị luồng điều khiển bao gồm:

Mỗi đỉnh (hình tròn) biểu thị một đoạn các câu lệnh thực hiện một

cách tuần tự, có thể kết thúc bằng một lệnh rẽ nhánh.

Mỗi cạnh (cung) biểu diễn dòng điều khiển nối hai nút với nhau.

Phần được bao bởi các cung và các đỉnh gọi là miền.

b) Độ phức tạp chu trình

Độ phức tạp chu trình là một thước đo phần mềm, cung cấp các phép đo

định lượng độ phức tạp của chương trình. Khi được sử dụng trong ngữ cảnh

của phương pháp đường dẫn cơ sở, giá trị được xác định cho độ phức tạp chu

trình cho biết số lượng đường dẫn độc lập trong một tập cơ sở của chương

trình và cung cấp cho chúng ta một giới hạn trên số lượng kiểm thử bắt buộc

để đảm bảo rằng tất cả các câu lệnh được thực hiện ít nhất một lần.

Cung

Đỉnh điều kiện

Miền

Hình 1.2 - Đồ thị luồng điều khiển

Page 20: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

20

Việc tính toán độ phức tạp chu trình sẽ cho chúng ta biết có bao nhiêu

đường dẫn cần tìm. Cho đồ thị luồng điều khiển G, độ phức tạp chu trình

V(G) được tính theo một trong 3 công thức sau:

1. V(G) = R, trong đó R là số miền của đồ thị G.

2. V(G) = P + 1, trong đó P là số đỉnh điều kiện có trong đồ thị G.

3. V(G) = E – N + 2, trong đó E là số cung và N là số đỉnh của đồ thị G.

Đối chiếu với đồ thị luồng điều khiển trong hình 1.2, độ phức tạp chu

trình V(G) được tính như sau:

1. Công thức 1: V(G) = R = 6

2. Công thức 2: V(G) = P + 1 = 5 + 1 = 6

3. Công thức 3: V(G) = E – N + 2 = 15 – 11 + 2 = 6

Như vậy, độ phức tạp chu trình của đồ thị luồng điều khiển ở hình 1.2 là

6.

c) Phát sinh các trường hợp kiểm thử theo đường dẫn cơ sở

Phương pháp kiểm thử đường dẫn cơ sở có thể áp dụng để kiểm thử thủ

tục chi tiết hoặc cho mã nguồn bao gồm các bước sau:

Bước 1: Sử dụng mã nguồn hoặc thiết kế để xây dựng đồ thị luồng

điều khiển tương ứng.

Bước 2: Tính toán độ phức tạp chu trình V(G) .

Bước 3: Xác định tập cơ sở của các đường dẫn độc lập (một đường

dẫn được gọi là độc lập với các đường dẫn khác nếu nó có ít nhất một

cạnh không xuất hiện trong các đường dẫn khác).

Bước 4: Chuẩn bị các trường hợp kiểm thử có khả năng thực hiện

mỗi đường dẫn trong tập cơ sở.

Chúng ta dùng hàm tính giá trị trung bình cộng của các số, average trong

C như hình 1.3 để làm ví dụ minh họa cho mỗi bước thiết kế các trường hợp

kiểm thử. Hàm average là một thuật toán đơn giản có chứa các tổ hợp và

vòng lặp, trong đó chương trình tính giá trị trung bình của 100 hoặc một vài

Page 21: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

21

số trong mảng values nằm trong khoảng của biên trên (max) và biên dưới

(min). Đầu vào được kết thúc bằng giá trị -999.

Bước 1: Vẽ đồ thị luồng điều khiển (như hình 1.3)

Bước 2: Tính độ phức tạp chu trình V(G)

V(G) = P (số đỉnh điều kiện) + 1 = 5 + 1 = 6 (trong hình 1.3 có 5

đỉnh điều kiện: 2, 3, 4, 5, 8)

Bước 3: Tìm tập cơ sở của các đường dẫn độc lập

+ Đường dẫn 1: 1 2 8 9 11

+ Đường dẫn 2: 1 2 8 10 11

+ Đường dẫn 3: 1 2 3 8 9 11

+ Đường dẫn 4: 1 2 3 4 7 2 …

+ Đường dẫn 5: 1 2 3 4 5 7 2 …

+ Đường dẫn 6: 1 2 3 4 5 6 7 2 …

Bước 4: Thiết kế các trường hợp kiểm thử cho mỗi đường dẫn độc lập

trong tập cơ sở đã chọn.

1

2

3

8

9 10 5

6

Hình 1.3 – Ví dụ minh họa phát sinh các trường hợp kiểm thử theo đường dẫn cơ sở

4

7 11

Page 22: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

22

Trường hợp kiểm thử đường dẫn 1

Đầu vào: Values = {3, 5, 11, -999}, min = 0, max = 100

Đầu ra mong muốn: Average = (3 + 5 + 11) / 3

Mục đích: Để kiểm thử việc tính giá trị trung bình chính xác

Lưu ý: Đường dẫn 1 không thể kiểm thử một mình, mà phải được kiểm

thử như là một phần của các kiểm thử đường dẫn 4, 5 và 6.

Trường hợp kiểm thử đường dẫn 2

Đầu vào: Values = {-999}, min = 0, max = 0

Đầu ra mong muốn: Average = -999

Mục đích: Để tạo ra Average = -999

Trường hợp kiểm thử đường dẫn 3

Đầu vào: Values = {2, 6, 7, …, 120} (101 số), min = 0, max = 100

Đầu ra mong muốn: Trung bình của 100 số đầu tiên

Mục đích: Chỉ tính trung bình cho 100 số hợp lệ đầu tiên

Trường hợp kiểm thử đường dẫn 4

Đầu vào: Values = {67, -2, 12, 23, -999}, min = 0, max = 100

Đầu ra mong muốn: Average = (67 + 12 + 23) / 3

Mục đích: Kiểm thử biên dưới (Values[i] > min, i < 100)

Trường hợp kiểm thử đường dẫn 5

Đầu vào: Values = {7, 32, 102, 23, 68, 2, -999}, min = 0, max = 100

Đầu ra mong muốn: Average = (7 + 32 + 23 + 68 + 2) / 5

Mục đích: Kiểm thử biên trên (Values[i] < max, i < 100)

Trường hợp kiểm thử đường dẫn 6

Đầu vào: Values = {3, 4, 12, 15, 16, 2, -999}, min = 0, max = 100

Đầu ra mong muốn: Average = (3 + 4 + 12 + 15 + 16 + 2) / 6

Mục đích: Việc tính giá trị trung bình là đúng

Phương pháp đường dẫn cơ sở tập trung trên “giá trị đại diện” của mỗi

đường dẫn độc lập. Cần có các trường hợp kiểm thử bổ sung (ngoài các

Page 23: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

23

trường hợp kiểm thử đường dẫn cơ sở), nhất là để thực hiện các điều kiện

biên.

1.3.2.2. Kiểm thử cấu trúc điều khiển

Phương pháp kiểm thử đường dẫn cơ sở là phương pháp kiểm thử đơn

giản và hiệu quả nhưng chưa đủ. Chúng ta sẽ xem xét các biến thể trên kiểm

thử cấu trúc điều khiển mà phủ kiểm thử mở rộng và hoàn thiện chất lượng

của phương pháp kiểm thử hộp trắng.

a) Kiểm thử điều kiện Kiểm thử điều kiện là phương pháp thiết kế trường hợp kiểm thử thực thi

các điều kiện logic trong module chương trình. Mục đích là để xác định các

lỗi điều kiện và cả các lỗi khác trong chương trình. Một số phương pháp kiểm

thử điều kiện như sau:

Kiểm thử nhánh (Branch Testing): Là phương pháp kiểm thử điều

kiện đơn giản nhất. Thiết kế các trường hợp kiểm thử sao cho với

mỗi điều kiện rẽ nhánh phức hợp C, các nhánh true và false của C

và mỗi điều kiện đơn giản trong C cần phải được thực thi ít nhất một

lần.

Kiểm thử miền (Domain Testing): Cần 3 hoặc 4 trường hợp kiểm

thử cho biểu thức quan hệ. Với một biểu thức quan hệ có dạng E1

<op> E2, cần có 3 trường hợp kiểm thử được thiết kế cho E1 == E2,

E1 > E2, E1 < E2.

b) Kiểm thử luồng dữ liệu

Phương pháp kiểm thử luồng dữ liệu lựa chọn các đường dẫn kiểm thử

của chương trình dựa vào vị trí khai báo và sử dụng các biến trong chương

trình. Với kiểm thử luồng dữ liệu, mỗi câu lệnh trong chương trình được gán

số hiệu lệnh duy nhất và mỗi hàm không thay đổi tham số của nó và biến toàn

cục. Cho một lệnh với S là số hiệu câu lệnh. Ta định nghĩa:

DEF(S) = là tập các biến được khai báo trong S

Page 24: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

24

USE(S) = là tập các biến được sử dụng trong S

Một chiến lược kiểm thử luồng dữ liệu cơ bản là chiến lược mà mỗi

chuỗi DU được phủ ít nhất một lần. Chiến lược này được gọi là chiến lược

kiểm thử DU. Kiểm thử DU không đảm bảo phủ hết tất cả các nhánh của một

chương trình; tuy nhiên, một nhánh không đảm bảo được phủ bởi kiểm thử

DU chỉ trong rất ít tình huống như cấu trúc if – then – else mà trong đó phần

then không có một khai báo biến nào và có dạng khuyết (không tồn tại phần

else). Trong tình huống đó, nhánh else của lệnh if là không cần thiết phải phủ

bằng kiểm thử DU.

c) Kiểm thử vòng lặp Là phương pháp tập trung vào tính hợp lệ của các cấu trúc vòng lặp. Có

4 kiểu vòng lặp khác nhau được mô tả bằng sơ đồ khối như sau:

Vòng lặp đơn Vòng lặp nối tiếp Vòng lồng nhau Vòng lặp phi cấu trúc

Hình 1.4 –Các kiểu vòng lặp

Page 25: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

25

Các bước cần kiểm tra cho vòng lặp đơn giản + Bỏ qua toàn bộ vòng lặp;

+ Chỉ qua một vòng lặp;

+ Qua hai vòng lặp;

+ Qua vòng lặp m với (m < n);

+ Qua vòng lặp (n - 1), n, (n + 1).

Trong đó n là số lần lặp tối đa của vòng lặp.

Các bước cần kiểm tra cho vòng lặp dạng lồng nhau

+ Khởi đầu với vòng lặp nằm bên trong nhất. Thiết lập các tham số

lặp cho các vòng lặp bên ngoài về giá trị nhỏ nhất.

+ Kiểm tra với tham số min + 1, 1 giá trị tiêu biểu, max - 1 và max

cho vòng lặp bên trong nhất trong khi các tham số lặp của các

vòng lặp bên ngoài là nhỏ nhất.

+ Tiếp tục tương tự với các vòng lặp liền ngoài tiếp theo cho đến khi

tất cả vòng lặp bên ngoài được kiểm tra.

Các bước cần kiểm tra cho vòng lặp nối tiếp

Nếu các vòng lặp là độc lập với nhau thì kiểm tra như trường các vòng

lặp dạng đơn giản, nếu không thì kiểm tra như trường hợp các vòng lặp lồng

nhau.

Các bước cần kiểm tra cho vòng lặp phi cấu trúc Nếu gặp các lớp vòng lặp này chúng ta sẽ không kiểm thử, mà sẽ thiết

kế lại tương ứng với sử dụng việc xây dựng chương trình có cấu trúc.

Page 26: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

26

1.4. Kết luận

Trong chương 1 đã nêu tổng quan về các cấp độ và loại kiểm thử phần

mềm cơ bản. Kiểm thử hộp trắng xem xét chương trình ở mức độ chi tiết và

phù hợp khi kiểm tra các môđun nhỏ. Tuy nhiên, kiểm thử hộp trắng có thể

không đầy đủ vì kiểm thử hết các lệnh không chứng tỏ là chúng ta đã kiểm

thử hết các trường hợp có thể. Ngoài ra chúng ta không thể kiểm thử hết các

đường đi đối với các vòng lặp lớn.

Kiểm thử hộp đen chú trọng vào việc kiểm tra các quan hệ vào ra và

những chức năng giao diện bên ngoài, nó thích hợp hơn cho các hệ thống

phần mềm lớn hay các thành phần quan trọng của chúng. Nhưng chỉ sử dụng

kiểm thử hộp đen là chưa đủ. Bởi vì, kiểm thử chức năng chỉ dựa trên đặc tả

của môđun nên không thể kiểm thử được các trường hợp không được khai

báo trong đặc tả. Ngoài ra, do không phân tích mã nguồn nên không thể biết

được môđun nào của chương trình đã hay chưa được kiểm thử, khi đó phải

kiểm thử lại hay bỏ qua những lỗi tiềm ẩn trong gói phần mềm.

Phương pháp kiểm thử hộp trắng và kiểm thử hộp đen là hai phương

pháp cơ bản có vai trò rất quan trọng trong quá trình phát triển phần mềm, nếu

chúng ta biết kết hợp chúng để bổ sung khiếm khuyết lẫn nhau.

Page 27: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

27

CHƯƠNG 2 – KỸ THUẬT KIỂM THỬ ĐỘT BIẾN Với mục đích phát hiện lỗi, kiểm thử phần mềm thường phải trải qua

các bước: tạo dữ liệu thử, thực thi phần mềm trên dữ liệu thử và quan sát

kết quả nhận được. Trong các bước này, bước tạo dữ liệu đóng vai trò

quan trọng nhất, bởi vì chúng ta không thể tạo ra mọi dữ liệu từ miền vào

của chương trình, mà chúng ta chỉ có thể tạo ra các dữ liệu thử có khả năng

phát hiện lỗi cao nhất. Vấn đề đặt ra là làm sao để đánh giá được khả năng

phát hiện lỗi của một bộ dữ liệu thử? Chính kỹ thuật kiểm thử đột biến là

câu trả lời. Kỹ thuật này cho phép đánh giá chất lượng (khả năng phát hiện

lỗi) của một bộ dữ liệu thử.

2.1. Một số khái niệm

2.1.1. Kiểm thử đột biến

Kiểm thử đột biến được đề xuất đầu tiên vào năm 1979 bởi DeMillo và

đồng nghiệp [13]. Nó cung cấp một phương tiện để đánh giá và cải tiến chất

lượng dữ liệu thử cho chương trình được kiểm thử (PUT).

Kiểm thử đột biến tập trung vào việc đánh giá khả năng phát hiện lỗi

của dữ liệu dùng để kiểm thử. Kiểm thử đột biến được dùng kết hợp với

các kỹ thuật kiểm thử thông thường nhưng không thể được dùng để thay

thế cho các kỹ thuật kiểm thử thông thường đó.

2.1.2. Đột biến

Kiểm thử đột biến bao gồm việc tạo ra các phiên bản lỗi của chương

trình gốc được kiểm thử nhờ vào các toán tử đột biến. Các phiên bản lỗi đó

được gọi là các đột biến (mutant).

Khi tiến hành thực thi kiểm thử lần lượt chương trình gốc P và đột biến

P’ của P với một dữ liệu kiểm thử T, sẽ có hai kịch bản khác nhau có thể xảy

ra:

Page 28: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

28

- Một là, đột biến P’ được gọi là bị diệt bởi dữ liệu kiểm thử T.

- Hai là, chương trình gốc P và đột biến P’ cho ra kết quả hoàn toàn

giống nhau, đột biến P’ được cho là còn sống.

Các đột biến tương đương (equivalent mutant) là các đột biến của

chương trình gốc nhưng hoạt động hoàn toàn giống với chương trình gốc và

cho ra kết quả giống với chương trình gốc trong mọi trường hợp kiểm thử.

(Đột biến P’ là đột biến tương đương của PUT vì dữ liệu thử sẽ không

thể phát hiện ra lỗi trong chương trình P do giá trị của z luôn luôn bằng 4)

Tỷ số MS = 100 * D/(N - E) được gọi là tỷ lệ đột biến (Mutation

Score - MS). Trong đó, D là đột biến đã bị diệt; N là tổng số các đột biến;

E là số đột biến tương đương. Tỷ lệ đột biến cho phép đánh giá chất lượng

bộ dữ liệu thử.

Ví dụ: Toán tử đột biến quan hệ sẽ tạo ra một số các đột biến trong đó

mỗi đột biến có sự xuất hiện của một toán tử quan hệ được thay thế bởi toán

tử quan hệ khác. Hình 2.1 là một ví dụ về hai đột biến của PUT được tạo ra

bởi toán tử đột biến toán tử quan hệ.

--- --- if (x = = 2 && y = = 2) z = x + y; ---

--- --- if (x = = 2 && y = = 2) z = x * y; ---

Chương trình PUT gốc Đột biến P’

Hình 2.1 – Ví dụ về đột biến tương đương

Page 29: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

29

Dựa trên tiêu chuẩn chất lượng đột biến, các đột biến được thực hiện với

một bộ dữ liệu thử để xác định có bao nhiêu đột biến thất bại (tức là cung cấp

đầu ra không đúng cho đầu vào kiểm thử đó). Thất bại càng nhiều, càng lớn

thì bộ dữ liệu thử càng chất lượng. Mục đích của kiểm thử viên là tạo ra dữ

liệu thử mới để cải tiến chất lượng của các dữ liệu thử hiện có. Một kết quả

khá hữu ích của phương pháp này là việc cải tiến chất lượng của dữ liệu thử

sẽ cải thiện sự tin tưởng của kiểm thử viên vào tính đúng đắn của PUT. Có thể

nói rằng, sự tin tưởng của kiểm thử viên vào chương trình càng nhiều, thì

càng nhiều kiểm thử tốt hơn sẽ được sử dụng.

Ngoài ra, kiểm thử đột biến là phương pháp để cải tiến chất lượng dữ

liệu thử cung cấp nhiều hỗ trợ quan trọng. Nếu một lỗi làm cho đột biến của

PUT thất bại khi thực hiện với một số dữ liệu thử và PUT thành công, thì

chính PUT không thể chứa lỗi đó (tức là PUT là phiên bản đúng của chương

trình đối với lỗi đó). Kiểm thử mọi đột biến có thể có giúp kiểm thử biết rằng

Chương trình PUT gốc

int max (int x, int y) { int mx = x ; if (x < y) mx = x; else mx = y; return mx; }

int max (int x, int y) { int mx = x ; if (x > y) mx = x; else mx = y; return mx; }

Đột biến P’’

int max (int x, int y) { int mx = x ; if (x >= y) mx = x; else mx = y; return mx; }

Đột biến P’ (ĐBTĐ)

Hình 2.2 – Ví dụ về đột biến

Page 30: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

30

không có các lỗi đó xuất hiện trong PUT. Phát triển dữ liệu thử theo cách này

cho phép kiểm thử viên tăng sự tin tưởng của họ vào tính đúng đắn của PUT.

2.1.3. Toán tử đột biến

Toán tử đột biến (mutation operator) là một luật được áp dụng vào

chương trình gốc để tạo ra các đột biến. Các toán tử đột biến được xác định

bởi ngôn ngữ của chương trình được kiểm thử và hệ thống đột biến được

dùng để kiểm thử.

2.2. Cơ sở của kiểm thử đột biến

Kiểm thử đột biến là một kỹ thuật kiểm thử hộp trắng hay kiểm thử

cấu trúc, được xây dựng dựa vào hai g iả thuyết cơ bản [13]:

- Giả thuyết “lập trình viên giỏi” (competent programmer)

- Giả thuyết “ hiệu ứng liên kết” (coupling effect).

Giả thuyết “lập trình viên giỏi” giả thiết rằng lập trình viên chỉ phạm những

lỗi đơn giản do sơ suất. Giả thuyết “hiệu ứng liên kết” giả thuyết rằng, nếu

dữ liệu thử phát hiện được các lỗi đơn giản thì dữ liệu đó cũng cho phép phát

hiện các lỗi phức tạp.

2.3. Toán tử đột biến

Phần lớn các nghiên cứu về kiểm thử đột biến chủ yếu dựa trên các

chương trình Fortran do tính sẵn có và dễ sử dụng của hệ thống đột biến

Mothra [14]. Mothra (hệ thống đột biến cho Fortran) sử dụng 22 toán tử đột

biến để tạo ra các đột biến cho 77 chương trình Fortran [5], được biểu diễn

bảng 2.1. Các toán tử này đã được phát triển và chọn lọc cách đây hơn 20 năm,

ngày nay vẫn còn nhiều toán tử được sử dụng dưới một số hình thức chẳng

hạn như sử dụng toán tử thay thế toán tử logic và một số toán tử tương tự như

các toán tử LCR và SDL của Mothra.

Page 31: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

31

Toán tử đột biến Mô Tả

AAR Thay thế tham chiếu mảng cho tham chiếu mảng

ABS Thêm giá trị tuyệt đối

ACR Thay thế tham chiếu mảng cho hằng số

AOR Thay thế toán tử số học

ASR Thay thế tham chiếu mảng cho biến vô hướng

CAR Thay thế hằng số cho tham chiếu mảng

CNR Thay thế tên mảng tương đương

CRP Thay thế hằng số

CSR Thay thế hằng cho biến vô hướng

DER Thay thế kết thúc câu lệnh DO

DSA Thay đổi câu lệnh DATA

GLR Thay thế nhãn GOTO

LCR Thay thế kết nối logic

ROR Thay thế toán tử logic

RSR Thay thế câu lệnh RETURN

SAN Phân tích câu lệnh

SAR Thay thế biến vô hướng cho tham chiếu mảng

SCR Thay thế vô hướng cho hằng

SDL Xóa câu lệnh

SRC Thay thế hằng số nguồn

SVR Thay thế biến vô hướng

UOI Thêm toán tử nhị nguyên

Bảng 2.1- 22 toán tử đột biến chuẩn được sử dụng trong Mothra

Các toán tử đột biến được thiết kế để làm lộ ra các lỗi trong PUT khi

thực hiện. Ví dụ, toán tử thay thế toán tử quan hệ ROR. Đột biến tạo ra từ toán

tử này sẽ giống với PUT ngoại trừ một toán tử quan hệ được thay thế bằng

Page 32: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

32

một toán tử quan hệ khác, chẳng hạn như câu lệnh x < y sẽ được thay thế

bằng x y với mục đích để kiểm tra xem trong trường hợp < này, toán tử

quan hệ có sử dụng đúng hay không.

Nếu PUT thực sự là đúng thì nó có thể tìm thấy các dữ liệu thử tạo ra các

kết quả đầu ra không đúng cho tất cả các phiên bản toán tử quan hệ không

tương đương, do đó loại bỏ những đột biến đó để được phiên bản đúng của

chương trình. Tuy nhiên, trước khi kiểm thử, chúng ta không biết được liệu

PUT là đúng hay không. Thay vào đó, PUT phải được giả sử là đúng, trừ khi

một dữ liệu thử có thể chứng minh khác. Trong tình huống đó, tỷ lệ các đột

biến không tương đương bị diệt bởi bộ dữ liệu thử là thước đo cho chất lượng

của bộ dữ liệu thử và thước đo của sự tin tưởng vào tính đúng đắn của PUT.

Gần đây, nghiên cứu về kiểm thử đột biến đã tập trung phát triển các toán

tử đột biến mới, đặc biệt cho các môi trường hướng đối tượng như C, C++,

C_Sharp,… Nghiên cứu này tập trung kiểm thử các chương trình đơn giản,

hầu hết các toán tử đột biến truyền thống vẫn còn hiệu quả.

2.4. Quy trình kiểm thử đột biến Kiểm thử đột biến là một quy trình được lặp đi lặp lại để cải tiến dữ liệu

thử đối với một chương trình và được chia thành các bước cơ bản [13] sau:

Bước 1: Sản sinh đột biến (dùng công cụ sản sinh tự động hoặc

sản sinh thủ công) từ chương trình gốc.

Bước 2: Sản sinh các dữ liệu kiểm thử.

Bước 3: Thực hiện từng dữ liệu kiểm thử với chương trình gốc.

Bước 3.1: Nếu kết quả không đúng, phải chỉnh sửa l ạ i

chương trình và kiểm thử lại.

Bước 3.2: Nếu kết quả đúng, thực hiện bước tiếp theo.

Bước 4: Thực hiện từng dữ liệu kiểm thử với từng đột biến còn sống.

Page 33: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

33

Bước 4.1: Nếu kết quả ra của đột biến khác với chương

trình gốc, chương trình đột biến được xem là không

đúng và bị diệt. Hoàn thành kiểm thử.

Bước 4.2: Nếu đột biến sống sót được (qua kiểm thử): phân

tích các đột biến còn sống. Có hai khả năng xảy ra:

- Hoặc các đột biến là đột biến tương đương: không thể

bị diệt.

- Hoặc có thể diệt các đột biến được nhưng các dữ liệu

kiểm thử không đủ mạnh để diệt đột biến. Do đó

phải tạo ra các dữ liệu kiểm thử khác và lặp lại bước 1.

Từ các bước của thuật toán đã được tóm tắt thành sơ đồ [7] như hình sau:

( Lưu ý: Trong hình trên các bước biểu diễn trong hộp liền nét được thực

hiện tự động. Còn các bước biểu diễn trong hộp nét đứt được thực hiện bằng

tay)

T F

F T

Tạo các đột biến

Tất cả các đột biến bị diệt?

Đầu vào chương trình

P Đầu vào

test cases, T

Chạy T trên P

P(T) đúng ? Sửa P

Chạy test cases trên

từng đột biến còn sống

Phân tích và đánh dấu các đột biến tương đương

Kết thúc

Cập nhật T

Các toán tử đột biến

Hình 2.3 – Quy trình kiểm thử đột biến

Page 34: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

34

2.5. Hạn chế của kiểm thử đột biến

Mặc dù được xem là một kỹ thuật kiểm thử đơn vị mạnh, tuy nhiên kiểm

thử đột biến gặp phải một số vấn đề khó khăn trong ngành công nghiệp phần

mềm. Các vần đề này có thể được phân loại thành hai nhóm: chi phí tính toán

– tốn rất nhiều thời gian và công sức để thực hiện kiểm thử đột biến, và tự

động hóa – để giảm công sức của kiểm thử viên.

Kiểm thử đột biến thì tốn kém vì số lượng lớn các chương trình đột biến

cần được tạo ra và thực hiện. Do đó, các nhà nghiên cứu tiến hành nghiên cứu

bằng thực nghiệm với kiểm thử đột biến thường chỉ sử dụng chương trình nhỏ

để hạn chế số lượng đột biến được tạo ra. Trong khi đó, hạn chế này là chấp

nhận được ở các trường (đại học, học viện, …), nó không dành cho công

nghiệp thường mong muốn được kiểm thử các chương trình lớn hơn, phức tạp

hơn. Vì tính phức tạp gia tăng, do thời gian thực hiện cho một chương trình và

các phiên bản đột biến của nó, do đó làm tăng toàn bộ thời gian chạy cho

kiểm thử đột biến.

Các vấn đề trầm trọng hơn nữa là rất khó khăn trong việc tự động hoá

toàn bộ quá trình kiểm thử đột biến. Mặc dù, một phần lớn quá trình có khả

năng tự động được dễ dàng, các công việc như xác định các đột biến tương

đương và kiểm tra tính đúng đắn của kết quả đầu ra thường được thực hiện

một cách thủ công. Mặc dù, việc thực hiện những công việc này bằng thủ

công cho phép chương trình được xem xét kỹ lưỡng hơn, nhưng dễ bị lỗi. Vì

vậy, làm tăng thời gian kiểm thử ở một giai đoạn trong vòng đời phát triển

phần mềm, khi thời gian kiểm thử thường là rất quan trọng.

Page 35: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

35

2.6. Kết luận

Kiểm thử đột biến được giới thiệu để cung cấp một phương tiện để

đánh giá và cải tiến chất lượng các bộ dữ liệu thử. Nó được xây dựng dựa trên

hai giả thuyết cơ bản: giả thuyết lập trình viên giỏi, hiệu ứng liên kết. Do đó,

kiểm thử đột biến chỉ tập trung vào các lỗi đơn giản của chương trình (ví dụ:

sự khác biệt một từ đơn hoặc thay thế tên biến sai).

Tuy nhiên, chi phí để thực hiện kiểm thử đột biến khá cao vì một số

lượng lớn các chương trình đột biến cần phải được thực hiện bởi ít nhất một

dữ liệu thử và khó khăn để tự động hóa vì các dữ liệu thử mạnh cần phải được

tạo ra, đột biến tương đương cần được loại bỏ, và kết quả đầu ra của PUT cần

được kiểm thử tính đúng đắn. Vì vậy, chương 3 sẽ đề cập một số phương

pháp cải tiến kỹ thuật kiểm thử đột biến để khắc phục các vần đề trên.

Page 36: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

36

CHƯƠNG 3 - MỘT SỐ CẢI TIẾN KỸ THUẬT

KIỂM THỬ ĐỘT BIẾN

3.1. Giảm chi phí tính toán

Các hệ thống kiểm thử đột biến truyền thống tạo ra số lượng lớn các

chương trình đột biến. Ví dụ, có 385 đột biến được tạo ra cho thủ tục tìm

nghiệm theo phương pháp NiuTơn gồm 18 dòng lệnh. Phân tích cho thấy rằng

số lượng các đột biến tạo ra xấp xỉ bằng tích của số các tham chiếu dữ liệu và

số các đối tượng dữ liệu. Do đó, số lượng đột biến sẽ làm tăng tính phức tạp

của chương trình. Điều này làm tăng chi phí thực thi do mỗi đột biến phải

thực thi với ít nhất một trường hợp kiểm thử. Như vậy, chi phí là chấp nhận

được cho nghiên cứu ở các trường (đại học, học viện, …) với các ràng buộc

về thời gian có thể linh hoạt, nhưng trong công nghiệp sự lãng phí này là

không thể.

Mặt khác, các hệ thống truyền thống phải thông dịch các chương trình

đột biến nên thực tế thời gian chạy sẽ lâu hơn. Điều này gây ra nhiều bất tiện,

nó làm cho các hệ thống thực hiện chậm và rất khó để mô phỏng môi trường

hoạt động. Để khắc phục những chi phí liên quan với đột biến, các nghiên cứu

hầu hết đã tập trung vào một số phương pháp: làm ít hơn, làm nhanh hơn mà

không làm giảm khả năng phát hiện lỗi.

3.1.1. Phương pháp làm ít hơn (A “do fewer” approach)

Muốn giảm chi phí kiểm thử đột biến thì phải giảm số lượng các

chương trình đột biến thực thi. Để làm được điều này, chúng ta sử dụng một

trong số các phương pháp: Lấy mẫu đột biến (Mutant Sampling), đột biến

ràng buộc (Constrained Mutation), và N - đột biến lựa chọn (N - Selective

Mutation), mà không làm giảm các khả năng tìm kiếm lỗi.

Page 37: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

37

3.1.1.1. Lấy mẫu đột biến (Mutant Sampling)

Lấy mẫu đột biến là một phương pháp đơn giản lựa chọn ngẫu nhiên một

tập con nhỏ các đột biến từ tập toàn bộ các đột biến. Ý tưởng này được đề

xuất đầu tiên bởi Acree và Budd [19, 7]. Trong phương pháp lấy mẫu đột biến,

đầu tiên tất cả các đột biến có thể có được tạo ra như trong kiểm thử đột biến

truyền thống. Sau đó, x% của những đột biến này được lựa chọn ngẫu nhiên

để phân tích đột biến và các đột biến còn lại được bỏ đi.

Đã có nhiều nghiên cứu thực nghiệm về phương pháp này. Vấn đề chính

là về việc chọn tỷ lệ lựa chọn ngẫu nhiên (x) còn được gọi là tỷ lệ lấy mẫu x%.

Các nghiên cứu của Acree và Budd đề nghị rằng tỷ lệ lấy mẫu 10% có thể xác

định trên 99% tất cả đột biến không tương đương trong khi cung cấp tiết kiệm

chi phí đáng kể. Wong [23] tiếp tục nghiên cứu các lợi ích về chi phí của lấy

mẫu đột biến bằng cách thay đổi tỷ lệ lấy mẫu từ 10% đến 40%. Ngay cả ở

mức thấp nhất, các kết quả của Wong cho thấy lẫy mẫu đột biến là một chiến

lược cắt giảm chi phí hiệu quả cung cấp các tập dữ liệu thử có khả năng xác

định ít nhất 96,14% tất cả các đột biến nhưng chỉ phải kiểm tra 9,8% đột biến.

Một điểm nổi bật hơn nữa trong [23] là đối với các tập dữ liệu thử chất

lượng dựa vào lấy mẫu, một tỷ lệ lấy mẫu cao không có nghĩa là sẽ tạo ra tỷ lệ

đột biến cao hơn tỷ lệ lấy mẫu thấp. Ban đầu, điều này có vẻ không hợp lý.

Một trong những mong chờ đó là các dữ liệu thử được tạo ra từ tỷ lệ lấy mẫu

lớn thì sẽ chất lượng hơn trong việc xác định đột biến còn lại so với từ tỷ lệ

lấy mẫu nhỏ. Tuy nhiên, các kết quả của Wong cho thấy; đối với hàm

TEXTFMT, tỷ lệ lấy mẫu 25% đạt được tỷ lệ đột biến 98,92% so với 99,01%

cho tỷ lệ lấy mẫu 10%. Các kết quả này cho thấy rằng số lượng đột biến được

kiểm tra không phải là chỉ báo rõ ràng về tỷ lệ đột biến (ngoại trừ kiểm tra tất

cả các đột biến), nhưng thay vào đó, dấu hiệu là các dữ liệu thử có khả năng

xác định đột biến nhiều hơn những dấu hiệu khác. Trong trường hợp này, việc

Page 38: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

38

lựa chọn các đột biến cho kiểm thử có ảnh hưởng đến các dữ liệu thử được

tạo ra và tỷ lệ đột biến không? Các đột biến có thể được phân loại dựa trên tập các dữ liệu thử diệt

chúng. Đột biến mạnh là rất khó phát hiện, đòi hỏi dữ liệu thử đặc biệt để diệt

nó. Ngược lại, đột biến yếu có thể dễ dàng phát hiện bởi bất kỳ dữ liệu thử

nào. Do đó, cần có các tập dữ liệu thử khác nhau để diệt chúng. Các tập dữ

liệu thử này nói chung là không được biết trước khi (và thường sau khi) kiểm

thử. Tuy nhiên, tập dữ liệu thử đó phải được tạo ra để diệt đột biến. Xem xét

tình huống, chọn W là đột biến yếu và chọn S là đột biến mạnh, W sẽ có tập

dữ liệu thử để diệt nó - TW và S chưa có dữ liệu thử diệt được nó - TS. Có ba

tình huống có thể xảy ra được minh họa ở hình 3.1:

1. TS TW. Tập dữ liệu thử diệt đột biến mạnh hơn là tập con của tập dữ

liệu thử diệt các đột biến yếu hơn– hình 3.3(a). 2. (TS TW) (TS TW ). TS không phải là tập con của TW nhưng

hai tập giao nhau – hình3.3 (b). 3. TS TW = . Hai tập dữ liệu thử rời nhau – hình 3.3 (c). Nếu tình huống 1 xảy ra, thì chọn đột biến mạnh hơn trong quá trình lấy

mẫu sẽ đảm bảo dữ liệu thử được tạo ra diệt đột biến yếu hơn- tức là dữ liệu

thử được tạo ra trong cả TS và TW. Tuy nhiên, nếu đột biến yếu hơn được lựa

chọn, thì cơ hội dữ liệu thử được tạo ra diệt được đột biến mạnh hơn sẽ bị

giảm - tức là dữ liệu thử ở trong TW nhưng có thể hoặc không thể ở trong TS.

TW Ts

(a) (b) (c)

Ts TW TW Ts

Hình 3.1- Ba kịch bản có thể có cho quan hệ giữa các tập dữ liệu thử diệt đột biến yếu và mạnh

Page 39: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

39

Nếu tình huống 3 xảy ra, thì việc lựa chọn đột biến trong lấy mẫu sẽ chỉ tạo ra

dữ liệu thử có khả năng diệt đột biến đặc biệt. Tình huống 2 là sự kết hợp của

hai loại. Lựa chọn đột biến mạnh hơn sẽ tạo ra dữ liệu thử có thể hoặc không

thể diệt được đột biến yếu hơn và ngược lại. Nói chung, kích thước của TW có

thể sẽ lớn hơn kích thước của TS, dữ liệu thử từ TW giao nhau với TS có thể sẽ

nhỏ hơn so với dữ liệu thử từ TS giao nhau với TW. Ví dụ, cho một dữ liệu thử

x là giao với hai tập |TW| = 20 và |TS| = 5. Nếu dữ liệu thử được tạo ra để diệt

đột biến yếu hơn (nghĩa là dữ liệu thử thuộc TW) thì tỷ lệ của x là 1/20. Nếu

dữ liệu thử được tạo ra để diệt đột biến mạnh hơn (nghĩa là dữ liệu thử thuộc

TS) thì tỷ lệ của x là 1/5.

Ba tình huống trên cho thấy rằng, đột biến được chọn trong quá trình lấy

mẫu sẽ ảnh hưởng đến các dữ liệu thử được tạo ra. Hơn nữa, chúng cho thấy

rằng lựa chọn các đột biến mạnh hơn cải thiện cơ hội diệt các đột biến yếu

hơn và vì vậy kích thước của lấy mẫu đột biến là không quan trọng, nhưng đó

vẫn là sự lựa chọn đột biến. Lấy mẫu từ đột biến mạnh hơn với tỷ lệ thấp hơn

có thể tạo ra tỷ lệ đột biến cao hơn lấy mẫu từ đột biến yếu hơn với tỷ lệ cao

hơn.

3.1.1.2. Đột biến ràng buộc (Constrained Mutation)

Giảm số lượng các đột biến cũng có thể đạt được bằng cách giảm số

lượng các toán tử đột biến được áp dụng. Đây là ý tưởng cơ bản làm nền tảng

cho đột biến ràng buộc được đề xuất bởi Mathur [4], bằng cách lựa chọn một

tập con các toán tử đột biến tạo ra một tập con tất cả các đột biến có thể có mà

không mất tính hiệu quả của kiểm thử đột biến.

Các kiểm tra dựa trên kinh nghiệm thu được các kết quả khá thuyết phục

khi sử dụng đột biến ràng buộc. Nhìn chung, các kết quả của Wong cho thấy

rằng các tỷ lệ đột biến trung bình từ các tập dữ liệu thử chất lượng dựa trên

ràng buộc bằng cách sử dụng chỉ hai toán tử ABS và ROR đạt trên 95% trong

số bốn chương trình kiểm tra và giảm số lượng đột biến từ 14.39% đến

Page 40: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

40

19.94% của tổng số đột biến [22]. Trong khi đó, tiết kiệm chi phí không lớn

bằng tỷ lệ lấy mẫu 10% (thực hiện từ 9,8% cho đến 10,98% tổng số đột biến),

tỷ lệ đột biến trung bình là xấp xỉ bằng 97,56% với tỷ lệ lấy mẫu 10% và

97,18% với đột biến ràng buộc ABS / ROR. Các nghiên cứu của Mathur và

đồng nghiệp cũng cho ra kết quả tương tự, kết quả này thu được 7 trong số 10

thí nghiệm, đột biến ràng buộc ABS / ROR đạt hiệu quả ít nhất bằng tỷ lệ lấy

mẫu 10% trong việc phát hiện có lỗi. Hơn nữa, còn lại 3 thí nghiệm đều được

thực hiện trên cùng một chương trình không được sử dụng trong 7 thí nghiệm

khác.

3.1.1.3. N - đột biến lựa chọn (N - Selective Mutation)

Offutt và đồng nghiệp [9, 10] mở rộng nghiên cứu đột biến ràng buộc

của Mathur bằng cách sử dụng tất cả các toán tử đột biến trừ đi hai toán tử tạo

ra hầu hết các đột biến (được gọi là phương pháp 2 - đột biến lựa chọn). Giả

thuyết phương pháp N – đột biến lựa chọn, trong đó N là số toán tử đột biến

tạo ra nhiều đột biến nhất được loại bỏ. Ban đầu, 28 chương trình đã được

kiểm tra để xác định tỷ lệ đột biến được tạo ra bởi mỗi toán tử đột biến, như

thể hiện trong hình 3.2. Dựa trên đó, họ đề xuất loại bỏ hai toán tử SVR và

ASR cho 2 - đột biến lựa chọn, cùng với SCR và CSR cho 4 - đột biến lựa

chọn, kết hợp với ACR và SRC cho 6 - đột biến lựa chọn.

Đối với mỗi phương pháp lựa chọn, bộ tạo dữ liệu thử tự động Godzilla

được dùng để tạo ra dữ liệu thử chất lượng dựa trên đột biến lựa chọn. Sau đó,

các tập dữ liệu thử này được thực hiện với tất cả các đột biến để xác định hiệu

quả của chúng đối với tất cả các đột biến - tức là tỷ lệ đột biến của chúng. Các

kết quả mang lại nhiều hứa hẹn. Phương pháp 2 - đột biến lựa chọn cho kết

quả tỷ lệ đột biến 99,99% và tiết kiệm 23,98% số lượng đột biến không phải

kiểm tra. Đối với 4 - đột biến lựa chọn thu được những số liệu tương ứng này

là 99,84% và 41,36%, và 6 - đột biến lựa chọn là 99,71% và 60,56%.

Page 41: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

41

Hình 3.2 - Phân bố đột biến bằng toán tử đột biến cho Mothra Như vậy, các tỷ lệ đột biến cao thu được từ các tập dữ liệu thử chất

lượng dựa trên lựa chọn cho thấy rằng các dữ liệu thử được thiết kế để diệt

đột biến từ các toán tử đột biến tạo ra ít đột biến cũng có khả năng diệt các đột

biến từ các toán tử đột biến tạo ra nhiều đột biến.

Offutt và đồng nghiệp tiếp tục nghiên cứu để loại bỏ thêm các đột biến

nhằm tiết kiệm thêm chi phí mà không ảnh hưởng nhiều đến hiệu quả của các

tập dữ liệu thử được tạo ra [10]. 22 toán tử đột biến chuẩn được sử dụng

trong Mothra được chia thành ba nhóm:

Các toán tử thay thế toán hạng - thay thế từng toán hạng của

chương trình bằng toán hạng hợp lý khác.

Các toán tử thay đổi biểu thức của chương trình - thay thế các toán

tử của chương trình và thêm các toán tử mới.

Các toán tử thay đổi câu lệnh - thay đổi các câu lệnh hoàn toàn.

Offutt và đồng nghiệp thực hiện ba thí nghiệm để tạo ra dữ liệu thử

chất lượng, loại trừ một nhóm các toán tử đột biến trong từng thí nghiệm. Khi

so sánh với tất cả các đột biến, kết quả thu được 5 toán tử biểu thức (ABS,

AOR, LCR, ROR, UOI) là hữu ích nhất. Các thí nghiệm đã chứng minh rằng

các tập dữ liệu thử chất lượng tạo ra từ 5 toán tử này đạt tỷ lệ đột biến trung

bình là 99,51% và tiết kiệm 77,56% số lượng các đột biến phải kiểm tra. Các

kết quả này tương tự như các tỷ lệ đột biến trung bình thu được bằng cách sử

Toán tử đột biến

Tỷ lệ

đột

biế

n tiế

t kiệ

m đ

ược

Page 42: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

42

dụng lấy mẫu đột biến với tỷ lệ lấy mẫu 25% (tiết kiệm 75%): từ 98,27% đến

99,01%.

Tuy nhiên, không giống như lấy mẫu đột biến, phương pháp này đã tập

trung vào lớp đột biến phải kiểm tra, cung cấp độ tin cậy vào các toán tử đột

biến giúp tạo ra dữ liệu thử mạnh hơn (tức là chúng có thể diệt nhiều đột biến

hơn).

3.1.2. Phương pháp làm nhanh hơn (A “do smarter” approach)

Các kỹ thuật làm nhanh hơn nhằm mục đích tạo ra và chạy các chương

trình đột biến nhanh hơn các hệ thống chuẩn. Hầu hết các hệ thống đột biến

truyền thống thông dịch các đột biến của chúng, nó thì thuận tiện nhưng chậm

hơn so với thực hiện biên dịch chương trình.

Kỹ thuật biên dịch riêng rẽ: biên dịch từng đột biến trước khi thực hiện.

Điều này sẽ làm tăng tốc độ chạy từ 15-20 lần so với hệ thống truyền thống.

Tuy nhiên, nếu thời gian biên dịch lớn hơn nhiều so với thời gian chạy thì tắc

nghẽn biên dịch có thể xảy ra, kết quả là trong khi xây dựng các chương trình

được biên dịch, sự thực thi vẫn đang diễn ra [7].

Để tránh tắc nghẽn, Krauser đã sử dụng một cơ chế đột biến tích hợp

trình biên dịch, sử dụng một trình biên dịch mới để biên dịch đồng thời PUT

và phát triển các đoạn chương trình (code patches) biểu diễn cho các đột biến.

Trước khi thực thi, các đoạn chương trình cần thiết được áp dụng để PUT

được biên dịch cung cấp một chương trình đột biến thực hiện với tốc độ biên

dịch. Do đó, PUT chỉ cần được biên dịch một lần. Các kết quả của Krauser

chứng minh rằng phương pháp tích hợp trình biên dịch làm tăng tốc độ đáng

kể (tính bằng tỷ lệ giữa các kỹ thuật thời gian thực hiện trung bình trên mỗi

đột biến để tạo ra và thực hiện tất cả các đột biến đối với một trường hợp

kiểm thử) so với biên dịch riêng rẽ khi thời gian thực hiện PUT thấp. Ví dụ,

sử dụng phương pháp tích hợp trình biên dịch cho chương trình TRANSPOSE

Page 43: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

43

nhanh hơn 7,58 lần so với sử dụng kỹ thuật biên dịch riêng rẽ và làm cho

chương trình TRITYP nhanh hơn 27,33 lần.

Nói chung, thời gian thực hiện chương trình ảnh hưởng đến sự gia tăng

tốc độ của phương pháp tích hợp trình biên dịch. Với thời gian thực hiện thấp

(tức là thời gian thực hiện < thời gian biên dịch), phương pháp biên dịch riêng

rẽ thực hiện các đột biến nhanh hơn. Sự chậm trễ lúc biên dịch xảy ra trong

toàn bộ thời gian thực hiện tất cả các đột biến tăng và vì vậy làm tăng thời

gian thực hiện đột biến trung bình. Tuy nhiên, với số lần thực hiện cao hơn

(tức là thời gian thực hiện > thời gian biên dịch), thời gian biên dịch sẽ trở

nên ít quan trọng. Các đột biến có thể dễ dàng được biên dịch trước khi thực

hiện có nghĩa là thời gian trung bình để thực hiện từng đột biến bằng phương

pháp biên dịch riêng rẽ chỉ phụ thuộc vào thời gian thực hiện - giống như kỹ

thuật tích hợp trình biên dịch, có nghĩa là tỷ lệ gia tăng tốc độ các phương

pháp là 1/1.

3.1.2.1. Phương pháp tạo lược đồ đột biến

Phương pháp tạo lược đồ đột biến (MSG) [18] là một trong những

phương pháp giúp khắc phục vấn đề tắc nghẽn. Tất cả các đột biến của

chương trình được mã hóa vào một mức mã nguồn duy nhất gọi là chương

trình siêu đột biến (metamutant). Các điểm đột biến trong PUT (chẳng hạn

như một phép toán số học) được thay thế bằng các lời gọi hàm có cú pháp hợp

lệ được gọi là siêu thủ tục (metaprocedure). Mỗi metaprocedure mã hóa toán

tử đột biến và thay đổi đầu ra của nó tùy thuộc vào các đối số. Ví dụ, tùy

thuộc vào các đối số của nó, metaprocedure số học sẽ thực hiện cộng, trừ,

nhân, chia, hoặc module. Sau đó, các đột biến được biểu diễn dưới dạng một

tập các đối số metaprocedure được áp dụng lúc thực thi metamutant. Bằng

cách chỉ thay đổi một đối số metaprocedure duy nhất từ tập các đối số

metaprocedure (của PUT) ban đầu, đột biến thích hợp có thể được thực hiện.

Page 44: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

44

Điều này có nghĩa là các đột biến không được biên dịch hoặc thông dịch riêng

rẽ và được thực hiện trong môi trường đích với tốc độ chương trình biên dịch.

Một metamutant đơn giản của đoạn chương trình ở hình 3.3 được mô tả

ở hình 3.4. Metamutant này được tạo ra bằng cách chỉ sử dụng toán tử đột

biến toán tử quan hệ thay thế mọi trường hợp của toán tử quan hệ bằng một

metaprocedure toán tử quan hệ thích hợp, trong trường hợp này ROR:op()

được biểu diễn ở dòng 2- hình 3.4. ROR:op() có ký hiệu: ROR:op(int lhs; int

rhs; int mutantNumber).

Metaprocedure được định nghĩa dòng 1- hình 3.4. Trong quá trình thực

hiện metamutant này, các đối số thích hợp được cung cấp cho metaprocedure

ROR cho phép bất kỳ toán tử quan hệ được áp dụng hai giá trị.

Mỗi đột biến được biểu diễn bằng một dãy các giá trị biểu diễn toán tử

cho mỗi metaprocedure. MutantNumber là chỉ số metaprocedure trong dãy

đột biến. Ví dụ: mutantNumber trong đoạn mã 3.2 là 0, biểu diễn giá trị ở chỉ

// phương thức PUT đột biến bằng toán tử ROR

1 import MTAIS.Operators.ROR;

...

public boolean sumIsPositive (int n, int m){

z = 0;

sum = n + m;

2 return (ROR.op(sum, z, 0));

}

Hình 3.4- Phiên bản đột biến của PUT gốc hình 3.3

// phương thức PUT gốc

public boolean sumIsPositive (int n, int m){

z = 0;

sum = n + m;

return (sum > z);

}

Hình 3.3- Ví dụ phương thức PUT gốc

Page 45: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

45

số 0 trong dãy đột biến thiết lập toán tử được sử dụng trong ROR:op(). Tất cả

các toán tử quan hệ được đánh số, ví dụ: < là 0, là 1, == là 2, > là 3 và v.v...

Giá trị chỉ số mutantNumber xác định toán tử quan hệ để áp dụng, trong ví dụ

này, câu lệnh sum > z sẽ được thực hiện bởi một dãy đột biến với chỉ số 0

chứa 3 (số cho toán tử quan hệ >). Để thực hiện sum == z, giá trị ở chỉ số 0

sẽ được sửa đổi bằng 2 (số cho toán tử quan hệ ==). Bằng cách sử dụng

phương pháp này, tất cả các đột biến đều xuất hiện trong metamutant, từng

đột biến được chọn lúc thực thi bằng cách áp dụng các giá trị thích hợp từ dãy

đột biến vào các metaprocedure.

Untch và các đồng nghiệp [18] cho biết rằng việc thực hiện thủ tục tìm

nghiệm theo phương pháp Niutơn bằng cách sử dụng sản sinh lược đồ đột

biến thì nhanh hơn 4,1 lần sử dụng phương pháp thông dịch [18]. Họ lập luận

rằng đây “là một tín hiệu tốt cho thấy MSG có thể tăng đáng kể khả năng thực

thi của kiểm thử đột biến ".

3.1.2.2. Đột biến yếu (Weak Mutation)

Kỹ thuật này được đề xuất bởi Howden [21]. Để tăng tỷ lệ đột biến, kiểm

thử đột biến phải diệt các đột biến được thể hiện ở kết quả đầu ra khác với

PUT khi nhận cùng đầu vào. Do đó, kiểm thử đột biến mạnh (strong

mutation) tiếp tục thực hiện đột biến cho đến khi hoàn thành và so sánh các

kết quả đầu ra tiếp theo hoặc các trạng thái chương trình. Nhưng điều này là

lãng phí. Hãy so sánh một đột biến với PUT. Từng câu lệnh chương trình là

giống nhau ngoại trừ câu lệnh đơn có chứa đột biến, dẫn đến các kết quả đầu

ra có thể khác nhau, code “lỗi” này sẽ gây ra một số trạng thái khác ngay sau

khi nó được thực hiện. Nếu không tìm thấy trạng thái khác thì đột biến sẽ tiếp

tục theo đường chương trình giống nhau và tạo ra đầu ra giống như PUT. Tuy

nhiên, nếu tìm thấy trạng thái khác từ điểm này (vị trí tạo ra đột biến) thì điều

này cho biết các kết quả đầu ra của chương trình có thể khác nhau và lưu việc

Page 46: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

46

thực hiện phần còn lại của đột biến. Đây là tiền đề về sau của kiểm thử đột

biến yếu.

Đột biến yếu khác với đột biến mạnh khi so sánh các trạng thái của đột

biến và PUT. Cả hai phương pháp có thể được phân loại khi so sánh ở các thái

cực đối lập: đột biến yếu so sánh ngay sau câu lệnh đột biến, còn đột biến

mạnh so sánh khi kết thúc chương trình.

Những biến đổi này của đột biến yếu đã được nghiên cứu bằng thực

nghiệm. Cụ thể, sử dụng phiên bản đã sửa đổi của Mothra, được gọi là

Leonardo (quan sát đầu ra mong đợi không phải sau khi trả về nhưng vẫn

trong quá trình hoạt động). Offutt và Lee [9] thực hiện các nghiên cứu về đột

biến vững chắc bằng cách sử dụng bốn điểm so sánh khác nhau:

i. Sau khi thực hiện biểu thức trong cùng nhất bao quanh đột biến

đầu tiên;

ii. Sau khi thực hiện câu lệnh đột biến đầu tiên - đột biến yếu truyền

thống;

iii. Sau khi thực hiện khối cơ bản đầu tiên (các lệnh tuần tự với các

điểm vào và ra duy nhất) bao quanh đột biến;

iv. Sau N lần thực hiện đột biến chứa khối cơ bản trong đó N là lớn

hơn 1 và nhỏ hơn số lần khối cơ bản được thực hiện trong PUT -

một đột biến bị diệt khi xuất hiện trạng thái không chính xác đầu

tiên.

Offutt và Lee đã thực hiện hai nghiên cứu so sánh bốn phiên bản trên với

đột biến mạnh. Nghiên cứu đầu tiên là tạo ra các tập dữ liệu thử có tỷ lệ đột

biến vững chắc (firm-mutation scoring) 100% cho từng phương pháp vững

chắc và thực hiện chúng bằng cách sử dụng đột biến mạnh để tạo ra toàn bộ tỷ

lệ đột biến. Nghiên cứu thứ hai là tạo ra tập dữ liệu thử với các tỷ lệ đột biến

ít hơn 90% và thực hiện bằng bốn phương pháp vững chắc để xác định các tỷ

lệ đột biến vững chắc của chúng. Các kết quả khá thú vị. Bằng trực quan,

Page 47: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

47

phương pháp (iv) sẽ kiểm tra các trạng thái chương trình gần với kết thúc

chương trình tự nhiên hơn và do đó gần với hệ thống đột biến mạnh hơn, cho

thấy rằng phương pháp này cung cấp mạnh hơn tức là thu được dữ liệu thử

chất lượng hơn. Đây không phải là trường hợp duy nhất. Nghiên cứu đầu tiên

cũng chỉ ra rằng điểm hiệu quả nhất để thực hiện các so sánh trạng thái là sau

khi thực hiện câu lệnh bị đột biến (phương pháp ii) hoặc thực hiện khối cơ

bản đầu tiên (phương pháp iii). Các kết quả từ nghiên cứu của Offutt và Lee

cho thấy rằng đột biến yếu cũng có thể làm giảm đáng kể chi phí tính toán,

với tiết kiệm thường vượt trên 50% số lần thực hiện.

Xem xét ví dụ về thử nghiệm đột biến yếu, lấy từ một trong những giấy

tờ của Brian Marick với chỉnh sửa nhỏ:

Trong phạm vi bảo hiểm đột biến yếu chúng ta giả sử rằng một chương

trình có chứa một lỗi đơn giản. Một trong những lỗi có thể được sử dụng <=

thay vì < chính xác trong một biểu thức như sau:

if (A <= B)

Với chương trình này, một đột biến hệ thống bảo hiểm yếu sẽ tạo ra một

thông báo như : "Gcc.c", dòng 488: <= có thể thay thế <

Có thể các thử nghiệm gây ra các mã chạy (A <= B) luôn luôn có cùng

một giá trị (A < B), đó là trường hợp A = B. Thông báo này sẽ tiếp tục xuất

hiện cho đến khi chương trình được thực hiện trong một trường hợp thử

nghiệm mà (A <= B) có một giá trị khác hơn (A < B).

Với đột biến mạnh Jester cho thấy nếu kiểm tra vẫn vượt qua khi biểu thức

(A <= B) được thay thế bằng (A < B). Điều này cho thấy rằng một thử

nghiệm có thể bị mất (trường hợp A = B), do đó nó làm cho một sự khác biệt

rằng "<=" hơn "<". Trong trường hợp này đột biến yếu là tốt.

Từ kết quả từ nghiên cứu của các nhà khoa học cho thấy rằng đột biến

yếu cũng có thể làm giảm đáng kể chi phí tính toán.

Page 48: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

48

3.2. Tăng tự động hóa Bên cạnh chi phí tính toán quá tốn kém, khả năng tự động hóa cũng là

một trong những rào cản đối với kiểm thử đột biến để được chấp nhận trong

ngành công nghiệp phần mềm. Các rào cản này có thể được phân loại như là

những khó khăn về tự động hóa với thực trạng hiện tại, đòi hỏi nỗ lực đáng kể

từ kiểm thử viên.

Trước hết, dữ liệu thử phải được tạo ra để diệt các đột biến. Trong khi đó,

đối với phần lớn các đột biến, dữ liệu thử ngẫu nhiên nào sẽ đáp ứng đủ (cung

cấp bằng cách sử dụng các bộ sản sinh dữ liệu thử ngẫu nhiên), một tỷ lệ nhỏ

các đột biến khó để diệt đòi hỏi phải rà soát lại mã nguồn và các dữ liệu thử

được tạo ra bằng thủ công để xác định các lỗi. Đây là vấn đề tốn nhiều thời

gian và đầy thử thách. Hơn nữa, tỷ lệ đột biến được tính toán khi đo lường

chất lượng dữ liệu thử phải giảm số lượng các đột biến tương đương. Đây là

vấn đề được cho là không giải được, xác định các đột biến tương đương theo

cách truyền thống được thực hiện bằng tay. Một lần nữa, đây lại là công việc

tốn kém hơn nữa, cản trở sự thu hút của ngành công nghiệp. Do đó để tăng

tính tự động hoá cho chương trình kiểm thử thì phải có kỹ thuật sao cho tạo

được dữ liệu thử và xác định các đột biến tương đương một cách tự động.

3.2.1. Tạo dữ liệu thử tự động

Một trong những nhiệm vụ kỹ thuật khó nhất trong kiểm thử phần mềm

là tạo ra các dữ liệu thử cần thiết để đáp ứng các tiêu chuẩn kiểm thử. Để thực

hiện được điều này. Offutt đã phát triển kỹ thuật kiểm thử dựa trên ràng buộc

(CBT) để tạo ra các tập dữ liệu thử chất lượng dựa trên đột biến. Kỹ thuật này

dựa trên khái niệm để diệt được đột biến thì dữ liệu thử phải thỏa mãn ba điều

kiện: 1. Điều kiện có thể đạt đến được: Các chương trình đột biến khác so với

PUT bởi một lượng nhỏ thường được chứa trong một câu lệnh đơn.

Vì tất cả các câu lệnh khác đều giống nhau, câu lệnh bị đột biến này

Page 49: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

49

phải chịu trách nhiệm về một sự khác biệt trong các đầu ra của

chương trình. Vì vậy, để dữ liệu thử phân biệt đột biến từ PUT thì câu

lệnh bị đột biến này phải đạt đến được (tức là câu lệnh bị đột biến

phải được kích hoạt).

2. Điều kiện cần: Khi đạt đến được câu lệnh bị đột biến, điều kiện cần là

câu lệnh đột biến phải gây ra một trạng thái chương trình bên trong

không đúng ngay sau khi nó được thực hiện. Nếu không thì đột biến

không thể thất bại vì với tất cả các câu lệnh khác đều giống nhau,

không có câu lệnh kế tiếp nào có thể gây ra trạng thái bên trong để

khác biệt.

3. Điều kiện đủ: Cuối cùng, dữ liệu thử là đủ nếu như trạng thái không

đúng truyền qua đột biến dẫn đến thất bại khi kết thúc. Nếu bất kỳ câu

lệnh nào sửa chữa trạng thái bên trong thì hoặc là đột biến tương

đương hoặc dữ liệu thử không đủ chất lượng trong việc gây ra đầu ra

của chương trình khác biệt.

Các điều kiện này đã được sử dụng bởi bộ sản sinh dữ liệu tự động

Godzilla để tạo ra các tập dữ liệu thử cho Mothra. Godzilla mô tả các điều

kiện bằng miền đầu vào dựa trên các biểu thức đại số được gọi là các ràng

buộc, để xác nhận từng điều kiện được đáp ứng. Các ràng buộc về điều kiện

có thể đạt đến được được biểu diễn bằng các biểu thức đường dẫn mô tả tất cả

các đường dẫn tới câu lệnh bị đột biến. Tương tự như vậy, các ràng buộc về

điều kiện cần xác nhận rằng liệu việc thực hiện câu lệnh đột biến có dẫn đến

trạng thái bên trong không đúng hay không. Tuy nhiên, không thể tạo ra các

ràng buộc về điều kiện đủ vì chúng đòi hỏi phải biết trước kết quả của đường

dẫn hoàn chỉnh mà chương trình sẽ lấy. Điều này là không thể giải được [13].

Thay vào đó, Godzilla kết hợp các ràng buộc về điều kiện có thể đạt đến được

và điều kiện cần, và giải quyết vấn đề này để cung cấp dữ liệu thử thực hiện

câu lệnh bị đột biến tạo ra trạng thái bên trong không nhất quán. Đáng lưu ý,

Page 50: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

50

dữ liệu thử có thể tạo ra trạng thái bên trong không nhất quán trong đột biến

mà sau đó được sửa chữa để tạo ra đầu ra mong muốn; đột biến sẽ bị diệt khi

nó vẫn còn sống. Các kết quả thực nghiệm cho rằng các phương pháp CBT

tạo ra dữ liệu thử có tỷ lệ đột biến cao, diệt được trên 90% đột biến.

3.2.2. Xác định các đột biến tương đương tự động

Một vấn đề khó khăn nữa đối với kiểm thử đột biến là việc xác định liệu

một đột biến còn sống có tương đương với chương trình gốc hay không. Các

đột biến tương đương hiển thị đầu ra giống như chương trình gốc cho tất cả

các đầu vào có thể có và phải được loại bỏ trước khi tính toán tỷ lệ đột biến.

Nếu chúng không bị loại bỏ, tỷ lệ các đột biến bị diệt không bao giờ có thể đạt

được 100% (trong trường hợp các đột biến tương đương vẫn còn tồn tại), do

đó sẽ làm giảm sự tin tưởng của kiểm thử viên vào tính đúng đắn của PUT và

dữ liệu thử.

Một tập dữ liệu thử diệt ít hơn 100% các đột biến được tạo ra hoặc là

không đủ để diệt các đột biến còn lại, hoặc các đột biến còn lại là tương

đương, hoặc cả hai. Tóm lại, kiểm thử viên sẽ không biết chắc chắn về những

tình huống phát sinh trừ khi họ có thể xác định được các đột biến tương

đương. Tuy nhiên, các đột biến tương đương phải được loại bỏ và do đó các

hệ thống đột biến truyền thống trở thành gánh nặng cho các kiểm thử viên vì

phải xác định các đột biến tương đương thủ công dễ bị lỗi. Tệ hơn nữa, có

nhiều tiềm năng cho một số lượng lớn các đột biến tương đương tồn tại, mỗi

đột biến phải được xác định riêng rẽ.

Offutt và Craft [6] thực hiện các thuật toán dựa trên luồng dữ liệu và các

kỹ thuật tối ưu hóa trình biên dịch để xác định các chương trình tương đương

một cách tự động. Thực tế, các kỹ thuật tối ưu hóa trình biên dịch sử dụng các

phép biến đổi tối ưu hóa chương trình để tạo ra các chương trình tương đương

bằng cách hoặc là tối ưu hóa hoặc tái tối ưu hóa chương trình gốc, do đó nếu

đột biến thỏa mãn quy tắc tối ưu hóa chương trình thì nó có thể là tương

Page 51: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

51

đương. Ý tưởng tối ưu hóa trình biên dịch này được đề xuất đầu tiên bởi

Baldwin và Sayward trong. Offutt và Craft sử dụng sáu kỹ thuật tối ưu hóa

trình biên dịch để xác định các đột biến tương đương được mô tả chi tiết hơn

trong [13]:

Xác định các đoạn mã chương trình chết (dead code) - Hình thức rõ

ràng nhất: các đoạn mã lệnh không thể thực hiện được có chứa câu lệnh

được sửa đổi sẽ là tương đương với PUT. Xác định thông qua đồ thị

luồng điều khiển.

Truyền hằng số (constant propagation) - Một biến có giá trị được xác

định bằng hằng số khi chạy sẽ tạo ra các đột biến tương đương trong

một số trường hợp. Ví dụ, hãy xem xét toán tử đột biến ABS. Một câu

lệnh đột biến thực hiện giá trị tuyệt đối của một hằng số ( 0) sẽ luôn

luôn tạo ra một đột biến tương đương.

Truyền bất biến (invariant propagation) - Bất biến là một quan hệ đúng

giữa hai biến hoặc một biến và một hằng số trong đó được xác định tại

một điểm cụ thể trong chương trình. Ví dụ, để diệt một đột biến thay

thế một biến bằng một biến khác, hai biến phải có giá trị khác nhau.

Nếu biết được chúng đều bằng nhau tại điểm này, thì đột biến có khả

năng là tương đương.

Xác định biểu thức con chung - Sử dụng kết hợp với kỹ thuật truyền bất

biến, xác định các biến tương đương dựa trên các biểu thức con chung.

Ví dụ, nếu A = B + C - D và X = B + C - D thì A == X sau khi gán X.

Thông tin này được sử dụng bằng kỹ thuật truyền bất biến để xác định

các đột biến tương đương.

Xác định bất biến vòng lặp - Tối ưu hóa code thường di chuyển mã bất

biến ra bên ngoài vòng lặp. Nếu đột biến thay đổi vị trí này (tức là di

chuyển mã vào bên trong hay ra bên ngoài vòng lặp) thì nó là tương

đương.

Page 52: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

52

Nâng lên và hạ xuống (hoisting and sinking) - Tối ưu hóa chương trình

cố gắng di chuyển đoạn mã chương trình được thực hiện nhiều lần đến

vị trí mà nó được thực thi một lần. Các đột biến có ảnh hưởng bởi vị trí

này là tương đương.

Offutt và Craft đã kiểm tra việc thực hiện của chúng trên 15 chương

trình thử nghiệm. Các kết quả mà họ nhận được là xác định được từ 0 đến

100% các đột biến tương đương, mặc dù giá trị trung bình là khoảng 10%.

Tuy nhiên, xét các đột biến tương đương thường phải được xác định bằng tay,

phương pháp này được thực hiện để giảm bớt gánh nặng cho các kiểm thử

viên.

Page 53: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

53

3.3. Kết luận

Kiểm thử đột biến được được xem là một kỹ thuật kiểm thử đơn vị mạnh

để tìm ra tập dữ liệu thử hiệu quả giúp phát hiện các lỗi trong chương trình.

Tuy nhiên, kiểm thử đột biến còn có một số hạn chế về chi phí tính toán và tự

động hóa, được phân tích ở chương 2.

Nhằm nâng cao hiệu quả của kiểm thử đột biến, các nghiên cứu đã tập

trung vào một số phương pháp để giảm chi phí tính toán: làm ít, làm nhanh.

Tăng tự động hóa trong kiểm thử đột biến mắc phải ba trở ngại chính: tạo ra

các dữ liệu thử, xác định các đột biến tương đương, và xác định tính đúng đắn

đầu ra của chương trình. Những vấn đề này cần phải được khắc phục, ở một

mức độ nhất định, cho ngành công nghiệp chấp nhận kiểm thử đột biến như

một công cụ hữu hiệu.

Offutt đã phát triển phương pháp kiểm thử dựa trên ràng buộc (CBT) để

sản sinh dữ liệu thử tự động, các kết quả thực nghiệm là khá triển vọng, với

CBT diệt được trung bình 97% các đột biến. Các kỹ thuật dựa trên tối ưu hoá

trình biên dịch đã được áp dụng để phát hiện đột biến tương đương, các kết

quả trong nghiên cứu cho thấy các phương pháp này phát hiện tỷ lệ trung bình

10% các đột biến tương đương. Kiểm thử phần mềm đòi hỏi tính chính xác

của dữ liệu thử thực hiện trên PUT được xác định. Nghiên cứu này giả sử

rằng tồn tại một quy trình tự động thích hợp cho mỗi PUT mà có thể quyết

định tính đúng đắn của dữ liệu thử dựa trên các đặc tả của chương trình.

Page 54: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

54

CHƯƠNG 4 - ỨNG DỤNG KỸ THUẬT KIỂM THỬ ĐỘT BIẾN ĐỂ KIỂM THỬ CÁC CHƯƠNG TRÌNH C (C – SHARP)

Trong thời gian gần đây, ngôn ngữ C-Sharp là một trong những

ngôn ngữ được sử dụng rộng rãi để phát triển các ứng dụng, C-Sharp là

phiên bản cao của C . Trong phần ứng dụng này em xin đề xuất quy trình

áp dụng kỹ thuật kiểm thử đột biến cho các ứng dụng được phát triển

dùng C- Sharp.

Quy trình ứng dụng kiểm thử đột biến để kiểm thử các chương

trình C-Sharp áp dụng kỹ thuật kiểm thử đột biến lựa chọn và sử dụng

công cụ Nester, dùng để phân tích và tạo đột biến, và công cụ NUnit

dùng để kiểm thử đơn vị. Quy trình này được minh họa trong Hình 4.1.

Hình 4.1. Quy trình ứng dụng kỹ thuật kiểm thử đột biến trong C-Sharp

Tốt

Chương trình P NUnit 2.5.2

Chỉnh sửa P Tốt?

NESTER Đột biến P’

Gọi lệnh biên dịch

NUnit 2.5.2 Kết quả

Không tốt

Không tốt

Tốt

Page 55: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

55

4.1. Tìm hiểu về NUnit

4.1.1. Định nghĩa

NUnit là một framewwork miễn phí được sử dụng khá rộng rãi trong

Unit Testing đối với ngôn ngữ .Net. Ban đầu được chuyển từ JUnit, phiên bản

sản xuất hiện nay là phiên bản 2.5.

NUnit được viết hoàn toàn bằng C# và đã được hoàn toàn thiết kế lại để

tận dụng lợi thế của nhiều người.

Ngôn ngữ .Net cho các thuộc tính tùy chỉnh các tính năng ví dụ và liên

quan phản ánh khả năng khác.

4.1.2. Đặc điểm của NUnit

- NUnit không phải là giao diện tự động kiểm tra.

- Không phải là một ngôn ngữ kịch bản, kiểm tra tất cả các Unit testing

được viết bằng .Net và hỗ trợ ngôn ngữ như C#, VC, VB.Net, J#...

- Không phải là công cụ chuẩn.

- Đi qua các bộ phận kiểm tra toàn bộ không có nghĩa là phần mềm được

sản xuất sẵn sàng.

4.1.3. Thuộc tính hay dùng trong thư viện NUnit.Framework

Page 56: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

56

- [TestFixture]: Dùng để đánh đấu một lớp kiểm thử (test class), những

lớp khác không có thuộc tính này sẽ mặc định bị “ignore” khi NUnit test

assembly của bạn, ví dụ:

- [Test]: Dùng để đánh dấu một phương thức (method) được gọi là test

method. Ý nghĩa của nó tương tự như TestFixture nhưng phạm vi ở cấp

method. Ví dụ:

- [SetUp]: Dùng để đánh dấu một phương thức (method) sẽ gọi trước khi

một test case được gọi. Nếu trong một test class có 10 method test, thì mỗi lần

một method test chạy thì NUnit sẽ chạy method được đánh dấu với Setup đầu

tiên.

- [TearDown]: Thuộc tính này ngược với Setup, chạy sau mỗi method

test.

- [TestFixtureSetup]: Dùng để đánh dấu một class sẽ được gọi trước khi

một test case được gọi. Khi một test class được chạy thì method nào được

đánh dấu với thuộc tính này sẽ được chạy trước tiên.

Ví dụ:

- [TestFixtureTearDown]: Ngược với TestFixtureSetup.

Page 57: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

57

- [ExpectedException]: Chỉ ra rằng kết quả bình thường của bài test sẽ là

một ngoại lệ được đưa vào. Nếu không phải là một ngoại lệ được đưa vào

hoặc một ngoại lệ khác được đưa vào thì test đó sẽ thất bại.

- [Ignore]: Việc thuộc tính nghi ngờ (Ignore) có thể được thêm vào một

bài test hay một TestFixture. Đánh dấu một test hay một TestFixture như bị

bỏ qua sẽ gây ra các bài test không chạy. Giao diện của NUnit sẽ hiển thị các

bài test là màu vàng.

- [Category]: Thuộc tính phạm trù (category) cho phép bạn test từng

nhóm theo từng phạm trù, bởi đang áp dụng thuộc tính category vào từng test

hay testfixture. Có thể chọn để bao gồm hay loại trừ các phạm trù cụ thể khi

đang test các unit test.

4.1.4. Phương thức tĩnh hay dùng trong NUnit.Framework.Assert

Trong lớp Assert của thư viện NUnit.Framework có một số phương thức

tĩnh để có thể khẳng định tính đúng đắn cho một số điểm trong bài test:

Page 58: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

58

Assert.AreEqual (object, object): Là kiểm tra sự bẳng nhau bởi

cách gọi phương thức Equal trên đối tượng.

Assert.AreEqual( int, int): Là so sánh hai giá trị để kiểm tra bằng

nhau. Test chấp nhận nếu các giá trị bằng nhau.

Assert.AreEqual( float, float, float):

Assert.AreEqual( double, double, double):

Assert.Fail(): Là hữu ích khi có một bộ test. Test sẽ chấp nhận nếu

biểu thức sai.

Assert.IsTrue( bool): Đánh giá một biểu thức luận lý. Test chấp

nhận nếu biểu thức đúng.

Assert.IsFalse(bool): Đánh giá một biểu thức luận lý. Test chấp

nhận nếu biểu thức sai.

Assert.IsNull(bool): So sánh tham chiếu của đối tượng với giá trị

null. Test sẽ được chấp nhận nếu tham chiếu là null.

Assert.IsNotNull(bool): So sánh tham chiếu của một đối tượng

null. Test sẽ chấp nhận nếu biểu thức tham chiếu đối tượng khác

nulll.

Assert.AreSame(object, object): Thực thi một tham chiếu bảng

trên hai đối tượng là điểm giống như đối tượng.

Assert.Ignore(): dùng để test trạng thái nghi ngờ

Assert.IsEmpty(): Khẳng định một mảng, danh sách hay một bộ

nào đó là rỗng.

Assert.IsNotEmpty(): Khẳng định một mảng, danh sách, hay một

bộ nào đó là không rỗng.

Page 59: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

59

4.1.5. Cài đặt NUnit

Để có thể cài đặt được NUnit cần phải có bộ cài của Nuint. Bạn đọc có

thể download ở trang chủ của NUnit:

http://www.NUnit.org/index.php?p=download .

Ví dụ như phiên bản: NUnit-2.5.2.9222.msi hay NUnit-2.5.7.10213.msi.

Các bước cài đặt:

Bước 1: chạy file Nuni -2.5.2.9222.msi sẽ được như thế này và

click Next

Bước 2: Tick vào ô “I accept…” và click Next

Page 60: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

60

Bước 3: Chọn vào “Typical” và Click Next

Bước 4: Click Install và tiếp tục cài đặt.

Bước 5: Quá trình hoàn thành nhấn Finish.

Page 61: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

61

4.1.6. Cách sử dụng NUnit

a. Hướng dẫn tạo test case trong Visual studio 2008

Giả sử tạo ra một bộ test như sau:

Bước 1: Mở visual studio 2008, tạo ra một Solution mới để dùng

cho việc test.

Bước 2: Thêm vào một project có tên là MyApp vào Solution.

Đây là dự án mà ta có thể chạy thử nghiệm.

Bước 3: Đổi tên class1 thành MyMath. Thay đổi cách khai báo

các lớp:

Page 62: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

62

Bước 4: Thêm một phương thức duy nhất là “Add” để cho phép

tính tổng của hai số và kết quả trả về là tổng của hai số đó. Hoàn

thành lớp đó:

Bước 5: Thêm vào một project mới là MyAppTest vào Solution.

Đây là dự án sẽ cho phép NUnit kiểm thử. Đó là ý tưởng tốt để sử

dụng một tên cho phép các dự án test dễ dàng xác định. (Kích

chuột phải vào Solution →Add→New Project → NameProject).

Page 63: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

63

Bước 6: Chọn tham chiếu NUnit framework cho test project

MyAppTest; Chọn Project->Add Reference from the Visual

Studio .NET IDE menu. In the Add Reference dialog, double-click

on NUnit.framework in the listbox on the .NET tab and click OK.

Bước 7: Thêm một tham chiếu tới các dự án đang được

test:MyApp cho dự án test MyAppTest. Select Project →Add

Reference. Thêm một tham chiếu tới NUnit Framework: Add

reference →Tab Project → Chọn dự án mà đang test →OK.

Page 64: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

64

Bước 8: The Solution Explorer bây giờ như hình vẽ sau:

Bước 9: Thêm thư viện NUnit.Framework đến lớp test class1.

Using NUnit.Framework;

Bước 10: Sử dụng namespace MyApp:

Using MyApp;

Bước 11: Thêm một thuộc tính [TestFixture] tới test class

MyAddTest để chỉ ra rằng lớp này chứa mã kiểm tra.

Page 65: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

65

Bước 12: Tạo ra một phương thức MyTest trong lớp test. Lưu ý

phương thức này sử dụng public và void, và không có đối số

truyền vào. Xác định phương thức test bằng việc trang trí nó với

thuộc tính [Test].

Bước 13: Viết một test. Trong trường hợp này, kiểm thử phương

thức Add trong MyMath.

Hoàn thành một tình huống test

Page 66: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

66

b. Sử dụng NUnit

Sau khi hoàn thành công việc viết code cho các tình huống test ở trên thì

bắt đầu sử dụng NUnit để kiểm tra quá trình viết code tạo ra các test case ở

trên.

Quá trình test trong NUnit:

Bước 1: Chạy NUnit thì giao diện của NUnit sẽ như sau:

Bước 2: Add project vừa viết vào công cụ NUnit như sau: (trước

khi thực hiện công việc Add project cần phải Built project đó.)

File →Open Project →Tìm tới File MyAppTest.exe(file vừa viết)

Page 67: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

67

Kích vào MyAppTest.exe →Open. Lúc này giao diện của NUnit

như sau:

Bước 4: Kiểm tra bằng cách ấn vào Run. Lúc này giao diện của

NUnit sẽ hiển thị như sau:

Trong giao diện của NUnit gồm có: MyAppTest là namespace để thực

thi, MyAddTest là lớp test, MyTest là phương thức test.

Page 68: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

68

Trường hợp lỗi xảy ra trong khi viết code test case bị sai: Ví dụ: Đưa sai

mong đợi đầu ra của test case đó thì giao diện của NUnit sẽ như sau:

Trong giao diện này có hiển thị: Expected(mong đợi): 11 nhưng But was

(thực tế):10.

Chú ý: Có một số trường hợp khi Add vào NUnit một file mà nó hiển thị

ra:

Cách khắc phục như sau: (add NUnit vào trong Visual Studio)

1. Mở project chuẩn bị test ra.

2. Thực hiện vào:

Menu Tools→ External Tools→ Add→…(điền thông số như

hình vẽ sau:)

Page 69: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

69

Thực hiện một test case khác cũng làm tương tự như vậy.

4.2. Công cụ Nester

Nester là một công cụ miễn phí là hệ thống đột biến cho C-Sharp hỗ trợ

toàn bộ quá trình đột biến cho các chương trình C-Sharp. Nó sản sinh các đột

biến một cách tự động, thực thi các đột biến với các dữ liệu thử và báo cáo tỷ

lệ đột biến của dữ liệu thử đó. Nó liên quan đến việc sửa đổi bổ sung các

chương trình để có thể phân biệt các chương trình ban đầu từ các chương trình

bị sửa đổi.

Phiên bản hiện tại của Nester là 0.3 Alpha hỗ trợ cho chương trình C-

Sharp trong Microsoft Visual Studio 2005 và NUnit Framework.

4.2.1. Điều kiện tiên quyết

Microsoft . NET Framework 2.0 (tải miễn phí). Đây là phiên bản duy

nhất được hỗ trợ ở thời điểm hiện tại.

4.2.2. Giải pháp cho đột biến

1. Tạo một bản sao của cơ sở mã nguồn

2. Mở ứng dụng trong Visual Studio 2005

3. Xây dựng cấu hình phát hành

4. Chạy đơn vị thử nghiệm

Page 70: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

70

4.2.3. Chạy Nester

1. Tải về Nester.zip

2. Giải nén nội dung của kho lưu trữ vào thư mục đích

3. Sao chép NUnit.core.dll và NUnit.core.interfaces.dll từ cài đặt NUnit

vào thư mục mục tiêu Nester

4. Lưu ý thư mục NET Framework. (% SystemRoot% \ Microsoft.NET \

Framework \ v2.0.50727) trong đường dẫn để Nester có thể chạy

msbuild.exe. Nếu không, hãy thêm nó thông qua Control Panel /

System / Advanced / Biến môi trường

5. Run Nester.exe

Giao diện khi chạy Nester:

Page 71: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

71

Minh họa một chương trình chạy hệ thống đột biến được hiển thị trong chế độ

xem mã nguồn:

Trong đoạn mã nguồn trên, các điểm mã màu xanh lá cây là nơi xảy ra

các đột biến và các đột biến này đã bị diệt. Điểm màu đỏ đại diện cho các đột

biến chưa diệt được.

Page 72: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

72

4.2.4. Lựa chọn Nester.exe.config

Key Giá trị

mặc định Mô tả

ReportKilledMutations đúng

Báo cáo thông tin về đột biến cố gắng và

giết chết. Nếu sai Nester sẽ sử dụng các

bài kiểm tra chạy cho đến khi thất bại đầu

tiên

ClearReadOnlyFlag đúng Tự động rõ ràng chỉ đọc cờ từ các nguồn

UnitTestTimeOut 5000

Nếu đơn vị kiểm tra thời gian thực hiện là

vượt quá quy định thời gian chờ Nester,

xem xét kiểm tra như thất bại. Đặt ở đây

0 nếu bạn muốn chuyển đổi của thời gian

chờ việc

DetectAssertions đúng Hãy thử để phát hiện Debug.Assert ()

BuildConfiguration Phát hành Chỉ định bất cứ khi nào Nester nên xây

dựng cấu hình gỡ rối hoặc phát hành

shadowfiles.path Đường dẫn NUnit AppDomain sẽ làm

bản sao bóng

4.3. Quy trình ứng dụng kiểm thử đột biến để kiểm thử các chương trình C - Sharp

Quy trình kiểm thử các chương trình C # được minh hoạ trong hình 4.1.

Trong phần minh hoạ ứng dụng kiểm thử đột biến này xin được

minh họa chương trình cs-money được viết bằng ngôn ngữ C-Sharp gồm

có các lớp như: AssemblyInfo.cs, Imoney.cs, Money.cs, MoneyBag.cs, gồm

Bảng 4.1. Lựa chọn Nester.exe.config

Page 73: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

73

khoảng 200 dòng lệnh và 21 trường hợp kiểm thử cùng dữ liệu thử được xây

dựng trong MoneyTest.cs. Phần code của các lớp này được trình bày trong

phần phụ lục.

4.3.1. Kiểm thử

Kiểm thử chương trình này bằng bộ kiểm thử NUnit (phiên bản 2.5.2),

với các trường hợp kiểm thử và dữ liệu thử đã được thiết kế sẵn.

Dưới “góc nhìn” của NUnit với dữ liệu thử được xây dựng trong 21

trường hợp kiểm thử thì đây là một chương trình tốt .

Kết quả chạy NUnit:

Bảng 4.2. Kết quả chạy NUnit

Page 74: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

74

Phân tích kết quả sau khi chạy NUnit :

1. Kiểm tra tất cả các mục, có giá trị như nhau trong một và tổng số

các cột. Nhìn vào bảng kết quả chúng ta có thể thấy mẫu BagNegative ()

<2> diệt tổng cộng 21 đột biến, và các đột biến tương tự cũng bị diệt bởi

MixedSimpleAdd () <7 >. Điều đó không có nghĩa là chúng ta nên loại bỏ

BagNegative (), bởi vì MixedSimpleAdd () thay thế nó.

2. Kiểm tra tất cả các mục, có điểm đặc biệt số đột biến bị diệt thấp. Từ

đó để chúng ta viết trường hợp thử nghiệm cho hợp lý. Rõ ràng là các vấn đề

với việc kiểm tra quá nhỏ sẽ được tăng kích thước của mã kiểm tra đơn vị và

bảo trì do đó tốn kém hơn.

3. Kiểm tra tất cả các mục, có tổng số các đột biến bị diệt cao.

4.3.2. Tạo đột biến

Sử dụng Nester với tập toán tử đột biến được lựa chọn để thực hiện

đột biến. Tập toán tử đột biến được lựa chọn gồm: {true, false}, {+,-},

{==,!=}, {if(,if(true}, {xyz, a b c, 12, <> ?}, {1, 2, 3, 4}, {a, b, c, d}. Đây là

các toán tử có xuất hiện trong chương trình và có thể bị “viết nhầm” bởi các

lập trình viên.

Trong quá trình thực thi, Nester sinh ra số các đột biến là 78 và trong

đó có 70 đột biến bị diệt và 8 đột biến “còn sống”. Tỷ lệ đột biến ở đây là

xấp xỉ 90%. Cụ thể với từng trường hợp kiểm thử được cho trong Bảng 4.3.

Page 75: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

75

Bảng 4.3 – Chất lượng các trường hợp kiểm thử chương trình cs-money sau

khi thực thi Nester.

Trường hợp kiểm thử Số đột biến

diệt được

Số đột biến

không diệt được 1. BagMultiply 67 11 2. BagNegate 71 7 3. BagSimpleAdd 68 10 4. BagSubtract 67 11 5. BagSumAdd 68 10 6. IsZero 68 10 7. MixedSimpleAdd 71 7 8. MoneyBagEquals 71 7 9. MoneyBagHash 76 2 10. MoneyEquals 73 5 11. MoneyHash 76 2 12. Normalize 71 7 13. Normalize2 68 10 14. Normalize3 66 12 15. Normalize4 67 11 16. Print 76 2 17. SimpleAdd 74 4 18. SimpleBagAdd 68 10 19. SimpleMultiply 75 3 20. SimpleNegate 74 4 21. SimpleSubtract 73 5

Điều này chứng tỏ, chất lượng bộ dữ liệu thử được tạo ra trong 21

trường hợp kiểm thử ở trên rõ ràng là chưa cao, vì không có bất kỳ một

trường hợp kiểm thử nào diệt được tất cả các đột biến. Đặc biệt, 4 đột biến

được sinh ra khi Nester “chèn lỗi” vào lớp AssemlyInfo.cs, thì không có bất

Page 76: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

76

cứ trường hợp kiểm thử nào diệt được. Như vậy, Nester đã đưa ra được một

cảnh báo rất kịp thời để chúng ta xem xét và xây dựng lại các trường hợp

kiểm thử và bộ dữ liệu thử tốt hơn để đảm bảo chất lượng của phần mềm.

4.4. Kết luận

Kiểm thử đột biến được giới thiệu như là một ý tưởng để đánh

giá chất lượng của các bộ dữ liệu kiểm thử. Dựa vào các ưu điểm, nhược

điểm của kỹ thuật kiểm thử đột biến, có các phương pháp nhằm cải tiến

kỹ thuật kiểm thử đột biến như ở chương 3; do đó ở chương 4 đã ứng

dụng để kiểm thử chương trình C-Sharp hiệu quả, giảm chi phí và thời

gian.

Tuy nhiên từ chất lượng các trường hợp kiểm thử chương trình sau

khi chạy Nester cho thấy chất lượng bộ dữ liệu thử được tạo ra trong 21

trường hợp kiểm thử ở trên rõ ràng là chưa cao, vì không có bất kỳ một

trường hợp kiểm thử nào diệt được tất cả các đột biến. Vì vậy chúng ta

cần xây dựng lại các trường hợp kiểm thử và bộ dữ liệu thử tốt hơn nhằm

nâng cao chất lượng của chương trình cs – money.

Page 77: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

77

KẾT LUẬN

Với cách tiếp cận dựa trên những đề xuất đã có trong lĩnh vực nghiên

cứu về kiểm thử phần mềm, bản luận văn này là một sự tổng hợp những nét

chính trong kiểm thử phần mềm nói chung và kiểm thử đột biến nói riêng

cùng với những cải tiến. Sau đây là những điểm chính mà luận văn đã tập

trung nghiên cứu:

Trình bày một cách tổng quan nhất về kiểm thử phần mềm: khái

niệm, mục đích và mục tiêu của kiểm thử, trong đó giới thiệu hai

phương pháp thiết kế dữ liệu thử phổ biến được hầu hết các kiểm

thử viên sử dụng hiện nay là phương pháp kiểm thử hộp trắng và

phương pháp kiểm thử hộp đen, kèm theo các ví dụ.

Giới thiệu kỹ thuật kiểm thử đột biến, các quy tắc để tạo đột biến và

quy trình phân tích đột biến; các vấn đề còn hạn chế đối với kiểm

thử đột biến, từ đó giới thiệu một số kỹ thuật cải tiến nhằm khắc

phục những hạn chế trên.

Sử dụng hai công cụ mã nguồn mở miễn phí Nester để tạo - phân

tích đột biến, và NUnit để kiểm thử đơn vị và ứng dụng kiểm thử

đột biến đối với chương trình C#; cụ thể là sử dụng kỹ thuật đột

biến lựa chọn để kiểm thử chương trình cs – money với 21 trường

hợp kiểm đạt tỷ lệ xấp xỉ 90%.

Trong quá trình thực hiện luận văn cũng như trong thời gian trước

đó, tôi đã cố gắng tập trung nghiên cứu kỹ thuật kiểm thử này cũng

như đã tham khảo khá nhiều tài liệu liên quan. Tuy nhiên, do thời

gian và trình độ có hạn nên không tránh khỏi những hạn chế và

thiếu sót nhất định. Tôi thật sự mong muốn nhận được những góp ý

cả về chuyên môn lẫn cách trình bày của luận văn từ bạn đọc.

Page 78: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

78

HƯỚNG PHÁT TRIỂN Kiểm thử đột biến là một kỹ thuật kiểm thử được khá nhiều nhà nghiên

cứu quan tâm bởi tác dụng của nó. Tuy nhiên, trong luận văn này, vẫn còn tồn

tại nhiều vấn đề, trong thời gian tới, tôi cần phải tiếp tục nghiên cứu:

- Các vấn đề về phát hiện đột biến tương đương trong chương trình được

kiểm thử.

- Tìm hiểu thêm các phương pháp khác nhằm giảm chi phí tính toán và

tăng tính tự động hoá cho chương trình được kiểm thử.

- Đối với ứng dụng kỹ thuật kiểm thử đột biến để kiểm thử chương trình

cs - money, luận văn chỉ mới dừng lại ở mức độ đánh giá chất lượng 21

trường hợp kiểm thử đã được xây dựng ở trên, chưa cải tiến nó để đạt

tỷ lệ đột biến 100%. Do đó, trong thời gian tới, tôi sẽ tiếp tục nghiên

cứu để loại bỏ các đột biến tương đương trong số các đột biến còn sống

của chương trình này, đồng thời cải tiến các trường hợp kiểm thử để đạt

tỷ lệ đột biến 100%.

Cuối cùng, tôi hy vọng sau khi giải quyết xong những vấn đề còn tồn tại

nêu trên, tôi sẽ tiếp tục nghiên cứu kiểm thử đột biến để ứng dụng cho các

ngôn ngữ khác như: JAVA, SQL, ….Bởi vì, qua quá trình nghiên cứu kỹ

thuật kiểm thử đột biến, tôi thấy có rất nhiều công cụ hỗ trợ để thực hiện kiểm

thử đột biến cho các ngôn ngữ này.

Page 79: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

79

TÀI LIỆU THAM KHẢO

Tiếng Việt

[1] Nguyễn Xuân Huy (1994), Công nghệ phần mềm, Trường Đại học

Tổng hợp TP.HCM.

[2] Lê Văn Tường Lân (2004), Giáo trình công nghệ phần mềm, Trường

Đại học Khoa học Huế - Đại học Huế.

[3] Hồ Văn Phi (2008), Nghiên cứu và ứng dụng kiểm thử đột biến cho

các câu lệnh truy vấn SQL, Luận văn thạc sỹ kỹ thuật, chuyên ngành

khoa học máy tính, trường Đại học Bách Khoa - Đại học Đà Nẵng.

Tiếng Anh

[4] A.P. Mathur (1991), Performance, effectiveness and reliability issues

in software testing, Tokyo, Japan.

[5] A.J.Offutt and K.N.King, “A Fortran 77 interpreter for mutation

analysis”, in 1987 Symposium on Interpreters and Interpretive

Techniqes, pp. 177-188, ACM SIGPLAN, June 1987.

[6] A.J. Offutt and W.M. Craft, “Using compiler optimization techniques to

detect equivalent mutants,” The Journal of Softwave Testing,

Verification, and Reliability, vol.4, pp. 131-154, September 1994.

[7] A.T. Acree, T.A. Budd, R.A. DeMillo, R.J. Lipton, and F.G. Sayward,

“Mutation Analysis”, Georgia Institute of Technology, Technical

Report, GIT – ICS – 79/08, 1979.

[8] A.T.Acree, On Mutation, PhD thesis, Georgia Institute of Technology,

Atlanta GA, 1980.

[9] Jeff Offutt, Ammei Lee, Gregg Rothermel, Roland H. Untch, and

Christian Zapf (1996), An Experimental Determination of Sufficient

Mutant Operators, George Mason University.

[10] Jeff Offutt, Gregg Rothermel, Roland H. Untch, and Christian Zapf

Page 80: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

80

(1993), An Experimental Evaluation of Selective Mutation, Baltimore,

MD.

[11] K.S.H.T.Wah, “Fault coupling in finite bijecttive functions,” the

Journal of Softwave testing Verification, and Reliability, vol.5, pp.3-47,

March 1995.

[12] Mark Harman and Rob Hierons (2006), “An Overview of

Mutation Testing”, Genetic Algorithms for Mutation Testing, Brunel

University, London.

[13] R.A. DeMillo and A.J. Offutt (1993), Experimental results from an

automatic test case generator, ACM transactions on Softwar

Engineering Methodology, 2(2) pages 109-127.

[14] R.A. DeMillo, D.S. Guindi, K.N.King, W.M.Mc Cracken and

A.J.Offutt, “An extended overview of the Mothra Softwave testing

environment,” in Proceeding of the Second wrokshop on Softwave

Testing, Verification, and Anlysis, (Banff Alberta) pp. 142-151, IEEE

Computer Society Press, July 1988.

[15] R.Geist, A.J.Offutt, and F. Harris, “Estimation and endhancement of

real-time softwave reliability through mutation analysis,” IEEE

Transactions on Computers, vol.41, pp. 550-558, May 1992. Special

Issue on Fault – Tolerant Computing.

[16] R.Untch (1992), “Mutation-based software testing using program

schemata”, Proceedings of 30th ACM Southeast Regional Conference,

Raleigh, NC.

[17] R.J.Lipton and F.G. Sayward, “the status of reseach on program

mutation,” in Digest for the Workshop on Softwave Testing and Test

Documentation, pp. 355-373, December 1978.

[18] R. Untch, A.J. Offutt and M.J. Harold (1993), Mutation Analysis

using program schemate, pages 139-148, Cambridge, MA.

Page 81: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

81

[19] T.A. Budd (1980), Mutation Analysis of Program Test Data, Ph.D

Thesis, Yale University, New Haven CT.

[20] Nguyen Thanh Binh, C. Robach (2001), “Mutation Testing Applied

to Hardware: the Mutants Genenration”, Proceedings of the 11th

IFIP International Conference on Very Large Scale Integration,118--

123, Montpellier, France.

[21] W.E. Howden (1982), Weak mutation testing and completeness

of test sets, IEEE Transactions on Software Engineering, 8(4) pages

371-379.

[22] W.Wong, J.Maldonado, an M.Delamaro Peducing the cost of regression

test by using selective mutation. In 8 th CITS – International

Conference on Softwave Technology, pages 11 – 13, Curitiba, PR, June

1997.

[23] W.E.Wong, On Mutation and Data Flow. PhD thesis, Purduce

University, December 1993. (Also Technical Re-port SERC – TR – 149

– P, Softwave Engineering Research Center, Purduce University, West

Lafayetle.

[24] W.E.Wong, M.E. Delamaro, J.C. Maldonado, and A.p.Mathur,

“Constrained mutation in C program” in proceedings of the 8th

Brarilian Symposium on Softwave Engineering, (Curitiba, Brazil), pp.

439 – 452, October 1994.

[25] http://www.scribd.com

Page 82: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

82

PHỤ LỤC 1

Code Money.cs namespace NUnit.Samples.Money

{

using System;

using System.Text;

/// <summary>A simple Money.</summary>

class Money: IMoney {

private int fAmount;

private String fCurrency;

/// <summary>Constructs a money from the given amount and

/// currency.</summary>

public Money(int amount, String currency) {

fAmount= amount;

fCurrency= currency;

}

/// <summary>Adds a money to this money. Forwards the request to

/// the AddMoney helper.</summary>

public IMoney Add(IMoney m) {

return m.AddMoney(this);

}

public IMoney AddMoney(Money m) {

if (m.Currency.Equals(Currency) )

return new Money(Amount+m.Amount, Currency);

return new MoneyBag(this, m);

}

public IMoney AddMoneyBag(MoneyBag s) {

return s.AddMoney(this);

}

public int Amount {

get { return fAmount; }

}

public String Currency {

get { return fCurrency; }

}

public override bool Equals(Object anObject) {

if (IsZero)

if (anObject is IMoney)

Page 83: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

83

return ((IMoney)anObject).IsZero;

if (anObject is Money) {

Money aMoney= (Money)anObject;

return aMoney.Currency.Equals(Currency)

&& Amount == aMoney.Amount;

}

return false;

}

public override int GetHashCode() {

return fCurrency.GetHashCode()+fAmount;

}

public bool IsZero {

get { return Amount == 0; }

}

public IMoney Multiply(int factor) {

return new Money(Amount*factor, Currency);

}

public IMoney Negate() {

return new Money(-Amount, Currency);

}

public IMoney Subtract(IMoney m) {

return Add(m.Negate());

}

public override String ToString() {

StringBuilder buffer = new StringBuilder();

buffer.Append("["+Amount+" "+Currency+"]");

return buffer.ToString();

}

}

}

Page 84: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

84

PHỤ LỤC 2

Code Moneytest.cs namespace NUnit.Samples.Money.Port

{

using System;

using NUnit.Framework;

public class MoneyTest: TestCase

{

private Money f12CHF;

private Money f14CHF;

private Money f7USD;

private Money f21USD;

private MoneyBag fMB1;

private MoneyBag fMB2;

protected override void SetUp()

{

f12CHF= new Money(12, "CHF");

f14CHF= new Money(14, "CHF");

f7USD= new Money( 7, "USD");

f21USD= new Money(21, "USD");

fMB1= new MoneyBag(f12CHF, f7USD);

fMB2= new MoneyBag(f14CHF, f21USD);

}

public void TestBagMultiply()

{

// {[12 CHF][7 USD]} *2 == {[24 CHF][14 USD]}

Money[] bag = { new Money(24, "CHF"), new

Money(14, "USD") };

MoneyBag expected= new MoneyBag(bag);

Assertion.AssertEquals(expected,

fMB1.Multiply(2));

Assertion.AssertEquals(fMB1, fMB1.Multiply(1));

Assertion.Assert(fMB1.Multiply(0).IsZero);

}

public void TestBagNegate()

{

// {[12 CHF][7 USD]} negate == {[-12 CHF][-7 USD]}

Page 85: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

85

Money[] bag= { new Money(-12, "CHF"), new Money(-

7, "USD") };

MoneyBag expected= new MoneyBag(bag);

Assertion.AssertEquals(expected, fMB1.Negate());

}

public void TestBagSimpleAdd()

{

// {[12 CHF][7 USD]} + [14 CHF] == {[26 CHF][7

USD]}

Money[] bag= { new Money(26, "CHF"), new Money(7,

"USD") };

MoneyBag expected= new MoneyBag(bag);

Assertion.AssertEquals(expected,

fMB1.Add(f14CHF));

}

public void TestBagSubtract()

{

// {[12 CHF][7 USD]} - {[14 CHF][21 USD] == {[-2

CHF][-14 USD]}

Money[] bag= { new Money(-2, "CHF"), new Money(-

14, "USD") };

MoneyBag expected= new MoneyBag(bag);

Assertion.AssertEquals(expected,

fMB1.Subtract(fMB2));

}

public void TestBagSumAdd()

{

// {[12 CHF][7 USD]} + {[14 CHF][21 USD]} == {[26

CHF][28 USD]}

Money[] bag= { new Money(26, "CHF"), new Money(28,

"USD") };

MoneyBag expected= new MoneyBag(bag);

Assertion.AssertEquals(expected, fMB1.Add(fMB2));

}

public void TestIsZero()

{

Assertion.Assert(fMB1.Subtract(fMB1).IsZero);

Money[] bag = { new Money(0, "CHF"), new Money(0,

"USD") };

Page 86: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

86

Assertion.Assert(new MoneyBag(bag).IsZero);

}

public void TestMixedSimpleAdd()

{

// [12 CHF] + [7 USD] == {[12 CHF][7 USD]}

Money[] bag= { f12CHF, f7USD };

MoneyBag expected= new MoneyBag(bag);

Assertion.AssertEquals(expected,

f12CHF.Add(f7USD));

}

public void TestMoneyBagEquals()

{

Assertion.Assert(!fMB1.Equals(null));

Assertion.AssertEquals(fMB1, fMB1);

MoneyBag equal= new MoneyBag(new Money(12, "CHF"),

new Money(7, "USD"));

Assertion.Assert(fMB1.Equals(equal));

Assertion.Assert(!fMB1.Equals(f12CHF));

Assertion.Assert(!f12CHF.Equals(fMB1));

Assertion.Assert(!fMB1.Equals(fMB2));

}

public void TestMoneyBagHash()

{

MoneyBag equal= new MoneyBag(new Money(12, "CHF"),

new Money(7, "USD"));

Assertion.AssertEquals(fMB1.GetHashCode(),

equal.GetHashCode());

}

public void TestMoneyEquals()

{

Assertion.Assert(!f12CHF.Equals(null));

Money equalMoney= new Money(12, "CHF");

Assertion.AssertEquals(f12CHF, f12CHF);

Assertion.AssertEquals(f12CHF, equalMoney);

Assertion.AssertEquals(f12CHF.GetHashCode(),

equalMoney.GetHashCode());

Assertion.Assert(!f12CHF.Equals(f14CHF));

}

public void TestMoneyHash()

Page 87: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

87

{

Assertion.Assert(!f12CHF.Equals(null));

Money equal= new Money(12, "CHF");

Assertion.AssertEquals(f12CHF.GetHashCode(),

equal.GetHashCode());

}

public void TestNormalize()

{

Money[] bag= { new Money(26, "CHF"), new Money(28,

"CHF"), new Money(6, "CHF") };

MoneyBag moneyBag= new MoneyBag(bag);

Money[] expected = { new Money(60, "CHF") };

// note: expected is still a MoneyBag

MoneyBag expectedBag= new MoneyBag(expected);

Assertion.AssertEquals(expectedBag, moneyBag);

}

public void TestNormalize2()

{

// {[12 CHF][7 USD]} - [12 CHF] == [7 USD]

Money expected= new Money(7, "USD");

Assertion.AssertEquals(expected,

fMB1.Subtract(f12CHF));

}

public void TestNormalize3()

{

// {[12 CHF][7 USD]} - {[12 CHF][3 USD]} == [4

USD]

Money[] s1 = { new Money(12, "CHF"), new Money(3,

"USD") };

MoneyBag ms1= new MoneyBag(s1);

Money expected= new Money(4, "USD");

Assertion.AssertEquals(expected,

fMB1.Subtract(ms1));

}

public void TestNormalize4()

{

// [12 CHF] - {[12 CHF][3 USD]} == [-3 USD]

Money[] s1 = { new Money(12, "CHF"), new Money(3,

"USD") };

MoneyBag ms1= new MoneyBag(s1);

Page 88: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

88

Money expected= new Money(-3, "USD");

Assertion.AssertEquals(expected,

f12CHF.Subtract(ms1));

}

public void TestPrint()

{

Assertion.AssertEquals("[12 CHF]",

f12CHF.ToString());

}

public void TestSimpleAdd()

{

// [12 CHF] + [14 CHF] == [26 CHF]

Money expected= new Money(26, "CHF");

Assertion.AssertEquals(expected,

f12CHF.Add(f14CHF));

}

public void TestSimpleBagAdd()

{

// [14 CHF] + {[12 CHF][7 USD]} == {[26 CHF][7

USD]}

Money[] bag= { new Money(26, "CHF"), new Money(7,

"USD") };

MoneyBag expected= new MoneyBag(bag);

Assertion.AssertEquals(expected,

f14CHF.Add(fMB1));

}

public void TestSimpleMultiply()

{

// [14 CHF] *2 == [28 CHF]

Money expected= new Money(28, "CHF");

Assertion.AssertEquals(expected,

f14CHF.Multiply(2));

}

public void TestSimpleNegate()

{

// [14 CHF] negate == [-14 CHF]

Money expected= new Money(-14, "CHF");

Assertion.AssertEquals(expected, f14CHF.Negate());

}

public void TestSimpleSubtract()

Page 89: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

89

{

// [14 CHF] - [12 CHF] == [2 CHF]

Money expected= new Money(2, "CHF");

Assertion.AssertEquals(expected,

f14CHF.Subtract(f12CHF));

}

}

}

Page 90: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

90

PHỤ LỤC 3

Code MoneyBag.cs namespace NUnit.Samples.Money

{

using System;

using System.Collections;

using System.Text;

/// <summary>A MoneyBag defers exchange rate conversions.</summary>

/// <remarks>For example adding

/// 12 Swiss Francs to 14 US Dollars is represented as a bag

/// containing the two Monies 12 CHF and 14 USD. Adding another

/// 10 Swiss francs gives a bag with 22 CHF and 14 USD. Due to

/// the deferred exchange rate conversion we can later value a

/// MoneyBag with different exchange rates.

/// A MoneyBag is represented as a list of Monies and provides

/// different constructors to create a MoneyBag.</remarks>

class MoneyBag: IMoney {

private ArrayList fMonies= new ArrayList(5);

private MoneyBag() {

}

public MoneyBag(Money[] bag) {

for (int i= 0; i < bag.Length; i++) {

if (!bag[i].IsZero)

AppendMoney(bag[i]);

}

}

public MoneyBag(Money m1, Money m2) {

AppendMoney(m1);

AppendMoney(m2);

}

public MoneyBag(Money m, MoneyBag bag) {

AppendMoney(m);

AppendBag(bag);

}

public MoneyBag(MoneyBag m1, MoneyBag m2) {

AppendBag(m1);

AppendBag(m2);

}

Page 91: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

91

public IMoney Add(IMoney m) {

return m.AddMoneyBag(this);

}

public IMoney AddMoney(Money m) {

return (new MoneyBag(m, this)).Simplify();

}

public IMoney AddMoneyBag(MoneyBag s) {

return (new MoneyBag(s, this)).Simplify();

}

private void AppendBag(MoneyBag aBag) {

foreach (Money m in aBag.fMonies)

AppendMoney(m);

}

private void AppendMoney(Money aMoney) {

IMoney old= FindMoney(aMoney.Currency);

if (old == null) {

fMonies.Add(aMoney);

return;

}

fMonies.Remove(old);

IMoney sum= old.Add(aMoney);

if (sum.IsZero)

return;

fMonies.Add(sum);

}

private bool Contains(Money aMoney) {

Money m= FindMoney(aMoney.Currency);

return m.Amount == aMoney.Amount;

}

public override bool Equals(Object anObject) {

if (IsZero)

if (anObject is IMoney)

return ((IMoney)anObject).IsZero;

if (anObject is MoneyBag) {

MoneyBag aMoneyBag= (MoneyBag)anObject;

if (aMoneyBag.fMonies.Count != fMonies.Count)

return false;

foreach (Money m in fMonies) {

if (!aMoneyBag.Contains(m))

return false;

Page 92: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

92

}

return true;

}

return false;

}

private Money FindMoney(String currency) {

foreach (Money m in fMonies) {

if (m.Currency.Equals(currency))

return m;

}

return null;

}

public override int GetHashCode() {

int hash= 0;

foreach (Money m in fMonies) {

hash^= m.GetHashCode();

}

return hash;

}

public bool IsZero {

get { return fMonies.Count == 0; }

}

public IMoney Multiply(int factor) {

MoneyBag result= new MoneyBag();

if (factor != 0) {

foreach (Money m in fMonies) {

result.AppendMoney((Money)m.Multiply(factor));

}

}

return result;

}

public IMoney Negate() {

MoneyBag result= new MoneyBag();

foreach (Money m in fMonies) {

result.AppendMoney((Money)m.Negate());

}

return result;

}

private IMoney Simplify() {

Page 93: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

93

if (fMonies.Count == 1)

return (IMoney)fMonies[0];

return this;

}

public IMoney Subtract(IMoney m) {

return Add(m.Negate());

}

public override String ToString() {

StringBuilder buffer = new StringBuilder();

buffer.Append("{");

foreach (Money m in fMonies)

buffer.Append(m);

buffer.Append("}");

return buffer.ToString();

}

}

}

Page 94: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

94

PHỤ LỤC 4

Code Imoney.cs namespace NUnit.Samples.Money

{

/// <summary>The common interface for simple Monies and

MoneyBags.</summary>

interface IMoney {

/// <summary>Adds a money to this money.</summary>

IMoney Add(IMoney m);

/// <summary>Adds a simple Money to this money. This is a helper

method for

/// implementing double dispatch.</summary>

IMoney AddMoney(Money m);

/// <summary>Adds a MoneyBag to this money. This is a helper method

for

/// implementing double dispatch.</summary>

IMoney AddMoneyBag(MoneyBag s);

/// <value>True if this money is zero.</value>

bool IsZero { get; }

/// <summary>Multiplies a money by the given factor.</summary>

IMoney Multiply(int factor);

/// <summary>Negates this money.</summary>

IMoney Negate();

/// <summary>Subtracts a money from this money.</summary>

IMoney Subtract(IMoney m);

}

}

Page 95: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

95

PHỤ LỤC 5

Code Assemblyinfo.cs using System.Reflection;

using System.Runtime.CompilerServices;

//

// General Information about an assembly is controlled through the

following

// set of attributes. Change these attribute values to modify the

information

// associated with an assembly.

//

[assembly: AssemblyTitle("")]

[assembly: AssemblyDescription("")]

[assembly: AssemblyConfiguration("")]

[assembly: AssemblyCompany("")]

[assembly: AssemblyProduct("")]

[assembly: AssemblyCopyright("")]

[assembly: AssemblyTrademark("")]

[assembly: AssemblyCulture("")]

//

// Version information for an assembly consists of the following four

values:

//

// Major Version

// Minor Version

// Build Number

// Revision

//

// You can specify all the values or you can default the Revision and

Build Numbers

// by using the '*' as shown below:

[assembly: AssemblyVersion("2.2.0.0")]

//

// In order to sign your assembly you must specify a key to use. Refer to

the

// Microsoft .NET Framework documentation for more information on

assembly signing.

//

Page 96: LỜI CẢM ƠN - hus.vnu.edu.vn (273).pdf · niệm kiểm thử phần mềm, mục đích, mục tiêu và các mức kiểm thử phần mềm. Chương này cũng đề cập

96

// Use the attributes below to control which key is used for signing.

//

// Notes:

// (*) If no key is specified, the assembly is not signed.

// (*) KeyName refers to a key that has been installed in the Crypto

Service

// Provider (CSP) on your machine. KeyFile refers to a file which

contains

// a key.

// (*) If the KeyFile and the KeyName values are both specified, the

// following processing occurs:

// (1) If the KeyName can be found in the CSP, that key is used.

// (2) If the KeyName does not exist and the KeyFile does exist,

the key

// in the KeyFile is installed into the CSP and used.

// (*) In order to create a KeyFile, you can use the sn.exe (Strong

Name) utility.

// When specifying the KeyFile, the location of the KeyFile should

be

// relative to the project output directory which is

// %Project Directory%\obj\<configuration>. For example, if your

KeyFile is

// located in the project directory, you would specify the

AssemblyKeyFile

// attribute as [assembly: AssemblyKeyFile("..\\..\\mykey.snk")]

// (*) Delay Signing is an advanced option - see the Microsoft .NET

Framework

// documentation for more information on this.

//

[assembly: AssemblyDelaySign(false)]

[assembly: AssemblyKeyFile("")]

[assembly: AssemblyKeyName("")]