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

(Luận văn thạc sĩ) kiểm thử tích hợp với độ phức tạp tương đương kiểm thử thành phần

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

4
MỤC LỤC
CHƯƠNG 1 – GIỚI THIỆU ················································································ 1
1.1. Mục tiêu nghiên cứu ·················································································· 1
1.2. Ý tưởng giải quyết bài toán········································································ 2
1.3. Cấu trúc luận văn······················································································· 3
CHƯƠNG 2 – KIẾN THỨC NỀN TẢNG···························································· 5
2.1. Kiểm thử đơn vị························································································· 5
2.2. Phân tích tĩnh····························································································· 5
2.3. Kiểm thử luồng điều khiển ········································································ 6
2.4. Kiểm thử luồng dữ liệu·············································································· 9
2.4.1. Kiểm thử định nghĩa – sử dụng (Define/Use Testing) ························· 10
2.4.2. Kiểm thử dựa trên lát cắt (Slice-based testing)···································· 11
CHƯƠNG 3 – KỸ THUẬT KIỂM THỬ SINH MÔI TRƯỜNG ························· 14
3.1. Chọn chức năng cần kiểm thử và xác định đơn vị······································ 14
3.2. Xác định giao diện đơn vị - môi trường ····················································· 14
3.3. Kiểm thử···································································································· 19
CHƯƠNG 4 - ỨNG DỤNG ················································································· 20
4.1. Giới thiệu phần mềm TestSystem ······························································ 20
4.2. Kiểm thử chức năng đăng nhập của phần mềm TestSystem······················· 21
4.2.1. Xác định đơn vị ·················································································· 21
4.2.2. Xác định giao diện đơn vị - môi trường ·············································· 21
4.2.3. Kiểm thử chức năng đăng nhập··························································· 22
4.2.4. Báo cáo kết quả kiểm thử···································································· 36
CHƯƠNG 5 – KẾT LUẬN ·················································································· 38
TÀI LIỆU THAM KHẢO ···················································································· 40
PHỤ LỤC ············································································································ 41
Phụ lục 1 – Mã lớp TestLogin ·········································································· 41


5


DANH SÁCH CÁC HÌNH VẼ
Hình 1.1. Tạo mơi trường cho đơn vị ·································································· 2
Hình 2.1. Các thành phần cơ bản của đồ thị luồng điều khiển ····························· 7
Hình 2.2. Các cấu trúc điều khiển phổ dụng ························································ 7
Hình 3.1. Minh họa thuật tốn giao diện đơn vị···················································· 16
Hình 3.2. Minh họa thuật tốn xác định giao diện mơi trường ······························ 18
Hình 4.1. Đồ thị luồng điều khiển lớp Login ························································ 27
Hình 4.2. Mã phương thức GetStudent································································· 31
Hình 4.3. Đồ thị luồng điều khiển phương thức GetStudent ································· 31
Hình 4.4. Mã phương thức GetDataTeacher ························································· 33
Hình 4.5. Mã phương thức SetPresenceStudent···················································· 34
Hình 4.6. Đồ thị luồng điều khiển phương thức SetPresenceStudent ···················· 34
Hình 4.7. Kiểm thử chức năng đăng nhập của TestSystem ··································· 37
Hình 4.8. Giao diện trang chủ của phần mềm TestSystem ···································· 37


6
DANH SÁCH CÁC BẢNG
Bảng 4.1. Các nút định nghĩa, sử dụng của các biến············································· 25
Bảng 4.2. Các trường hợp kiểm thử của biến nTypeUser ····································· 26
Bảng 4.3. Các trường hợp kiểm thử của biến nIDStudent····································· 27
Bảng 4.4. Các trường hợp kiểm thử của biến nIDTeacher ···································· 28
Bảng 4.5. Các trường hợp kiểm thử của biến countTeacher·································· 28
Bảng 4.6. Các trường hợp kiểm thử của biến countStudent ·································· 29
Bảng 4.7. Các trường hợp kiểm thử của biến countAdmin ··································· 29
Bảng 4.8. Các trường hợp kiểm thử của biến countAnonymous ··························· 30
Bảng 4.9. Các trường hợp kiểm thử của phương thức GetStudent ························ 32
Bảng 4.10. Các trường hợp kiểm thử của phương thức GetDataTeacher ·············· 33
Bảng 4.11. Các trường hợp kiểm thử của phương thức SetPresenceStudent ········· 35
Bảng 4.12. Các trường hợp kiểm thử của phương thức SetPresenceTeacher ········ 35



7

CHƯƠNG 1 - GIỚI THIỆU
1.1. Mục tiêu nghiên cứu
Với những chương trình có kích thước nhỏ và chức năng đơn giản, ta dễ dàng
tiến hành kiểm thử bằng kỹ thuật kiểm thử đơn vị. Kiểm thử đơn vị có thể được
lập trình viên thực hiện, có độ phức tạp nhỏ và tốn ít chi phí. Với sự phát triển
của ứng dụng công nghệ thông tin, hiện nay, những phần mềm thường lớn và
chứa nhiều lớp. Các lớp có thể được thực thi độc lập, sau đó được tích hợp lại
thành một hệ thống như mong muốn. Để kiểm thử một chức năng trên hệ thống,
người ta thường sử dụng kỹ thuật kiểm thử tích hợp.
Việc kiểm thử tích hợp một chức năng trên tồn hệ thống thường có độ
phức tạp cao, địi hỏi kiểm thử trên một khơng gian kiểm thử lớn. Để làm giảm
khơng gian cần kiểm thử, có thể tiếp cận theo hướng mơ-đun hóa bằng cách chia
phần mềm thành hai phần: đơn vị (unit) và môi trường. Đơn vị bao gồm tập hợp
một số lớp liên quan đến chức năng cần kiểm thử, môi trường là tập hợp các lớp
mà đơn vị tương tác với. Các tương tác này xẩy ra tại giao diện đơn vị – mơi
trường. Đơn vị có thể tác động một số hành vi lên mơi trường và ngược lại, mơi
trường cũng có thể tác động một số hành vi lên đơn vị. Sự tương tác giữa đơn vị
và mơi trường có thể là những hành vi về điều khiển, như gọi đến một thuộc tính
hay một phương thức; hoặc có thể là những hành vi về dữ liệu, như thay đổi giá
trị của một thuộc tính. Tất cả những thuộc tính và những phương thức thể hiện
hành vi của đơn vị và môi trường tạo nên giao diện đơn vị – môi trường.
Với mỗi đơn vị cần kiểm thử, việc tạo ra môi trường là một công việc quan
trọng. Môi trường được chia thành hai phần là driver và stub. Driver bao gồm
các lớp gọi đến các thuộc tính hay các phương thức của đơn vị, còn stub là các
lớp mà đơn vị gọi đến. Như vậy, driver thể hiện những hành vi mà mơi trường
tác động lên đơn vị, cịn stub thể hiện những hành vi mà đơn vị tác động đến

môi trường.
Với việc định nghĩa các khái niệm như trên, có thể tổng qt hóa q trình
tạo ra mơi trường cho đơn vị như hình 1.1. Tồn bộ phần mềm được thể hiện ở
bên trái mũi tên. Phần mềm gồm nhiều lớp. Mỗi lớp được minh họa bởi hình
chữ nhật có các dịng kẻ ngang bên trong. Đơn vị cần kiểm thử được bao quanh
bởi đường viền chấm. Các đường mũi tên nối giữa các lớp, thể hiện quan hệ
giữa các lớp với nhau. Những đường mũi tên nối trực tiếp với đường bao quanh
đơn vị thể hiện tương tác giữa đơn vị và môi trường. Từ những thông tin trên, ta


8
cần xác định driver và stub cho đơn vị. Phần bên phải mũi tên thể hiện mối
quan hệ giữa đơn vị, driver và stub.

Tạo mơi trường

Driver

Mã chương trình
Stub

Hình 1.1. Tạo môi trường cho đơn vị [1].
Sau khi tạo ra môi trường cho đơn vị, để đảm bảo đơn vị được kiểm thử
trên toàn bộ hệ thống, cần đặt đơn vị vào mối quan hệ với môi trường và kiểm
thử đơn vị trong tổng thể mối quan hệ đơn vị – mơi trường đó. Với một phạm vi
khơng lớn, để tiến hành kiểm thử các tính chất của đơn vị, hồn tồn có thể sử
dụng các kỹ thuật kiểm thử đơn vị như kiểm thử luồng điều khiển, kiểm thử
luồng dữ liệu.
Kết quả, chỉ cần sử dụng các kỹ thuật kiểm thử đơn vị, có thể kiểm thử một
chức năng trên tồn bộ hệ thống mà khơng cần sử dụng kỹ thuật kiểm thử tích

hợp. Nghiên cứu này có ý nghĩa rất lớn trong việc kiểm thử những hệ thống
phức tạp, làm đơn giản và tăng hiệu quả kiểm thử.
Trong luận văn, kiểm thử thành phần hay kiểm thử đơn vị được tiến hành
trên từng lớp, kiểm thử tích hợp là kiểm thử tích hợp giữa đơn vị và mơi trường.
1.2. Ý tưởng giải quyết bài tốn
Để làm được cơng việc nêu trong mục 1.1, với mỗi chức năng cần kiểm thử của
phần mềm, lần lượt làm các bước sau:


9
Bước thứ nhất - Xác định đơn vị: Sử dụng kỹ thuật phân tích tĩnh, cùng các
tài liệu đặc tả, thiết kế, mã chương trình, xác định những lớp quyết định trực tiếp
đến chức năng cần kiểm thử. Tập hợp các lớp đó gọi là đơn vị.
Bước thứ hai - Xác định giao diện đơn vị – môi trường: giao diện đơn vị –
môi trường bao gồm hai phần: giao diện đơn vị và giao diện môi trường. Giao
diện đơn vị bao gồm các thuộc tính, phương thức của đơn vị mà môi trường
tham chiếu đến. Giao diện đơn vị thể hiện các hành vi của môi trường tác động
lên đơn vị. Ngược lại, giao diện môi trường bao gồm các thuộc tính, phương
thức của các lớp trong mơi trường mà đơn vị tham chiếu đến. Giao diện môi
trường thể hiện các hành vi của đơn vị tác động lên môi trường.
Bước cuối cùng – Kiểm thử: sau khi xác định giao diện đơn vị - môi trường,
tất cả các phương thức và các thuộc tính liên quan trực tiếp đến các hành vi mà
đơn vị và môi trường tác động qua lại lên nhau đã được chỉ rõ. Sử dụng các kỹ
thuật kiểm thử đơn vị như kiểm thử luồng điều khiển, kiểm thử luồng dữ liệu,
tiến hành kiểm thử các thuộc tính và các phương thức trên. Kết quả chính xác
của các thuộc tính và các phương thức đó đảm bảo chức năng ban đầu cần kiểm
thử sẽ hoạt động đúng trên toàn hệ thống.
Như vậy, với việc sử dụng kỹ thuật kiểm thử đơn vị, ta đã kiểm thử được
chức năng cần kiểm thử trên toàn bộ hệ thống mà không cần sử dụng kỹ thuật
kiểm thử tích hợp. Trong luận văn này, ta gọi kỹ thuật kiểm thử được trình bày ở

trên là kỹ thuật kiểm thử sinh mơi trường.
1.3. Cấu trúc luận văn
Để trình bầy cụ thể các kiến thức, giúp người đọc tiếp cận phương pháp kiểm
thử sinh môi trường nêu trên, nội dung của luận văn được tập trung vào ba
chương.
Những kiến thức nền tảng về kiểm thử được trình bày trong chương 2 Kiến thức nền tảng. Đó là những kiến thức về kiểm thử đơn vị, phân tích tĩnh,
các kỹ thuật kiểm thử đơn vị bao gồm kiểm thử luồng điều khiển và kiểm thử
luồng dữ liệu. Những kiến thức này hỗ trợ người đọc trong việc tiếp cận và hiểu
vấn đề mà luận văn nghiên cứu.
Lý thuyết chính của luận văn được đề cập ở chương 3 – Kiểm thử sinh mơi
trường. Chương 3 trình bày cơ sở lý thuyết và các thuật toán được sử dụng trong
kỹ thuật kiểm thử sinh môi trường. Kỹ thuật bao gồm các bước: xác định đơn vị,
xác định giao diện đơn vị - môi trường, áp dụng kỹ thuật kiểm thử đơn vị để
kiểm thử chức năng cần kiểm thử.


10
Việc áp dụng kỹ thuật kiểm thử sinh môi trường với một ví dụ cụ thể được
trình bầy trong chương 4 - Ứng dụng. Chương 4 giới thiệu khái quát về phần
mềm kiểm tra trực tuyến - TestSystem. Sau đó trình bày từng bước áp dụng kỹ
thuật kiểm thử sinh môi trường để kiểm thử chức năng đăng nhập (login) trong
hệ thống TestSystem.


11
CHƯƠNG 2 - KIẾN THỨC NỀN TẢNG
2.1. Kiểm thử đơn vị
Kiểm thử đơn vị là kỹ thuật kiểm thử trên một đơn vị của chương trình. Đơn vị
đó được kiểm thử trong sự cơ lập với tồn bộ chương trình. Người ta thường
hiểu với nghĩa rằng, một đơn vị là một hàm, một thủ tục, một phương thức hay

một lớp [1].
Với định nghĩa như trên, ta thấy rằng đơn vị có kích thước nhỏ, lập trình
viên tạo ra đơn vị để đảm bảo một chức năng nhỏ nào đó cho hệ thống. Vì vậy
việc kiểm thử đơn vị thường dễ dàng tiến hành. Với phạm vi cần kiểm thử
không lớn, nếu phát hiện ra lỗi trong quá trình kiểm thử thì cũng dễ dàng tìm ra
nguyên nhân và khắc phục lỗi. Việc tiến hành kiểm thử đơn vị đòi hỏi người
kiểm thử phải hiểu cặn kẽ về mã chương trình nên quá trình kiểm thử đơn vị
thường được thực hiện bởi chính lập trình viên viết chương trình đó.
Kiểm thử đơn vị là mức kiểm thử thấp nhất nhưng nó có ý nghĩa rất quan
trọng. Việc đảm bảo các đơn vị chạy chính xác sẽ làm giảm thời gian và chi phí
rất nhiều cho các mức kiểm thử cao hơn về sau. Quá trình kiểm thử đơn vị nên
được tiến hành sớm nhất có thể ngay trong giai đoạn viết mã và cần được thực
hiện thường xuyên và xuyên suốt cả chu kỳ phát triển phần mềm.
Mục đích của kiểm thử đơn vị là đảm bảo với một dữ liệu đầu vào, đơn vị
phải cho ra kết quả chính xác. Việc kiểm thử đòi hỏi chúng ta phải kiểm tra tất
cả các đường thi hành trong đơn vị để phát hiện đường phát sinh lỗi. Để tiến
hành kiểm thử, đòi hỏi phải có một bộ các ca kiểm thử hoặc kịch bản kiểm thử
chỉ rõ dữ liệu đầu vào và đầu ra mong muốn. Trong quá trình kiểm thử, với mỗi
dữ liệu đầu vào, ta so sánh dữ liệu đầu ra thực, so sánh nó với đầu ra mong
muốn để viết báo cáo kiểm thử [6].
Kiểm thử đơn vị bao gồm hai hướng: Kiểm thử tĩnh và kiểm thử động.
Trong đó, kiểm thử tĩnh là kiểm thử dựa trên phân tích tất cả các hành vi có thể
xẩy ra khi chạy chương trình mà khơng chạy chương trình thực sự. Còn kiểm
thử động là kiểm thử dựa trên việc chạy chương trình và phân tích kết quả đầu ra.
2.2. Phân tích tĩnh
Phân tích tĩnh là một kỹ thuật địi hỏi duyệt lại các tài liệu về yêu cầu, đặc tả,
thiết kế và mã chương trình để kiểm tra tính logic của chương trình, mà khơng
chạy chương trình [1].



12
Người ta thường ứng dụng phân tích tĩnh trong việc tối ưu mã hoặc kiểm
thử chương trình. Ví dụ như ứng dụng để loại bỏ các đoạn mã dư thừa, sử dụng
tài nguyên tối ưu, phát hiện các lỗi tiềm năng,… Phân tích tĩnh được ứng dụng
trong kiểm thử, đảm bảo thơng tin nó thu thập được cần phải đúng với tất cả các
đường thi hành chương trình và với các đầu vào có thể [3].
Trong kiểm thử, phân tích tĩnh thường được dùng như kỹ thuật bổ xung cho
các kỹ thuật kiểm thử truyền thống và kiểm tra mô hình. Do sự khơng chính xác
của phân tích, phân tích tĩnh ít chính xác hơn, nhưng nói chung có khả năng mở
rộng tốt hơn kiểm tra mơ hình. Có một số phương pháp tiếp cận phân tích tĩnh,
trong đó có Phân tích lưu lượng dữ liệu và Diễn giải tóm tắt. Những phương
pháp tiếp cận như vậy đòi hỏi người thiết kế phân tích phải quyết định trên một
trạng thái cân bằng chi phí và độ chính xác: các phân tích càng chính xác, chi
phí càng tốn kém [4].
2.3. Kiểm thử luồng điều khiển
Kiểm thử luồng điều khiển là một kỹ thuật kiểm thử đơn vị do Tom McCabe đề
xuất. Để tiếp cận với kiểm thử luồng điều khiển, ta cần làm quen với các khái
niệm được trích dẫn trong tài liệu [2] được đề cập sau đây.
Định nghĩa 1
Đường thi hành (execution path) được định nghĩa là một danh sách có thứ
tự các lệnh trong chương trình được thực thi trong 1 lần chạy, bắt đầu từ điểm
nhập đến điểm kết thúc của đơn vị.
Định nghĩa 2
Đồ thị luồng điều khiển là một cơng cụ hữu ích để hiển thị luồng điều khiển
trong chương trình. Trong đó các nút hình trịn biểu thị các đoạn câu lệnh trong
chương trình, các cung biểu thị luồng điều khiển.
Các thành phần cơ bản của đồ thị luồng điều khiển được biểu diễn trong
hình 2.1. Các nút trịn màu trắng biểu thị các đoạn câu lệnh, các nút hình bầu
dục màu đen biểu thị điểm bắt đầu hoặc điểm kết thúc chương trình. Các mũi tên
đi đến và đi ra khỏi nút biểu thị luồng điều khiển của chương trình tại nút đó.

Điểm xuất phát khơng có luồng đi đến và chỉ có một luồng đi ra. Điểm kết thúc
khơng có luồng đi ra. Khối xử lý bình thường có một luồng đi đến và một luồng
đi ra. Tại điểm quyết định sẽ có nhiều nhánh rẽ ra từ nó. Ngược lại, điểm nối có
nhiều luồng đi đến và một luồng đi ra.


13

điểm xuất phát

khối xử lý điểm quyết định

điểm nối

điểm kết thúc

Hình 2.1. Các thành phần cơ bản của đồ thị luồng điều khiển [2].
Các cấu trúc điều khiển phổ dụng của đồ thị luồng điều khiển được minh
họa trong hình 2.2. Với cấu trúc tuần tự, tại mỗi điểm của đồ thị sẽ có một luồng
đi đến và một luồng đi ra. Khác với cấu trúc if, tại điểm quyết định chỉ có hai
luồng đi ra, tại điểm quyết định của cấu trúc switch có thể có ba hay nhiều hơn
ba luồng đi ra. Trong cấu trúc lặp, điểm quyết định được biểu diễn là điểm có
hai luồng rẽ nhánh ra từ nó. Với cấu trúc lặp while…do, điểm quyết định được
đặt trước thân vịng lặp, nếu điều kiện khơng thỏa mãn, sẽ thốt ra khỏi vịng lặp.
Ngược lại, trong cấu trúc do…while, điểm quyết định được đặt sau thân vịng
lặp, thực hiện thân vịng lặp, sau đó kiểm tra điều kiện, điều kiện đúng thì quay
lại thực hiện thân vòng lặp. Lặp lại cho đến khi điều kiện sai thì thốt khỏi vịng
lặp.

switch


while c do...

do ... while c

Hình 2.2. Các cấu trúc điều khiển phổ dụng [2].
Định nghĩa 3
Độ phức tạp Cyclomatic C được định nghĩa là một thước đo phần mềm, đo
độ phức tạp của chương trình. Trong ngữ cảnh kiểm thử luồng điều khiển, độ
phức tạp cyclomatic cho biết số đường thi hành tuyến tính độc lập cơ bản của
chương trình cần kiểm thử.
Độ phức tạp Cyclomatic C = V(G) của đồ thị dòng điều khiển được tính bởi
một trong các cơng thức sau :
o V(G) = E - N + 2, trong đó E là số cung, N là số nút của đồ thị.
o V(G) = P + 1, nếu đồ thị chỉ chứa các nút quyết định luận lý (chỉ có 2
cung xuất đúng/sai) và P là số nút quyết định.
Để xác định C đường tuyến tính độc lập, Tom McCabe đưa ra qui trình
gồm các bước sau:


14
o Xác định đường cơ bản, đường này nên là đường thi hành phố biến nhất.
o Để chọn đường thứ 2, thay đổi cung xuất của nút quyết định đầu tiên và
cố gắng giữ lại tối đa phần còn lại.
o Để chọn đường thứ 3, dùng đường cơ bản nhưng thay đổi cung xuất của
nút quyết định thứ 2 và cố gắng giữ lại tối đa phần còn lại.
o Tiếp tục thay đổi cung xuất cho từng nút quyết định trên đường cơ bản
để xác định đường thứ 4, 5,... cho đến khi khơng cịn nút quyết định nào
trong đường cơ bản nữa.
o Lặp dùng tuần tự các đường tìm được làm đường cơ bản để xác định các

đường mới xung quanh nó y như các bước 2, 3, 4 cho đến khi khơng tìm
được đường tuyến tính độc lập nào nữa.
Mục tiêu của phương pháp kiểm thử luồng điều khiển là đảm bảo mọi
đường thi hành của đơn vị phần mềm cần kiểm thử đều chạy đúng. Nhưng trên
thực tế, công sức và thời gian để đạt mục tiêu trên đây là rất lớn, ngay cả trên
những đơn vị phần mềm nhỏ bởi có những chương trình có một số lượng quá
lớn các đường thi hành hoặc khi chương trình được lập trình khơng tốt, bỏ sót
một số đường thi hành. Vì vậy, mục tiêu của kiểm thử là sử dụng tối thiểu các ca
kiểm thử để kiểm thử mà có thể đem lại kết quả độ tin cậy tối đa [2] . Để xác
định độ tin cậy của kết quả, sử dụng khái niệm phủ kiểm thử (Coverage).
Định nghĩa 4
Phủ kiểm thử là tỉ lệ các thành phần thực sự được kiểm thử so với tổng thể
sau khi đã kiểm thử các ca kiểm thử được chọn. Phủ càng lớn thì độ tin cậy càng
cao.
o Phủ cấp 0: kiểm thử những gì có thể kiểm thử được, phần còn lại để
người dùng phát hiện và báo lại sau. Đây là mức độ kiểm thử khơng
thực sự có trách nhiệm.
o Phủ cấp 1: kiểm thử sao cho mỗi lệnh được thực thi ít nhất 1 lần, gọi là
mức kiểm thử phủ các lệnh.
o Phủ cấp 2: kiểm thử sao cho mỗi điểm quyết định đều được thực hiện ít
nhất 1 lần cho trường hợp đúng lẫn sai. Ta gọi mức kiểm thử này là phủ
các nhánh (branch coverage). Phủ các nhánh đảm bảo phủ các lệnh.
o Phủ cấp 3: kiểm thử sao cho mỗi điều kiện luận lý con (subcondition)
của từng điểm quyết định đều được thực hiện ít nhất 1 lần cho trường
hợp đúng lẫn sai. Ta gọi mức kiểm thử này là phủ các điều kiện con


15
(subcondition coverage). Phủ các điều kiện con chưa chắc đảm bảo phủ
các nhánh.

o Phủ cấp 4: kiểm thử sao cho mỗi điều kiện luận lý con (subcondition)
của từng điểm quyết định đều được thực hiện ít nhất 1 lần cho trường
hợp đúng lẫn sai và điểm quyết định cũng được kiểm thử cho cả 2
nhánh. Ta gọi mức kiểm thử này là phủ các nhánh và điều kiện con
(branch & subcondition coverage).
Vậy để kiểm thử luồng điều khiển một đơn vị, lần lượt tiến hành các bước
sau:
o Xác định phủ kiểm thử
o Xây dựng đồ thị luồng điều khiển dựa trên phủ kiểm thử
o Tính độ phức tạp Cyclomatic của đồ thị (=C).
o Xác định C đường thi hành tuyến tính cơ bản cần kiểm thử.
o Tạo từng ca kiểm thử cho từng đường thi hành tuyến tính cơ bản.
o Thực hiện kiểm thử trên từng ca kiểm thử
o So sánh kết quả có được với kết quả được kỳ vọng.
o Lập báo cáo kết quả kiểm thử
2.4. Kiểm thử luồng dữ liệu
Kiểm thử luồng dữ liệu là một thuật ngữ mà hầu hết các nhà phát triển phần
mềm khi đọc nó, ngay lập tức nghĩ sẽ liên quan đến sơ đồ dòng dữ liệu. Kiểm
thử luồng dữ liệu đề cập đến các hình thức của kiểm thử cấu trúc, nó tập trung
vào các điểm mà tại đó các biến nhận giá trị hoặc giá trị của biến được sử dụng.
Chúng ta sẽ xem sét 2 hình thức chính của kiểm thử luồng dữ liệu, một là kiểm
thử theo định nghĩa – sử dụng và dạng hai được dựa trên khái niệm được gọi là
“lát cắt chương trình” (program slide), gọi là kiểm thử dựa trên lát cắt [5].
Hầu hết các chương trình phân phối các chức năng theo dữ liệu. Biến đại
diện cho một loại dữ liệu nào đấy và được nhận các giá trị (value), các giá trị
này được sử dụng để tính tốn ra giá trị cho biến khác. Từ những năm đầu thập
niên 1960, nhiều lập trình viên đã phân tích mã nguồn tại các điểm mà tại đó các
biến được nhận giá trị hay giá trị của biến được sử dụng. Ngày nay, những ý
tưởng trên cũng đã được vận dụng trong kiểm thử định nghĩa – sử dụng.



16
2.4.1. Kiểm thử định nghĩa - sử dụng (Define/Use Testing)
Để tiếp cận với lý thuyết kiểm thử định nghĩa – sử dụng, cần làm quen với một
số định nghĩa về nút định nghĩa, nút sử dụng, đường định nghĩa – sử dụng,…
Nội dung các định nghĩa này được trích dẫn từ tài liệu [5].
Những định nghĩa này áp dụng cho một chương trình P. P có đồ thị chương
trình G(P) và có tập hợp các biến chương trình V. G(P) được thiết lập với các
nút là các đoạn chương trình, các cạnh biểu diễn thứ tự các nút. G(P) có một nút
đơn đầu vào và một nút đơn đầu ra. Trong G(P) không cho phép một cạnh bắt
đầu từ một nút và kết thúc tại chính nút đó.
Với chương trình P được xác định như trên, ta có các định nghĩa sau đây:
Định nghĩa 1
Nút n G(P) là nút định nghĩa (defining node) của biến v V, ký hiệu là
DEF(v,n), nếu giá trị của biến v được định nghĩa tại đoạn câu lệnh tương ứng
với nút n.
Những câu lệnh nhập, câu lệnh gán, câu lệnh điều khiển vòng lặp, lời gọi
thủ tục là tất cả các ví dụ của các lệnh tương ứng với nút định nghĩa. Khi các câu
lệnh như trên được thực thi, giá trị lưu trữ trong bộ nhớ tương ứng với biến sẽ
được thay đổi.
Định nghĩa 2
Nút n G(P) là nút sử dụng (usage node) của biến v V, ký hiệu là
USE(v,n), nếu giá trị của biến v được sử dụng tại đoạn câu lệnh tương ứng với
nút n.
Những câu lệnh xuất, lệnh gán, lệnh điều kiện, lệnh điều khiển vòng lặp, lời
gọi thủ tục là tất cả các ví dụ của các lệnh tương ứng với nút sử dụng. Khi các
câu lệnh như trên được thực thi, giá trị lưu trữ trong bộ nhớ tương ứng với biến
sẽ không bị thay đổi.
Định nghĩa 3
Một nút sử dụng USE(v,n) là một sử dụng mệnh đề (predicate use) (kí hiệu

là P-use) nếu câu lệnh n là một câu lệnh mệnh đề, trong trường hợp ngược lại
USE(v,n) là một sử dụng tính tốn (kí hiệu là C-use).
Những nút tương ứng với sử dụng mệnh đề ln ln có bậc xuất
(outdegree) ≥ 2, còn những nút tương ứng với sử dụng tính tốn ln ln có
bậc xuất ≤ 1.


17
Định nghĩa 4
Đường định nghĩa – sử dụng (definition-use path) với một biến v là một
đường thuộc PATHS(P) với m và n lần lượt là các nút bắt đầu và nút kết thúc,
trong đó DEF(v, m) và USE(v,n) lần lượt là các nút định nghĩa và nút sử dụng
của biến v.
Định nghĩa 5
Đường định nghĩa - rõ ràng (definition-clear path) với một biến v là
đường định nghĩa - sử dụng trong PATHS(P) với nút bắt đầu và kết thúc là
DEF(v,m) và USE(v,n), đồng thời không tồn tại một nút định nghĩa khác của
biến v trong đường.
Người kiểm thử cần chú ý đến những định nghĩa trên để nắm bắt được bản
chất q trình tính tốn với các giá trị dữ liệu lưu trữ. Định nghĩa - sử dụng và
định nghĩa - rõ ràng mơ tả dịng dữ liệu của đoạn mã nguồn từ điểm giá trị được
định nghĩa đến điểm giá trị được sử dụng. Những đường định nghĩa - sử dụng
mà không phải là định nghĩa - rõ ràng sẽ chứa đựng nhiều điểm rắc rối.
Vậy để kiểm thử định nghĩa – sử dụng một chương trình, cần tiến hành
kiểm thử theo quy trình sau :
o Xác định phủ kiểm thử
o Xây dựng đồ thị chương trình dựa trên phủ kiểm thử
o Tìm các đường định nghĩa - sử dụng với mỗi biến
o Với mỗi đường định nghĩa - sử dụng, có thể xây dựng một ca kiểm thử
đi qua các câu lệnh trong đường đó để kiểm thử dòng dữ liệu của biến.

2.4.2. Kiểm thử dựa trên lát cắt (Slice-based testing)
Khái niệm lát cắt chương trình được đề cập đến trong tài liệu kỹ sư phần mềm từ
những năm đầu 1980. Khái niệm về lát cắt chương trình được trình bày rất tự
nhiên, rõ ràng trực quan. Một lát cắt chương trình là một tập hợp các câu lệnh,
những câu lệnh mà góp phần tạo ra hoặc ảnh hưởng đến giá trị của một biến tại
một số điểm trong chương trình [5].
Bắt đầu bằng việc phát triển định nghĩa về lát cắt chương trình. Tiếp tục sử
dụng những ký hiệu dùng cho các đường định nghĩa - sử dụng ở mục 2.4.1: Một
chương trình P có đồ thị chương trình G(P), và có tập hợp các biến chương trình
V. Đầu tiên cần xem xét các định nghĩa để cho phép chuyển đổi các nút trong
G(P) thành các đoạn câu lệnh.


18
Định nghĩa 1
Cho một chương trình P, và một tập V các biến trong P. Một lát cắt trên tập
các biến V tại câu lệnh n, ký hiệu là S(V,n), là tập hợp tất cả các câu lệnh trong
P mà có đóng góp tạo ra các giá trị của các biến trong V.
Liệt kê các phần tử của lát cắt S(V,n) sẽ rất rườm rà, bởi vì các phần tử đó
chính là các đoạn mã chương trình. Sẽ đơn giản hơn nhiều nếu liệt kê số các
đoạn trong G(P) [5].
Định nghĩa 2
Cho một chương trình P, một đồ thị chương trình G(P), trong đó các câu
lệnh và các đoạn câu lệnh được đánh số, và tập hợp V các biến của P. Một lát cắt
trên tập các biến V tại đoạn câu lệnh n, ký hiệu là S(V,n), là tập hợp số của các
nút của tất cả các đoạn câu lệnh trong P đứng trước n mà có đóng góp tạo ra các
giá trị của các biến trong V tại đoạn câu lệnh n [5].
Ý tưởng của các lát cắt khi chia chương trình thành các phần nhỏ có một số
ý nghĩa sau. Trước tiên, cần thảo luận về hai phần của định nghĩa. Cụm từ “đứng
trước” mang ý nghĩa động, như vậy một lát cắt nắm bắt được thời gian thực thi

các hành động của chương trình tương ứng với các biến trong lát cắt. Cuối cùng
sẽ phát triển một mạch (đồ thị hở, có hướng) của các lát cắt, trong đó, các nút là
các lát cắt, các cạnh tương ứng với các mối quan hệ tập hợp con.
Về việc sử dụng các biến, chúng ta có thể chia mối quan hệ sử dụng (use)
thành năm hình thức sau:
o P-use: sử dụng trong một quyết định (predicate)
o C-use: sử dụng trong tính tốn
o O-use: sử dụng cho xuất dữ liệu
o L-use: sử dụng cho việc đặt vị trí (con trỏ, subscript)
o I-use: việc lặp (biến đếm, chỉ số vòng lặp)
Theo đó, chúng ta xác định hai hình thức của các nút định nghĩa:
o I-def: định nghĩa bằng việc nhập dữ liệu
o A-def: định nghĩa bằng việc gán
Giả sử lát cắt S(V,n) là một lát cắt trên một biến, nghĩa là, tập V chỉ chứa
một biến v. Nếu đoạn lệnh n là một nút định nghĩa của biến v, thì n được bao
gồm trong lát cắt. Nếu đoạn lệnh n là một nút sử dụng của biến v, thì n không
được bao gồm trong lát cắt. P-use và C-use của các biến khác (không phải là v)


19
được bao gồm nếu việc thực thi chúng ảnh hưởng đến giá trị của biến v. Theo
như hướng dẫn, nếu giá trị của biến v là như nhau thì đoạn câu lệnh được loại bỏ
khỏi lát cắt.
Như vậy để cung cấp kiến thức nền tảng chuẩn bị cho nghiên cứu chuyên
sâu vào luận văn, luận văn đã lần lượt tìm hiểu về kiểm thử đơn vị, phân tích
tĩnh, kiểm thử luồng điều khiển và hai dạng của kiểm thử luồng dữ liệu là kiểm
thử định nghĩa – sử dụng và kiểm thử dựa trên lát cắt.


20

CHƯƠNG 3 - KỸ THUẬT KIỂM THỬ SINH MÔI TRƯỜNG
Chương 3 trình bầy từng bước để tạo ra mơi trường cho đơn vị và tiến hành
kiểm thử đơn vị trong sự tương tác với mơi trường. Q trình bao gồm các bước:
chọn chức năng cần kiểm thử; xác định đơn vị gồm những lớp nào; xác định
giao diện đơn vị - môi trường; liệt kê các hành vi của môi trường lên đơn vị và
các hành vi của đơn vị lên môi trường; cuối cùng, tiến hành kiểm thử trên tổng
thể mối quan hệ đơn vị và môi trường để đảm bảo tính đúng đắn của chức năng .
3.1. Chọn chức năng cần kiểm thử và xác định đơn vị
Những phần mềm lớn có rất nhiều lớp và nhiều chức năng. Cần xác định chức
năng cần kiểm thử. Sử dụng kỹ thuật phân tích tĩnh, cùng các tài liệu về đặc tả,
thiết kế, mã chương trình, xác định những lớp nào quyết định trực tiếp đến chức
năng này. Tập hợp những lớp đó gọi là đơn vị, những lớp này được gọi là các
lớp của đơn vị.
3.2. Xác định giao diện đơn vị - môi trường
Nội dung bước hai là tìm hiểu cấu trúc của giao diện đơn vị – môi trường. Giao
diện của đơn vị - môi trường gồm hai phần: giao diện đơn vị và giao diện môi
trường. Giao diện đơn vị thể hiện các hành vi mà mơi trường có thể thực thi trên
đơn vị. Ngược lại, giao diện môi trường thể hiện các hành vi mà đơn vị tác động
lên môi trường.
Giao diện đơn vị: Bằng việc sử dụng kỹ thuật phân tích tĩnh, lần lượt phân
tích các lớp của đơn vị. Giao diện đơn vị bao gồm tất cả các phương thức và các
thuộc tính công khai (public) của các lớp trong đơn vị, cái mà có thể bị tham
chiếu bởi mơi trường. Nghĩa là, lần lượt xét các thuộc tính và các phương thức
của các lớp trong đơn vị, xem những thuộc tính, phương thức nào được gọi đến
bởi môi trường, hay bị thay đổi giá trị bởi môi trường.
Để xác định giao diện đơn vị ta sử dụng thuật toán 3.1. Thuật toán với đầu
vào là tập hợp các lớp của đơn vị, kí hiệu là U. Đầu ra thu được sau khi thực
hiện thuật toán là tập hợp một số phương thức và một số thuộc tính của đơn vị
tạo nên giao diện đơn vị, kí hiệu là S. Ban đầu, giao diện đơn vị S được khởi tạo
bằng rỗng, nghĩa là khơng chứa thuộc tính hay phương thức nào. Lần lượt xét tất

cả các lớp trong đơn vị, lớp được xét kí hiệu là u (dịng 1). Với mỗi lớp u, xét tất
cả các phương thức của lớp, phương thức được xét kí hiệu là m (dịng 2). Kiểm
tra xem m có được thi hành bởi driver của đơn vị hay khơng (dịng 3). Nghĩa là,
tìm xem phương thức nào của u được gọi bởi các lớp ngoài đơn vị. Nếu phương
thức m đó được gọi bởi các lớp ngồi đơn vị, thêm phương thức m vào giao diện


21
đơn vị S (dòng 4). Tương tự, xét tất cả các thuộc tính của lớp u, thuộc tính đang
xét được kí hiệu là f (dịng 7). Kiểm tra xem thuộc tính f có được sử dụng bởi
các lớp ngồi đơn vị hay khơng (dịng 8). Nếu thuộc tính f được sử dụng bởi các
lớp ngồi đơn vị, thêm thuộc tính đó vào giao diện đơn vị S (dịng 9). Trong
thuật tốn, việc kiểm tra phương thức và thuộc tính có được sử dụng bởi các lớp
ngồi đơn vị hay khơng được minh họa bằng hàm isRevelant (dịng 3, 8).
Thuật tốn 3.1 – Thuật toán xác định giao diện đơn vị [5]
Đầu vào: U: tập hợp các lớp của đơn vị
Đầu ra: S: tập hợp các phương thức và các thuộc tính của đơn vị
Khởi tạo: S =
1: for each class u U do
2:
for each method m u.getMethods() do
3:
if isRelevant(m) then
4:
S=S m
5:
end if
6:
end for
7:

for each field f u.getFields() do
8:
if isRelevant(f) then
9:
S=S f
10:
end if
11:
end for
12: end for
13: return S.
Ví dụ 3.1. Minh họa thuật toán xác định giao diện đơn vị
Giả sử đơn vị chỉ bao gồm một lớp Login thuộc không gian tên
TestSystem.Models. Xét tất cả các thuộc tính và phương thức của lớp Login,
nhận thấy chỉ có thuộc tính TypeUser bị gọi bởi phương thức Page_Load của
lớp Default thuộc không gian tên TestSystem, thuộc tính IDTeacher, IDStudent
bị gọi bởi phương thức Logout_bt_Click của lớp Logout thuộc không gian tên
TestSystem.Models, thuộc tính countAdmin, countTeacher, countStudent,
countAnonymous bị gọi bởi phương thức Page_Load của lớp Status thuộc
khơng gian tên TestSystem.Models (xem hình 3.1). Như vậy giao diện đơn vị
bao gồm các thuộc tính TypeUser, IDTeacher, IDStudent, countAdmin,
countTeacher, countStudent, countAnonymous của lớp Login.


22

Hình 3.1. Minh họa thuật tốn giao diện đơn vị
Giao diện môi trường: Để xác định giao diện môi trường, phân tích lần
lượt các phương thức và các thuộc tính trong từng lớp của đơn vị, tìm kiếm các
liên kết ngoài mà các lớp của đơn vị tham chiếu đến. Sử dụng thuật tốn 3.2 để

xác định giao diện mơi trường. Đầu vào của thuật toán là tập hợp các lớp của
đơn vị, kí hiệu là U, và đồ thị biểu diễn việc các phương thức của chương trình
gọi lẫn nhau, kí hiệu là CG. Đầu ra thu được sau khi thực hiện thuật toán là tập
hợp một số các thuộc tính, các phương thức của mơi trường tạo nên giao diện
mơi trường, kí hiệu là E. Ban đầu, giao diện môi trường E được khởi tạo bằng
rỗng, nghĩa là khơng chứa thuộc tính hay phương thức nào. Lần lượt xét tất cả
các lớp trong đơn vị, lớp được xét kí hiệu là u (dịng 1). Với mỗi lớp u, xét lớp
cha của nó có nằm ngồi đơn vị hay khơng, nếu nó nằm ngồi và chưa có trong
mơi trường thì thêm nó vào mơi trường (dịng 2). Xét tất cả các giao diện
(interface) của u (dòng 3), kiểm tra xem giao diện đó có nằm ngồi đơn vị hay
khơng, nếu nó nằm ngồi và chưa có trong mơi trường thì thêm nó vào mơi
trường (dịng 4). Cơng việc kiểm tra trên được minh họa bởi hàm envCheck
trong thuật toán. Với mỗi lớp u, xét tất cả các thuộc tính trong lớp, thuộc tính
được xét kí hiệu là f (dịng 6). Kiểm tra xem kiểu của f có nằm ngồi đơn vị hay
khơng, nếu nó nằm ngồi và chưa có trong mơi trường thì thêm nó vào mơi
trường (dịng 7). Với mỗi lớp u, xét tất cả các phương thức trong lớp, phương
thức được xét kí hiệu là m (dịng 9). Dùng hàm envCheckSignature kiểm tra
xem kiểu của giá trị trả về của m có nằm ngồi đơn vị hay khơng, nếu nó nằm
ngồi và chưa có trong mơi trường thì thêm nó vào mơi trường (dịng 10). Lần
lượt xét tất cả các biến cục bộ của m, biến đang xét kí hiệu là l (dịng 11), kiểm
tra xem kiểu của l có nằm ngồi đơn vị hay khơng, nếu nó nằm ngồi và chưa có


23
trong mơi trường thì thêm nó vào mơi trường (dịng 12). Với mỗi câu lệnh s
trong phương thức m (dòng 14), kiểm tra xem nó có gọi đến phương thức nào
ngồi đơn vị hay khơng. Nếu trong câu lệnh có lời gọi hàm (dịng 15), tìm xem
hàm đó là hàm nào, kí hiệu là hàm m’ (dịng 16), kiểm tra xem kiểu của giá trị
trả về của m’ có nằm ngồi đơn vị hay khơng, nếu nó nằm ngồi và chưa có
trong mơi trường thì thêm nó vào mơi trường (dịng 17), tìm xem m’ thuộc lớp

nào, kí hiệu là lớp D (dịng 18). Kiểm tra xem lớp D có nằm ngồi đơn vị khơng
và nếu lớp D nằm ngồi và chưa được thêm vào mơi trường thì thêm lớp D vào
mơi trường (dịng 19), đồng thời thêm hàm m’ vào giao diện mơi trường E (dịng
20). Tương tự, nếu trong câu lệnh s có gọi đến một trường nào đó (dịng 23), tìm
xem thuộc tính đó là thuộc tính nào, kí hiệu là thuộc tính f (dịng 24), tìm xem
thuộc tính f thuộc lớp nào, kí hiệu là lớp D (dịng 25). Kiểm tra xem lớp D có
nằm ngồi đơn vị khơng và nếu lớp D nằm ngồi và chưa được thêm vào mơi
trường thì thêm lớp D vào mơi trường (dịng 26), đồng thời thêm thuộc tính f
vào giao diện mơi trường E (dịng 27).
Thuật tốn 3.2: Thuật tốn xác định giao diện mơi trường [5]
Đầu vào: U: tập hợp các lớp của đơn vị, CG: đồ thị gọi các phương thức
Đầu ra: E: tập hợp các lớp, các phương thức, các thuộc tính của mơi
trường
Khởi tạo: E =
1: for each class u U do
2: envCheck(u.getSuperclass())
3: for each interface I u.getInterfaces() do
4:
envCheck(I)
5: end for
6: for each field f u.getFields() do
7:
envCheck(f.getTypeClass())
8: end for
9: for each method m u.getMethods() do
10:
envCheckSignature(m)
11:
for each local l m.getLocals() do
12:

envCheck(l.getTypeClass())
13:
end for
14:
for each statement s m.getStatements() do
15:
if (s.containsInvokeExpr()) then
16:
method m’ = CG.resolveDispatch(s)
17:
envCheckSignature(m’)


24
18:
class D = m’.getDeclaringClass()
19:
if (envCheck(D)) then
20:
E = E m’
21:
end if
22:
end if
23:
if (s.containsFieldRef()) then
24:
f = s.getFieldRef()
25:
class D = f. getDeclaringClass()

26:
if (envCheck(D)) then
27:
E=E f
28:
end if
29:
end if
30: end for
31: end for.
Ví dụ 3.2. Minh họa thuật tốn xác định giao diện mơi trường
Sử dụng ví dụ 3.1, xác định giao diện mơi trường. Đơn vị chỉ bao gồm một
lớp Login thuộc không gian tên TestSystem.Models. Xét tất cả các phương thức
của lớp Login, xét từng câu lệnh trong từng phương thức, nhận thấy phương
thức Login_bt_Click của lớp Login gọi đến các phương thức GetStudent của lớp
Student và phương thức GetDataTeacher của lớp Teacher; phương thứ PrLogin
của lớp Login gọi đến các phương thức SetPresenceStudent của lớp Student và
phương thức SetPresenceTeacher của lớp Teacher (xem hình 3.2). Như vậy giao
diện mơi trường trong ví dụ bao gồm các phương thức GetStudent,
SetPresenceStudent của lớp Student và các phương thức GetDataTeacher,
SetPresenceTeacher của lớp Teacher.

Hình 3.2. Minh họa thuật tốn xác định giao diện mơi trường


25
Kết quả giao diện đơn vị - môi trường tổng hợp được từ hai ví dụ 3.1 và 3.2
bao gồm các thuộc tính TypeUser, IDTeacher, IDStudent, countAdmin,
countTeacher, countStudent, countAnonymous của lớp Login và các phương
thức GetStudent, SetPresenceStudent của lớp Student và các phương thức

GetDataTeacher, SetPresenceTeacher của lớp Teacher.
Đơn vị và mơi trường có thể tác động qua lại với nhau về mặt điều khiển
hay về mặt dữ liệu. Môi trường có thể làm thay đổi giá trị của thuộc tính hay gọi
đến một thuộc tính, một phương thức nào đó của đơn vị. Tập hợp những hành vi
đó gọi là những hành vi mà môi trường tác động lên đơn vị. Sử dụng giao diện
đơn vị được xác định ở trên, có thể liệt kê ra những hành vi của mơi trường tác
động lên đơn vị, từ đó địi hỏi cần tiến hành kiểm thử những thuộc tính, phương
thức nào của đơn vị để đảm bảo những hành vi mà mơi trường tác động lên đơn
vị có kết quả chính xác.
Tương tự, đơn vị cũng có thể có những tác động ngược lại lên môi trường,
chẳng hạn như đơn vị có thể sử dụng một phương thức hay thuộc tính nào đó
nằm ngồi đơn vị. Những hành vi đó gọi là hành vi của đơn vị tác động lên môi
trường. Với kết quả tìm được giao diện mơi trường ở trên, có thể xác định được
cần tiến hành kiểm thử những phương thức, thuộc tính nào ở những lớp nào để
đảm bảo tính đúng đắn của những hành vi mà đơn vị tác động lên môi trường.
Sau khi xác định được những hành vi của đơn vị và môi trường tác động lên
nhau, sử dụng những kỹ thuật kiểm thử đơn vị để kiểm thử, đảm bảo chức năng
được thỏa mãn.
3.3. Kiểm thử
Để kiểm tra tính đúng đắn của chức năng, có thể sử dụng các kỹ thuật kiểm thử
luồng điều khiển và kiểm thử luồng dữ liệu đã trình bày ở mục 2.3 và 2.4 để
kiểm thử các thuộc tính và phương thức liên quan đến các hành vi mà đơn vị và
môi trường tác động qua lại lên nhau.
Áp dụng các kỹ thuật kiểm thử đơn vị để kiểm thử các thuộc tính và
phương thức của giao diện đơn vị - mơi trường. Sau khi phân tích, ta có một hệ
thống các ca kiểm thử (testcase). Chạy chương trình với các ca kiểm thử, theo
dõi kết quả, so sánh với kết quả kỳ vọng của từng ca kiểm thử, lập báo cáo quá
trình kiểm thử. Quá trình kiểm thử cho kết quả chính xác sẽ đảm bảo chức năng
hoạt động đúng trên toàn hệ thống.



26
CHƯƠNG 4 - ỨNG DỤNG
Nội dung chương 4 bao gồm giới thiệu khái quát về hệ thống TestSystem – một
hệ thống kiểm tra trực tuyến đơn giản do tác giả xây dựng, đồng thời trình bày
việc áp dụng các bước của kỹ thuật kiểm thử sinh môi trường để kiểm thử chức
năng đăng nhập của hệ thống TestSystem.
4.1. Giới thiệu hệ thống TestSystem
Hệ thống TestSystem cho phép người dùng thực hiện và quản lý các bài trắc
nghiệm trực tuyến qua mạng của một trường đại học. Hệ thống được viết trên
C# và ASP.NET. Cơ sở dữ liệu được thiết kế trên Microsoft Access. Hệ thống
bao gồm 3 loại người dùng: sinh viên, giáo viên và người quản trị. Khi vừa truy
nhập hệ thống, người dùng được coi như là khách. Khách chỉ có quyền xem giới
thiệu chung về hệ thống mà khơng có chức năng, thao tác nào với hệ thống và
cơ sở dữ liệu. Để có thể thực hiện các chức năng cho phép của mình, người dùng
khi truy cập vào hệ thống cần phải đăng nhập với tên (user) và mật khẩu
(password) đã được đăng ký trước. Hệ thống sẽ thường xuyên thống kê số khách
và các loại người dùng hiện đang truy cập hệ thống. Các chức năng của từng loại
người dùng đối với hệ thống bao gồm như sau:
Chức năng của sinh viên
Sinh viên có thể thực hiện bài trắc nghiệm bằng cách thực hiện quy trình
như sau:
o Đăng nhập với tên và mật khẩu của sinh viên
o Lựa chọn cấp độ bài trắc nghiệm
o Lựa chọn môn học
o Hệ thống chọn ngẫu nhiên một số câu hỏi trong ngân hàng câu hỏi
o Sinh viên thực hiện bài trắc nghiệm, hoàn thành trong thời gian quy định
o Khi kết thúc bài làm, hệ thống thông báo kết quả
Ngồi ra, sinh viên cịn có chức năng xem lại điểm của tất cả các bài trắc
nghiệm mình đã làm.

Chức năng của giáo viên
Giáo viên sau khi đăng nhập hệ thống, có quyền quản lý đề thi, quản lý câu
hỏi và xem điểm của sinh viên. Giáo viên có quyền tạo, sửa, xóa đề của những
mơn mình có tham gia làm câu hỏi. Có quyền thêm, xóa, sửa các câu hỏi của
một mơn nào đó.


27
Chức năng của người quản trị
Người quản trị có đủ quyền như giáo viên. Ngồi ra, người quản trị cịn có
chức năng phân quyền cho các người dùng, quản lý dữ liệu về các khoa, lớp,
môn học, mức độ các bài trắc nghiệm,… Người quản trị quản lý dữ liệu của toàn
hệ thống.
Như vậy, chức năng đăng nhập là một chức năng quan trọng và rất hay
được sử dụng của hệ thống TestSystem. Trong phần tiếp theo của luận văn, việc
kiểm thử chức năng đăng nhập với việc áp dụng kỹ thuật kiểm thử sinh mơi
trường sẽ được trình bày chi tiết.
4.2. Kiểm thử chức năng đăng nhập của hệ thống TestSystem
Trong phần này, ta hiện thực hóa các bước được trình bày trong chương 3 với
một chức năng cụ thể của hệ thống TestSystem, đó là chức năng đăng nhập.
4.2.1. Xác định đơn vị
Sử dụng kỹ thuật phân tích tĩnh, nghiên cứu mã của chương trình, kết quả cho
thấy các lớp quyết định trực tiếp đến chức năng đăng nhập là lớp Login thuộc
không gian tên (namespace) TestSystem.Models.
4.2.2. Xác định giao diện đơn vị – môi trường
Giao diện đơn vị - môi trường bao gồm hai phần: giao diện đơn vị và giao diện
môi trường. Chi tiết từng giao diện được trình bày như sau:
Giao diện đơn vị: Áp dụng thuật toán xác định giao diện đơn vị được trình
bày trong mục 3.2, kiểm tra lần lượt các phương thức và các thuộc tính trong lớp
Login xem có những thuộc tính, phương thức nào được gọi hay bị thay đổi giá

trị bởi một lớp nào đó bên ngồi đơn vị hay khơng. Nếu có, thêm thuộc tính,
phương thức đó vào giao diện đơn vị. Kết quả, ta thấy những thuộc tính sau của
đơn vị được sử dụng bởi mơi trường bên ngoài.
o
o
o
o
o
o
o
o

nTypeUser
nUserName
nIDTeacher
nIDStudent
CountAnonymous
CountStudent
CountTeacher
CountAdmin


28
Giao diện mơi trường: Áp dụng thuật tốn xác định giao diện mơi trường
được trình bày trong mục 3.2, tìm kiếm tất cả các liên kết ngoài mà đơn vị tham
chiếu đến. Với chức năng đăng nhập của hệ thống TestSystem, xét lớp Login
xem tham chiếu đến các lớp bên ngồi nào, xác định được giao diện mơi trường
gồm các phương thức sau:
o
o

o
o

GetStudent của lớp Student
GetDataTeacher của lớp Teacher
SetPresenceStudent của lớp Student
SetPresenceTeacher của lớp Teacher

Sau khi xác định được giao diện đơn vị và giao diện môi trường, cần tiến
hành kiểm thử để đảm bảo chức năng hoạt động chính xác.
4.2.3. Kiểm thử chức năng đăng nhập
Để kiểm thử tính đúng đắn của chức năng đăng nhập, cần lần lượt kiểm thử các
thuộc tính và các phương thức của giao diện đơn vị - mơi trường.
Kiểm thử các thuộc tính trong đơn vị mà môi trường cần dùng
Sử dụng kiểm thử luồng dữ liệu theo phương pháp định nghĩa – sử dụng để
kiểm thử các thuộc tính nTypeUser, nIDStudent, nIDTeacher, countTeacher,
countAdmin, countStudent, countAnonymous trong lớp Login.
Mã lớp Login được đánh số dòng như sau:
1 prvate void Login_bt_Click(object sender, System.EventArgs e)
2 {
3
Error_lb.Visible = false;
4
string nUser, nPassword;
5
int nTypeUser;
6
7
nUser = User_tb.Text;
8

nPassword = Password_tb.Text;
9
DBStudent = CStudent.GetStudent(nUser, nPassword);
10 if (DBStudent.Rows.Count > 0)
11 {
12
nTypeUser = 3;
13
PrLogin( DBStudent, nTypeUser);
14 }
15 else
16 {


×