You are on page 1of 32

HỌC VIỆN CÔNG NGHỆ BƯU CHÍNH VIỄN THÔNG

Khoa Công nghệ thông tin

Báo cáo
MÔN HỌC: Nhập môn công nghệ phần mềm

NHÓM MÔN HỌC: 11

Giảng viên: Đặng Ngọc Hùng

Nhóm sinh viên thực hiện: nhóm 23


Nguyễn Minh Tuân B19DCCN604

Đỗ Như Đức B19DCCN189

Nguyễn Tiến Chức B19DCCN106

Hà Nội năm 2022


Chương 15: Luồng công việc thực thi
1. Khái niệm và mục tiêu nghiên cứu
- Luồng công việc thực thi là quá trình chuyển đổi từ quá trình thiết kế chi tiết
thành mã nguồn ngôn ngữ lập trình. Trên thực tế đối với dự án phần mềm
phức tạp và có quy mô lớn, việc thực hiện cả luồng công việc thực thi với
một cá nhân là điều rất khó và đòi hỏi sự hợp tác của nhiều lập trình viên với
nhau. Sản phẩm khi đó sẽ được thực thi bởi một nhóm, làm việc đồng thời
trên các thành phần khác nhau nhỏ hơn của sản phẩm.
- Mục tiêu
 Tìm hiểu luồng công việc thực thi trong kỹ thuật lập trình.
 Tìm hiểu các kĩ thuật kiểm thử hộp đen (black-box), kiểm thử hộp thuỷ
tinh (white-box) và kiểm thử phi thực thi (non-execution-based).
 Tìm hiểu các loại tích hợp (integration testing), kiểm thử sản phẩm
(product testing) và kiểm thử chấp nhận (acceptance testing).
 Đánh giá các tiêu chuẩn và các giải pháp tốt trong kỹ thuật lập trình.

2. Lựa chọn ngôn ngữ lập trình


- Trong hầu hết trường hợp, việc xảy ra vấn đề phải lựa chọn ngôn ngữ lập
trình thường không phát sinh dưới các trường hợp sau đây.
 Khách hàng (client) yêu cầu sản phẩm phải được thực thi dưới một ngôn
ngữ lập trình cố định
 Khi sản phẩm phải được thực thi trên một môi trường hạn chế nào đó mà
những ngôn ngữ lập trình khác không có tính khả dụng.
- Nếu giả sử ta đặt ra vấn đề ngôn ngữ lập trình nào phù hợp nhất để thực thi
sản phẩm: Công ty COBOL có hơn 200 nhân viên đã được đào tạo và sử
dụng thành thạo ngôn ngữ lập trình COBOL được nhiều năm. Một ngôn ngữ
lập trình mới là Java mạnh mẽ hơn nhiều xuất hiện và câu hỏi được đặt ra là
ngôn ngữ nào sẽ phù hợp để thực thi các sản phẩm của công ty COBOL. Để
trả lời vấn đề này chúng ta đi xem xét các khía cạnh:
 Vấn đề bảo trì: việc thực thi các sản phẩm mới bằng Java vẫn phải đảm
bảo việc bảo trì những sản phẩm cũ viết bằng COBOL Việc quản lý hai
phân lớp lập trình viên khác nhau là không hề dễ dàng bởi vấn đề bất
đồng có thể xảy ra khi lập trình viên Java thường được trả lương cao hơn
do nhân lực lúc đầu khan hiếm.
 Vấn đề chi phí: Quá trình tuyển dụng và đào tạo lập trình viên bằng ngôn
ngữ mới sẽ tốn rất nhiều kinh phí và thời gian của công ty. Mặt khác
công ty sẽ phải tốn thêm một khoản để đầu tư các thiết bị phần cứng,
phần mềm phục vụ việc lập trình bằng ngôn ngữ mới.
 Quá trình chuyển đổi lựa chọn ngôn ngữ lập trình mới có thể gây ra nhiều
hậu quả về tài chính cũng như nhân lực cho doanh nghiệp.

- Khi sản phẩm khó hoặc không thể được thực thi bằng ngôn ngữ lập trình sẵn
có: vấn đề lựa chọn ngôn ngữ lập trình khác phù hợp hoặc mạnh mẽ hơn là
điều cần thiết để phù hợp với yêu cầu sản phẩm của khách hàng. Việc thực
hiện lựa chọn này ví dụ có thể đánh giá theo các cách sau:
 Đánh giá theo chi phí: Doanh nghiệp phải tính toán chi phí cần phải đầu
tư để thực hiện dự án theo từng loại ngôn ngữ khả dụng. Ngôn ngữ lập
trình phù hợp nhất sẽ cho lợi nhuận cao và chi phí thực hiện nhỏ nhất.
 Đánh giá theo rủi ro: Xét các rủi ro có thể gặp phải và phương hướng giải
quyết. Ngôn ngữ lập trình phù hợp nhất là ngôn ngữ cho rủi ro thấp nhất.
3. Ngôn ngữ lập trình thế hệ thứ 4
- Thế hệ thứ nhất: Ở thời kì sơ khai của lập trình phần mềm, chưa hề có khái
niệm trình biên dịch hay thông dịch, phần mềm được viết bằng mã nhị phân,
hoặc bảng mạch và switch.
- Thế hệ thứ 2: hợp ngữ ra đời khiến và hoạt động bằng cách dịch hợp ngữ
sang mã máy. Việc lập trình và bảo trì trở nên dễ dàng hơn tuy nhiên độ dài
mã chương trình vẫn tương tự mã máy.
- Thế hệ thứ 3: ý tưởng của ngôn ngữ lập trình thế hệ thứ 3 là các loại ngôn
ngữ bậc cao như C, C++, Pascal hoặc Java khiến cho việc lập trình trở nên
dễ dàng hơn khi mỗi dòng mã có thể biên dịch và thực thi thay cho 5-10
dòng mã máy. Tuy nhiên việc bảo trì các phần mềm viết bằng hợp ngữ thời
điểm này lại tốn ít chi phí hơn.
- Thế hệ thứ 4: ý tưởng của ngôn ngữ lập trình thứ 4  có từ những cuối năm
1970. Mục tiêu của việc thiết kế ngôn ngữ thế hệ thứ 4 (4GL) này là mỗi
dòng mã sẽ tương đương với 30-50 dòng mã máy. Vì thế giúp rút ngắn quá
trình phát triển sản phẩm và khiến việc bảo trì dễ dàng hơn.
4. Các quy chuẩn phổ biến khi lập trình
1. Sử dụng tên biến thích hợp và có nghĩa 
- Việc đặt tên biến thích hợp và có nghĩa là vô cùng quan trọng với việc bảo
trì phần mềm do thành phần mã được viết ra bởi một lập trình viên sẽ có thể
bảo trì bởi nhiều hơn 1 người, việc bảo trì sẽ dàng và tiết kiệm chi phí hơn
nếu các tên biến được đặt theo đúng quy chuẩn ngay từ khi thực thi.
- Các quy chuẩn đặt tên biến:
 Đặt tên biến thích hợp: chọn duy nhất một tên biến có nghĩa hay vì nhiều
tên biến đều cùng chỉ một đối tượng. Ví dụ không nên dùng cả tên biến là
average và medium trong cùng một chương trình bởi chúng có nghĩa
gần tương đương.
 Đồng bộ thứ tự cách đặt tên biến: nếu đã chọn một thứ tự cho các thành
phần trong tên biến, thì các tên biến tương tự cũng phải tuân theo thứ tự
đó. Ví dụ: “frequencyMax” thì không nên dùng cách đặt tên
“minFrequency” cho giá trị min. Thay vì đó hãy đồng bộ thành
“frequencyMin”.
2. Chú thích khi viết mã
- Tại sao cần chú thích mã: 
 Mục tiêu quan trọng của việc chú thích là khiến đoạn mã có thể dễ dàng
đọc và hiểu bởi những lập trình viên khác điều hành hoặc thực hiện dự án
cùng. Việc chú thích mã cũng sẽ giúp cho việc bảo trì và đảm bảo chất
lượng phần mềm tốt và dễ dàng hơn.
 Mã tự chú thích: là cách viết mã có tính mô tả cao và có thể hiểu một
cách dễ dàng mà không cần chú thích. Tuy nhiên lập trình viên có thể
viết cách này khá hiếm.
- Các vấn đề gặp phải khi không chú thích mã:
 Với các lập trình viên thiếu kinh nghiệm việc viết mã không đảm bảo
chất lượng là hoàn toàn có thể xảy ra, điều này khiến việc thực thi và bảo
trì trở nên khó khăn hơn.
 Với đoạn mã không có chú thích nếu giả dụ có thay đổi nhân sự thì nhân
sự mới sẽ gặp khó khăn khi làm việc với đoạn mã có sẵn. 
3. Sử dụng tham số
- Tại sao nên sử dụng tham số để gán giá trị hằng số:
 Sử dụng tham số khiến hằng số trở nên có ý nghĩa thay vì những con số
không rõ ràng.
 Tránh việc vô tình thay đổi giá trị biến khiến sinh ra lỗi trong phần mềm
hoặc cho kết quả không chính xác.
 Việc thay đổi giá trị hằng số sẽ dễ dàng hơn vì dùng tham số tương quan
thay vì cố định.
4. Sắp xếp bố cục mã nguồn hợp lý
- Với sự ra đời của các IDE hiện đại có chức năng định dạng được tích hợp
sẵn thì việc sắp xếp bố cục mã nguồn càng dễ dàng hơn. Tuy nhiên ta vẫn
nên xem xét các tiêu chí để sắp xếp:
 Thụt lùi đầu dòng và sử dụng ngoặc
 Nên viết mỗi câu lệnh trên một dòng
 Sử dụng dòng trống để phân cách các đoạn mã
5. Câu lệnh điều kiện lồng nhau
- Ta đánh giá cách sử dụng các câu lệnh điều kiện if lồng nhau qua các trường
hợp sau đây:
 TH1 (Figure 15.3): bố cục mã trong sơ đồ 15.3 sắp xếp rất rối và thiếu
hợp lý.

 TH2 (Figure 15.4): Cấu trúc bố cục mã dễ đọc hơn tuy việc lồng nhiều
câu điều kiện if else khiến việc kiểm tra tính đúng đắn của đoạn mã trở
nên khó khăn

 TH3 (Figure 15.5): Sử dụng phương pháp đơn giản hóa điều kiện if-if
phức tạp bằng toán tử && 
 Sử dụng câu lệnh lặp lồng nhau sao cho bố cục hợp lí và có thể đơn giản
hoá bằng các toán tử nếu có thể, không nên dùng quá 3 câu điều kiện if
lồng nhau.
5. Vấn đề quy chuẩn lập trình
- Quy chuẩn lập trình có thể vừa có lợi vừa gây khó khăn. Theo định nghĩa từ
trước với các module thực hiện nhiều và đa dạng các hoạt động không liên
quan đến nhau, thường đặt ra những luật như “mỗi module phải được viết
trong khoảng 35-50 dòng câu lệnh thực thi”. Hay nói một cách khác rõ ràng
hơn  là “lập trình viên phải báo với quản lý nếu muốn xây dựng một module
ít hơn 35 hoặc nhiều hơn 50 dòng lệnh thực thi”. Những quy chuẩn áp đặt
như vậy thường bị bỏ qua.
- Khác với với những quy chuẩn chung và phổ biến như với câu lệnh điều
kiện if không nên được đặt lồng nhau quá 3 lần. Lập trình viên thường
không tuân thủ theo những quy chuẩn lập trình mà họ không hiểu tại sao lại
được áp dụng. Hơn thế nữa, việc áp đặt các quy chuẩn lập trình có thể gây ra
sự mâu thuẫn nội bộ giữa quản lý và lập trình viên.
- Quy chuẩn lập trình có thể được đặt ra bởi đơn vị quản lý chất lượng phần
mềm. Việc sử dụng các quy chuẩn lập trình khiến giai đoạn bảo trì dễ dàng
hơn. Tuy nhiên việc áp dụng nó cũng khiến công đoạn lập trình trở nên khó
khăn hơn với những quy chuẩn quá ngặt nghèo và phức tạp sẽ khiến hiệu
suất và tiến độ làm việc của dự án bị chậm lại.
- Thay vì đó nếu có thể áp dụng quy chuẩn lập trình vào hệ thống kiểm tra tự
động mà máy tính có thể kiểm tra như: kiểm tra lệnh if, số dòng, hay mã
lệnh sử dụng, … sẽ nâng cao chất lượng phần mềm đáng kể.
6. Tái sử dụng các đoạn mã
- Việc tái sử dụng (reuse) là tương đối quan trọng trong ngành lập trình phần
mềm. Thời gian và chi phí có thể được tiết kiệm được đáng kể nếu có thể áp
dụng việc tái sử dụng lên các tiêu chí dự án như: yêu cầu chức, kế hoạch,
thiết kế, và các đoạn mã.
- Đặc biệt tái sử dụng các đoạn mã trong quá trình thực thi là vô cùng cần
thiết và quan trọng.
7. Phương pháp tích hợp
1. Khái niệm tích hợp
- Tích hợp là quá trình ghép các thành phần mã lập trình lại thành một chương
trình hoàn chỉnh.
- Trong quá trình tích hợp sẽ có khả năng phát sinh nhiều vấn đề như lỗi và
xung đột, đòi hỏi phải có những biện pháp tích hợp hiệu quả.
- Khái niệm:
  stub: là một đơn vị chương trình hoặc thành phần giả lập (thay thế cho
chương trình hoặc thành phần chưa hoàn thành) dùng để kiểm thử.
 driver: là một đoạn mã phục vụ mục đích kiểm thử gọi một thành phần
mã một hoặc nhiều lần, nếu có thể kiểm tra kết quả đầu ra.
- Xét sơ đồ tích hợp sau đây: 

 Nếu muốn kiểm thử thành phần mã a ta cần phải gộp và kiểm thử cả 3
thành phần mã b, c, d như một stub. 
 Nếu muốn kiểm thử thành phần mã h ta cần có một driver gọi nó.
 Tương tự nếu muốn kiểm thử thành phần mã d ta cần một driver và 2
stubs
 Điều này khiến quá trình thực thi trở nên khó khăn khi quá trình thực
hiện sẽ tốn rất nhiều công sức thiết lập stubs và drivers. Chưa kể, nếu quá
trình thực thi hoàn thành trước khi quá trình tích hợp, việc phát hiện và
định vị lỗi gần như không thể thực hiện với các dự án lớn.
 Đòi hỏi cần phải có sự kết hợp giữa kiểm thử đơn vị và tích hợp.
2. Tích hợp Top-Down
- Trong tích hợp top-down, nếu thành phần phía bên trên giao tiếp và gọi
thành phần bên dưới thì thành phần bên trên phải được thực thi và tích hợp
trước thành phần bên dưới.
- Ưu điểm của tích hợp top-down:
 Hỗ trợ cô lập và tìm lỗi: do các thành thành phần sẽ được thực thi và tích
hợp theo thứ tự từ trên xuống, khi thêm một thành phần hoặc liên kết một
thành phần khác vào bộ khung sẵn có, nếu có lỗi xảy ra ta có thể xác định
ngay lỗi có thể xảy ra ở thành phần liên kết với nó hoặc chính nó
 Có thể phát hiện lỗ hổng thiết kế sớm hơn: thứ tự sắp xếp thành thành
phần để kiểm thử và tích hợp sẽ chắc chắn rằng các thành phần logic sẽ
luôn luôn hoạt động ổn định.
- Nhược điểm của tích hợp top-down:
 Có khả năng các thành phần được tái sử dụng sẽ không được kiểm thử
tương đối như nhau nếu được giả sử là thành phần không sinh lỗi và sẽ bị
bỏ qua. Nhưng trên thực tế có thể xảy ra các trường hợp phát sinh các lỗi
không ngờ đến.
 Dễ gặp rủi ro khi các thành thành phần điều hành tái sử dụng mà không
được kiểm thử kỹ lưỡng. Lý do là các thành thành phần điều hành thường
ở tầng dưới của kiến trúc tích hợp top-down và số lần được kiểm thử sẽ ít
hơn so với tầng trên.
3. Tích hợp Bottom-up
- Trong tích hợp bottom-up, nếu thành phần bên trên giao tiếp với  và gọi
thành phần bên dưới thì thành phần bên dưới sẽ được thực thi và tích hợp
trước thành phần bên trên.
- Tích hợp bottom-up:
 Ưu điểm: những thành thành phần điều hành (operational artifacts) sẽ
được kiểm thử một cách toàn diện qua các driver kiểm thử. Vì thế giải
bài toán của tích hợp top-down bởi cơ chế bắt lỗi dễ dàng.
 Nhược điểm: các thành phần logic (logic artifacts) sẽ là các thành phần
được tích hợp cuối cùng. Do đó nếu có phát hiện lỗi thiết kế nghiêm
trọng nào đó trong giai đoạn cuối của dự án sẽ khiến quy trình làm việc
bị thay đổi hoặc cần trả một chi phí lớn cho việc tái thiết kế lại một phần
lớn của sản phẩm.
4. Tích hợp Sandwich
- Xét lược đồ 15.7 trên hình, ta thấy 6 thành phần logic (tô màu xám) được
tích hợp theo kiểu top-down, còn 7 thành phần điều hành (tô màu hồng)
được tích hợp theo kiểu bottom-up. 
- Việc áp dụng kiến trúc kiểu này bởi là khi nếu dùng duy nhất kiến trúc top-
down hoặc bottom-up đều sẽ không phù hợp với sản phẩm, giải pháp đưa ra
là phải phân vùng chúng. Hai phần được kiểm thử một cách riêng biệt theo
kiến trúc tích hợp của chúng, và khi ghép lại các giao thức giữa 2 nhóm sẽ
được kiểm thử từng phần đầy đủ.
5. Quá trình tích hợp của hướng đối tượng
- Sản phẩm thiết kế theo hướng đối tượng có thể được tích hợp theo cả bằng
cách top-down hoặc bottom-up.
 Tích hợp theo top-down: các stub sẽ được sử dụng cho mỗi phương pháp
giống với các module.
 Tích hợp theo bottom-up: các đối tượng độc lập sẽ được thực thi và tích
hợp đầu tiên, sau đó đến các đối tượng mà chúng giao tiếp gọi các đối
tượng khác, cứ tích hợp như vậy cho đến khi sản phẩm hoàn chỉnh.
 Tích hợp theo sandwich: tích hợp sandwich cũng có thể sử dụng tuỳ theo
từng thuộc tính từng thành phần, hay tuỳ theo thuộc tính của ngôn ngữ
lập trình. Có nhiều biến thể của tích hợp sandwich có thể được sử dụng
trong chương trình hướng đối tượng.
6. Quản lý tích hợp
- Khi quá trình tích hợp giữa các thành thành phần với nhau của mỗi lập trình
viên khác nhau có khả năng xảy ra sự xung đột hoặc không tương thích. Giả
sử lập trình viên thực thi đối tượng 01 sử dụng tài liệu thiết kế yêu cầu đối
tượng 01 truyền đến đối tượng 02 4 tham số, tuy nhiên theo tài liệu thiết kế
của lập trình viên thực thi đối tượng 02 chỉ có 3 tham số được truyền đến đối
tượng 02. Sự xung đột này đến từ việc chỉnh sửa lại tài liệu thiết kế mà thiếu
đi sự đồng bộ và thông báo cho các bên liên quan, khiến cho việc tích hợp
gặp vấn đề và tốn thêm thời gian và chi phí để giải quyết.
- Để giải quyết vấn đề không tương thích như trên, cả quá trình tích hợp phải
được vận hành bởi nhóm SQA (quản lý chất lượng phần mềm). Nhiệm vụ
của nhóm SQA là đảm bảo quá trình tích hợp phải diễn ra thuận lợi và hoàn
thành đồng thời quyết định xem thành thành phần nào được tích hợp theo
kiểu nào và phụ trách phân chia công việc tích hợp cho mỗi lập trình viên. 
Nhóm SQA phải lên kế hoạch kiểm thử tích hợp trong kế hoạch quản
lý dự án phần mềm, đồng thời có trách nghiệm thực thi kế hoạch đó. Kết
thúc giai đoạn tích hợp, tất cả những thành thành phần đã được kiểm thử
được tích hợp thành một sản phẩm hoàn chỉnh
8. Luồng công việc thực thi
- Nhiệm vụ của luồng công việc thực thi là triển khai đối tượng sản phẩm
phần mềm bằng ngôn ngữ lập trình được chọn. Chính xác hơn là, một sản
phẩm phần mềm lớn sẽ được phân mảnh ra thành các hệ thống nhỏ hơn, sau
đó được thực thi song song bởi các nhóm. Các hệ thống nhỏ hơn bao gồm
những thành phần hoặc các thành phần mã.
- Sau khi các thành phần mã đã được viết, lập trình viên sẽ kiểm thử thành
phần đó, khái niệm đó gọi là kiểm thử đơn vị (unit testing). Sau khi đã kiểm
thử xong, lập trình viên chuyển thành phần mã xuống đơn vị quản lý chất
lượng phần mềm để kiểm thử sâu hơn. Giai đoạn kiểm thử sau đó được thực
hiện trong luồng công việc kiểm thử.
9. Luồng công việc kiểm thử trong thực thi
-  Trong luồng công việc thực thi, nhiều loại kiểm thử sẽ được thực hiện:
 Kiểm thử đơn vị
 Tích hợp
 Kiểm thử sản phẩm
 Kiểm thử chấp nhận
- Các thành phần mã sẽ được kiểm thử bằng 2 loại kiểm thử:
 Kiểm thử không hợp cách (informal unit testing): thực hiện bởi lập trình
viên khi viết thành phần mã.
 Kiểm thử hợp cách (methodical unit testing): thực hiện bởi đơn vị quản
lý chất lượng phần mềm. Kiểm thử hợp cách có 2 loại: kiểm thử thực thi
và kiểm thử không thực thi.
10. Lựa chọn Test Case
 Việc lựa chọn test case rất quan trọng trong quá trình kiểm thử. Bởi vì sẽ có
vô vàn khả năng xảy ra và việc test hết tất cả các khả năng là vô cùng lãng
phí. Điều cần làm là cần xây dựng các test case một cách có hệ thống.
1. Kiểm thử dựa trên đặc điểm và kiểm thử đoạn mã
- Dữ liệu cho việc kiểm thử có thể được xây dựng bằng 2 cách:
 Kiểm thử đặc điểm: với cách tiếp cận này, thành phần sẽ bị bỏ qua, phần
quan tâm duy nhất để tạo test case là tài liệu đặc tả. Còn được gọi là kiểm
thử hộp đen (black-box), kiểm thử hành vi (behavioral), kiểm thử hướng
dữ liệu (data-driven), kiểm thử hàm (functional), kiểm thử hướng vào ra
(input/output driven).
 Kiểm thử mã: chỉ kiểm thử thành phần và phần tài liệu đặc tả sẽ bị bỏ qua
khi lựa chọn test case. Còn được gọi là kiểm thử hộp thuỷ tinh, kiểm thử
hộp trắng, kiểm thử có cấu trúc, kiểm thử hướng logic.
2. Tính khả thi của kiểm thử đặc điểm
- Ta xét: Các đặc tả cho dữ liệu một trạng thái của sản phẩm có các loại phiếu
giảm giá và các mẫu mã sản phẩm. Giả sử sản phẩm có 5 mẫu mã khác nhau
và có 7 loại phiếu giảm giá khác nhau cần được áp dụng. Kiểm thử tất cả các
tổ hợp giữa các mẫu mã sản phẩm và phiếu giảm giá ta được 35 test cases.
Sẽ là vô nghĩa nếu coi loại mẫu mã và phiếu giảm giá được tính toán và xử
lý ở trong 2 thành phần riêng biệt và nên được kiểm thử riêng biệt. Trong
kiểm thử hộp đen, sản phẩm được coi như một hộp đen - có nghĩa là cấu trúc
bên trong của nó hoàn toàn không được xét. 
- Với số lượng sản phẩm và số các loại phiếu giảm giá càng nhiều thì số lượng
kết quả giá sản phẩm tính ra càng vô cùng lớn. Tương tự với nếu xét nhiều
nhân tố hơn thì sẽ có vô số test case và rất tốn thời gian để có thể kiểm thử
được hết số lượng test case đó.
 Vì vậy kiểm thử đặc điểm đầy đủ là không khả thi trên thực tế bởi số
lượng test case khả thi là vô cùng lớn. Vì vậy kiểm thử mã được đưa vào
xem xét.
3. Tính khả thi của kiểm thử mã
- Hình thức phổ biến nhất của kiểm thử mã là kiểm thử tất cả các trường hợp
(các đường đi) trong đoạn mã. Để xem xét tính khả thi của kĩ thuật kiểm thử
này, xem xét một biểu đồ hoạt động sau:

- Mặc dù biểu đồ hoạt động trông có vẻ đơn giản, tuy nhiên xét kỹ hơn nó có
hơn 10^12 đường đi. Có 5 đường đi khả thi trong nhóm 6 hộp được tô màu
xám và sau đó được lặp 18 lần, ta tính được tổng số đường đi khả thi trong
biểu đồ hoạt động như sau: 

=> Với một lần lặp đã có số đường đi rất lớn, nếu xét những thành
phần có độ phức tạp và quy mô lớn hơn thì việc kiểm thử mã cũng
hoàn toàn không khả thi giống như kiểm thử đặc điểm.
- Kiểm thử đòi hỏi việc kiểm thử tất cả các đường đi khả thi. Tuy nhiên có
khả năng xảy ra khi kiểm thử tất cả các đường đi vẫn không thể phát hiện
được lỗi. Ta xét ví dụ sau:
- Đoạn mã này có nhiệm vụ kiểm tra tính tương đương của 3 số dựa trên một
logic sai: nếu trung bình của 3 số bằng số đầu tiên thì 3 số đó bằng nhau.
Dựa trên 2 test case cho sẵn thì đoạn mã này sẽ được cho là chạy đúng. Tuy
nhiên nếu dùng một test case khác chưa được xét là x = 2 y = 1, z = 3 thì
đoạn mã sẽ có lỗ hổng và sai lệch.
- Ví dụ trên cho ta thấy rằng xem xét tất cả các đường đi trong phần mềm là
không tin cậy, bởi vì phần mềm có thể tồn tại những đường đi gây sai lệch
chưa được xét. Tuy vậy, kiểm thử hướng đường đi là hoàn toàn hợp lệ 
bởi vì nó vốn dĩ không loại trừ việc chọn dữ liệu kiểm thử có thể phát hiện
lỗi.
 Bởi vì sự đa dạng tổ hợp dữ liệu, cả kiểm thử mã đầy đủ và kiểm thử đặc
điểm đầy đủ đều không khả thi. Cần có một phương pháp để có thể phát
hiện lỗi nhiều nhất có thể, mặc dù có thể không đảm bảo việc phát hiện
tất cả các lỗi. Một phương pháp hợp lý đó là sử dụng kiểm thử hộp đen
sau đó tạo thêm các test case bằng phương pháp hộp thuỷ tinh.
11. Kĩ thuật kiểm thử hộp đen
 Kiểm thử hộp đen đầy đủ có thể yêu cầu hàng tỷ test case. Vì vậy phương
thức yêu cầu đặt ra là để tạo một tập hợp các test case nhỏ, tối ưu hoá khả
năng phát hiện lỗi trong khi giảm khả năng lãng phí test case khi phát hiện
lỗi giống nhau, mỗi test case cần độc lập về khả năng phát hiện lỗi.
1. Kiểm thử tương đương và phân tích giá trị giới hạn 
- Giả sử một cơ sở dữ liệu chứa thông tin về các sản phẩm và có thể chứa các
bản ghi từ 1-16383. Khoảng từ 1-16383 được gọi là lớp tương đương bởi vì
nếu test case  một sản phẩm trong khoảng 1-16383 vẫn có thể hoạt động tốt,
thì test case những sản phẩm có khoảng xung quanh sẽ tương tự. Để chuẩn
xác hơn, ta sẽ chia số lượng bản ghi thành 3 lớp tương đương
 Nhỏ hơn 1 bản ghi
 Từ 1 đến 16383 bản ghi
 Lớn hơn 16383 bản ghi
- Kiểm thử cơ sở dữ liệu sử dụng kĩ thuật lớp tương đương sẽ yêu cầu mỗi test
case từ mỗi lớp tương đương sẽ được chọn.
- Để tối đa hoá khả năng tìm được lỗi nên sử dụng kĩ thuật phân tích giá trị
giới hạn. Trong khoảng từ (R1, R2) được liệt kê từ đầu ra hoặc đầu vào đặc
điểm, có 5 test cases nên được chọn, các giá trị nhỏ hơn R1, bằng R1, lớn
hơn R1 và nhỏ hơn R2, bằng R2, lớn hơn R2. Khi chỉ ra một đơn vị thuộc
một tập, thì 2 lớp tương đương nên được xét là lớp chứa đơn vị đó và lớp
không chứa đơn vị đó.
 Việc sử dụng lớp tương đương cùng với phân tích giá trị giới hạn nhằm
kiểm thử các đặc điểm đầu vào và đặc điểm đầu ra của một phương thức
cho việc sinh các tập dữ liệu test nhỏ với mục tiêu tìm ra nhiều nhiều lỗi
nhất có thể nếu các cách chọn test cases mạnh mẽ hơn không được áp
dụng.
2. Kiểm thử chức năng 
- Một dạng kiểm thử khác của kiểm thử hộp đen là xây dựng dữ liệu test dựa
trên chức năng của đoạn mã. Trong kiểm thử chức năng, mỗi đơn vị của
chức năng hoặc hàm được triển khai ở trong thành phần sẽ được định danh.
Một ví dụ điển hình của quản lý nhà kho sẽ có những hàm như:
 get_next_database_record
 determine_whether_quantity_on_hand_is_below_the_reorder_point
- Sau khi xác định được tất cả các hàm của thành phần, dữ liệu test sẽ được
xây dựng dựa trên các hàm khác nhau.  Từ đây, nếu các thành thành phần
bao gồm các hàm gọi các hàm con, kết nối bởi cấu trúc điều khiển của lập
trình cấu trúc, khi đó kiểm thử chức năng sẽ được thực hiện đệ quy.
- Trên thực tế, các hàm cha không được xây dựng theo một cấu trúc từ các
hàm con. Thay vì đó, các hàm con thường được đan xen vào nhau theo một
cách nào đó. Để có thể tìm được các lỗi và lỗ hổng trong trường hợp này,
phân tích chức năng cần được thực hiện theo một chu trình khá phức tạp. 
- Một nhân tố làm tăng tính phức tạp đó là các chức năng thường xuyên không
trùng hợp với các ranh giới thành phần. Vì thế sự phân biệt giữa kiểm thử
đơn vị và tích hợp trở nên một cách thiếu quan trọng hơn: một đoạn mã
không thể kiểm thử đồng thời nếu không kiểm thử một đoạn mã khác chứa
chức năng mà nó sử dụng. Vấn đề này cũng có thể xảy ra trong mô hình
hướng đối tượng khi một phương thức của một đối tượng gọi một phương
thức của đối tượng khác.
 Các quan hệ ngẫu nhiên giữa các thành phần theo cách nhìn của kiểm thử
chức năng có thể tạo ra những hậu quả không chấp nhận được cho việc
quản lý. Ví dụ như việc quản lý cột mốc dự án hoặc deadline có thể trở
thành một thứ khó xác định được, trở thành chướng ngại cho việc xác
định trạng thái của sản phẩm theo kế hoạch quản lý dự án phần mềm.
12. Case study Tổ chức MSG: Các test case kiểm thử
hộp đen
Test cases kiểm thử hộp đen cho case study Tổ chức MSG:
- Biểu đồ 15.13 và 15.14 minh hoạ các test cases kiểm thử hộp đen cho case
study tổ chức MSG. Đầu tiên xem xét các test cases nhận được từ các lớp
tương đương và phân tích giá trị giới hạn. Test case đầu tiên trong biểu đồ
15.13 kiểm tra xem sản phẩm có phát hiện lỗi nếu biến itemName (tên) của
một khoản đầu tư không bắt đầu bằng một chữ cái. 5 test cases tiếp theo kiểm
tra xem biến itemName có giá trị độ dài từ 1 – 25 kí tự hay không. Các test
cases tương tự còn lại kiểm tra các mô tả đặc điểm khác.
- Với kiểm thử hàm, có 10 hàm được liệt kê ở trong tài liệu đặc tả, như được
minh hoạ ở biểu đồ 15.14. Có tổng cộng 11 test cases liên quan đến việc sử
dụng các hàm này.
- Nên biết rằng các test cases ở đây có thể được phát triển ngay khi giai đoạn
phân tích hoàn thành. Lý do mà nó được đề cập ở nội dung luồng thực thi là
nó có liên quan đến chủ đề lựa chọn test case. Cấu tạo chính của mọi kế hoạch
kiểm thử nên là một quy định rằng kiểm thử hộp đen nên được thực hiện ngay
khi quá trình phân tích đã được phê duyệt, nhằm thuận tiện cho nhóm SQA
trong luồng công việc thực thi.
13. Kĩ thuật kiểm thử hộp thuỷ tinh
 Trong kĩ thuật kiểm thử hộp thuỷ tinh, các test cases được lựa chọn dựa trên
việc xem xét đoạn mã hơn là các đặc điểm. Có nhiều hình thức kiểm thử hộp
thuỷ tinh, bao gồm nhánh (branch), câu lệnh (statement), bao quát đường
dẫn (path coverage).
1. Kiểm thử cấu trúc
- Bao quát câu lệnh: dạng cơ bản nhất của kiểm thử đơn vị hộp thuỷ tinh là
bao quát câu lệnh (statement coverage): chạy hàng loạt các test cases trong
quá trình mỗi câu lệnh được thực thi ít nhất một lần. Hay có thể nói
Statement Coverage đảm bảo rằng tất cả các dòng lệnh trong mã nguồn đã
được kiểm tra ít nhất một lần. Nhược điểm của việc kiểm thử này là không
đảm bảo việc tất cả các kết quả của các nhánh sẽ được kiểm tra đúng cách.
- Bao quát nhánh: một phiên bản cải tiến của statement coverage đó là bao
quát nhánh (branch coverage), thực hiện bằng cách chạy hàng loạt các các
test cases để đảm bảo rằng tất cả các nhánh đều được kiểm tra ít nhất một
lần.
- Bao quát đường dẫn: phiên bản mạnh mẽ nhất của kiểm thử cấu trúc đó là
bao quát đường dẫn (path coverage), đó là kiểm tra mọi đường dẫn khả thi.
Như ta đã xét, với phần mềm ở trong vòng lặp sẽ có thể có số lượng đường
dẫn rất lớn. Vì vậy cần tìm ra một cách tối ưu khi giảm số lượng đường dẫn
cần xét trong khi tối đa hoá số lượng lỗi và lỗ hổng có thể phát hiện.  
 Một tiêu chí cho việc lựa chọn đường dẫn đó là chuỗi mã tuyến tính
(linear mã sequences). Để thực hiện, đầu tiên xác định một tập L từ đó
mà quản lí bước nhảy khi phần mềm chạy. Tập L sẽ bao gồm các điểm ra
và vào và các câu lệnh rẽ nhánh như lệnh if/go to. Các chuỗi mã tuyến
tính là các đường dẫn bắt đầu từ một phần tử của tập L và kết thúc cũng
tại một phần tử của tập L. Kĩ thuật này thực hiện thành công khi nó có
thể phát hiện nhiều lỗi và lỗ hổng trong khi không phải kiểm tra tất cả các
đường dẫn khả thi.
 Một cách khác để giảm số lượng đường dẫn phải kiểm tra đó là “tất cả
định nghĩa sử dụng bao quát đường dẫn  (all-definition-use-path
coverage)”. Tất cả các đường dẫn giữa định nghĩa của một biến và cách
sử dụng của định nghĩa đó đều được xác định bằng công cụ tự động. Sau
đó một test case sẽ được xây dựng cho mỗi đường dẫn đó.
- Nhược điểm: khi sử dụng kiểm thử cấu trúc, người thực hiện kiểm thử có thể
bỏ sót test case thực hiện việc kiểm tra một câu lệnh, nhánh hay đường dẫn
nào đó. Nguyên nhân có thể là do một đường dẫn không khả thi (dead mã) ở
trong phần mảnh mã, có nghĩa là đường dẫn đó không thể được thực thi với
bất kì dữ liệu đầu vào nào.
2. Chỉ số độ phức tạp (complexity metrics)
- Chỉ số đo độ phức tạp được tạo ra nhằm so sánh xem thành phần nào sẽ có
rủi ro sinh nhiều lỗi và lỗ hổng hơn. Nếu một thành phần có chỉ số đo độ
phức tạp vô cùng cao thì nên xem xét việc thiết kế và thực thi lại từ đầu bởi
chi phí sẽ ít hơn so với việc tìm và gỡ lỗi. 
- Các cách đo chỉ số độ phức tạp:
 Dựa trên số dòng mã: với các thành phần càng nhiều dòng thì sẽ có rủi ro
có càng nhiều lỗi.
 Độ phức tạp chu kỳ: được xác định dựa trên số lượng nhánh trong thành
phần. Độ phức tạp chu kỳ cũng có thể sử dụng như số đo cho số lượng
test cases cần cho kiểm thử cấu trúc bao quát nhánh của thành phần.
13. Kỹ thuật rà soát lướt qua và kiểm tra kỹ lưỡng
- Ưu điểm của kỹ thuật rà soát mã:
 Việc sử dụng 2 kỹ thuật phát hiện lỗ hổng mà không cần thực thi này
khiến cho việc phát hiện lỗi trở nên nhanh chóng, hoàn toàn và sớm hơn.
 Tăng hiệu suất tiến trình làm việc khi quá trình tích hợp xảy ra ít lỗi hơn.
 Có thể giảm thiểu lên đến 95% chi phí bảo trì [Crossman, 1982]
- Một lý do khác cho việc sử dụng rà soát mã là khi thực hiện kiểm thử thực
thi dựa trên test cases có chi phí cao.
 Kiểm thử thực thi sẽ rất tốn thời gian
 Rà soát mã sẽ phát hiện lỗi và giúp vá lỗi sớm hơn trong chu trình. so với
kiểm thử thực thi.
14. So sánh các kĩ thuật kiểm thử đơn vị
- Có rất nhiều nghiên cứu về các chiến lược kiểm thử đơn vị. Nghiên cứu
Myes[1978] so sánh ba loại kiểm thử hộp đen, kiểm thử kết hợp hộp đen và
hộp thuỷ tinh, rà soát mã với ba người. Nghiên cứu thực hiện kiểm thử một
sản phẩm phần mềm trong thử nghiệm được thực hiện bởi 59 lập trình viên
đã có kinh nghiệm. Cả ba kỹ thuật đều hiệu quả như nhau trong việc phát
hiện lỗi, nhưng rà soát mã  được cho là ít tốn kém chi phí hơn so với hai kĩ
thuật kiểm thử còn lại.
- Một nghiên cứu lớn được thực thi bởi Basili và Selby[1987] được tham gia
bởi 2 nhóm gồm 32 lập trình viên chuyên nghiệp và 42 sinh viên giỏi. Thử
nghiệm này so sánh kiểm thử hộp đen, kiểm thử hộp thuỷ tinh và kiểm một
người. Mỗi nhóm sẽ kiểm thử 3 sản phẩm phần mềm, mỗi lần dùng một kĩ
thuật kiểm thử khác nhau, đảm bảo rằng không có ai thử nghiệm trên một
sản phẩm nhiều hơn một cách. Kết quả nhận được rằng nhóm lập trình viên
chuyên nghiệp phát hiện lỗi nhiều hơn bằng cách rà soát mã so với 2 cách
còn lại, và tiến độ phát hiện lỗi cũng nhanh hơn. Bên nhóm sinh viên được
chia làm 2 nhóm nhỏ hơn, ở một nhóm không thấy có sự khác biệt đáng kể
về hiệu quả của 3 cách, ở nhóm còn lại thấy kiểm thử hộp đen và hiệu quả
như nhau nhưng đều vượt qua kiểm thử hộp thuỷ tinh. Tuy nhiên tiến độ
phát hiện lỗi đều như nhau cho mỗi cách. Tóm lại, rà soát mã sẽ giúp việc
phát hiện lỗi giao diện tốt hơn 2 kĩ thuật còn lại, trong khi kiểm thử hộp đen
là tốt nhất khi tìm các lỗi và lỗ hổng điều khiển.
 Thử nghiệm trên cho thấy rà soát cũng có khả năng phát hiện lỗi như
kiểm thử hộp đen và hộp thuỷ tinh mặc dù kiểm thử hộp đen và hộp thuỷ
tinh có tính hiệu quả hơn so với việc kiểm . Tuy nhiên, cũng có vài thử
nghiệm cho thấy việc kết hợp thêm kiểm  sẽ tìm được các loại lỗi đa dạng
hơn. Nói cách khác, các kĩ thuật này bổ sung lẫn nhau và cần được sử
dụng trong quá trình phát triển của mọi sản phẩm phần mềm.
15. Kĩ thuật kiểm thử Cleanroom
- Kỹ thuật kiểm thử Cleanroom là tập hợp của nhiều kĩ thuật phát triển phần
mềm khác nhau, bao gồm một mô hình chu trình tăng dần, các kĩ thuật chính
thức cho việc phân tích và thiết kế và các kĩ thuật kiểm thử đơn vị không
thực thi như rà soát lướt qua và kiểm tra kỹ lưỡng. Một tiêu chí quan trọng
của Cleanroom đó là thành phần sẽ không được biên dịch cho đến khi hoàn
tất kiểm tra và đã thực hiện các kĩ thuật kiểm thử không thực thi.
- Kĩ thuật kiểm thử Cleanroom cũng có thể áp dụng cho những dự án phần
mềm lớn và có những kết quả khá ấn tượng. Một thước đo liên quan đó là tỉ
lệ lỗi (testing fault rate) được tính bằng cách tính trung bình số lỗi có trên
một KLOC (1000 dòng mã). Thước đo này được sử dụng phổ biến cùng
Cleanroom thay vì các kĩ thuật phát triển phần mềm truyền thống khác.
- So sánh kĩ thuật kiểm thử truyền thống và kỹ thuật Cleanroom:
 Kĩ thuật kiểm thử truyền thống: các lỗi phát hiện bởi lập trình viên trong
quá trình phát triển mã sẽ không được ghi lại. Các lỗi chỉ được ghi lại khi
đoạn mã được gửi đến đơn vị quản lý chất lượng phần mềm SQA khi quá
trình test kỹ hơn được thực hiện
 Kỹ thuật Cleanroom: các lỗi được ghi lại ngay từ thời điểm biên dịch cho
đến thời điểm thực hiện các kĩ thuật kiểm thử thực thi.
16.  Vấn đề tiềm ẩn khi kiểm thử đối tượng
- Phần mềm hướng đối tượng có cấu trúc và hành vi khác so với phần mềm
thực hiện bằng ngôn ngữ hướng thủ tục. Phần mềm hướng đối tượng không
phân rã chức năng trong các thủ tục riêng biệt, nó có các đối tượng và các
lớp, sự tương tác với nhau thông qua gửi thông báo và dùng chung các định
nghĩa thông qua sự thừa kế.
- Sử dụng hướng đối tượng trong dự án được cho là có thể có những ưu điểm
cho việc giảm số lượng công việc kiểm thử:
 Tái sử dụng quá thừa kế là thế mạnh của lập trình hướng đối tượng: khi
một lớp đã được kiểm tra, đối số sẽ được tiếp tục, khiến việc kiểm tra lại
là không cần thiết
 Các phương thức mới ở lớp con cần được kiểm tra, nhưng các phương
thức được kế thừa thì không cần
 Trên thực tế, những ưu điểm trên chỉ đúng một phần, kiểm thử đối tượng
có thể tồn tại những vấn đề mà chỉ hướng đối tượng mới có.
- Xét các vấn đề với kiểm thử lớp và kiểm thử đối tượng
 Theo định nghĩa, một lớp (class) là một kiểu dữ liệu trừu tượng cho phép
việc kế thừa, và đối tượng được định nghĩa bởi lớp. Có nghĩa là một lớp
không thể cách nào có thể kiểm thử thực thi mà chỉ có thể được thực thi
thông qua đối tượng của nó. Lớp chỉ có thể kiểm thử thông qua các kĩ
thuật kiểm thử không thực thi.
  Một object được định nghĩa có thể có nhiều cho đến ít phương thức. Sẽ
có những phương thức thay đổi trạng thái dữ liệu state của object. Khi ta
muốn kiểm tra các phương thức đó thì cần ít nhất phải gửi thêm một câu
yêu cầu lấy dữ liệu để xem phương thức đó có hoạt động đúng hay
không. Vấn đề nảy sinh khi đối tượng không bao gồm các phương thức
hỗ trợ việc xác định giá trị state. Một cách xử lý đó là thêm một phương
thức chỉ phục vụ riêng cho việc xác định giá trị và chỉ khả dụng cho mục
đích kiểm thử
 Một phương thức được kế thừa có thể vẫn phải được kiểm tra lại ngay kể
cả khi nó đã được kiểm tra kĩ ở lớp cha. 
- Để chứng minh vấn đề với phương thức được kế thừa ta một cây kế thừa
sau:
 
- Trong ví dụ trên ta thấy 2 phương thức chính đó là printNode và phương
thức  displayNodeContents có sử dụng phương thức printRoutine. Lớp
BinaryTreeLớp kế thừa lớp cha (RootedTreeLớp) sẽ kế thừa phương thức 
printNode từ RootedTreeLớp.printRoutine và ghi đè phương thức
displayNodeContents.
- Vấn đề nảy sinh khi lớp thứ ba BalancedBinaryTreeLớp kế thừa lớp
BinaryTreeLớp và ghi đè phương thức printRoutine. Tuy nhiên phương
thức displayNodeContents được kế thừa từ 
BinaryTreeLớp. displayNodeContents lại sử dụng phương thức
printRoutine từ RootedTreeLớp.printRoutine thay vì
BalancedBinaryTreeLớp.printRoutine.
 Vì thế cho dù đã kiểm thử kĩ càng phương thức từ BinaryTreeLớp, môi
trường của lớp BalancedBinaryTreeLớp vẫn phải kiểm thử lại từ đầu.
Công việc này lại càng phức tạp hơn vì theo lý thuyết có nhiều lý do tại
sao chúng cần được kiểm thử lại với nhiều test cases khác nhau.
- Sử dụng hướng đối tượng giảm tải công việc kiểm thử: 
 Vấn đề chỉ có thể xảy ra thông qua sự tương tác giữa các phương thức 
 Có thể hoàn toàn phát hiện vấn đề thông qua việc kiểm thử với các test
cases khác nhau
 Các lớp con cần được kiểm thử lại cùng với các phương thức có sự tương
tác với các phương thức khác. 
17.  Các khía cạnh quản lý của kiểm thử đơn vị
- Trong quá trình phát triển, việc quyết định xem một phần mảnh mã được
dành bao nhiêu thời gian, chi phí là vô cùng quan trọng. Kỹ thuật phân tích
chi phí và lợi ích (cost-benefit analysis) trở thành một công cụ hữu ích trong
việc giải quyết bài toán kinh tế trong dự án phần mềm. Ví dụ như việc xem
xét chi phí kiểm soát chất lượng có vượt quá lợi ích của việc đảm bảo sản
phẩm có thoả mãn đặc điểm đề ra hay không, hay so sánh chi phí chạy thêm
nhiều test case để kiểm thử chuyên sâu với chi phí rủi ro nếu phần mềm sản
phẩm chưa được kiểm thử kỹ lưỡng.
- Một phương pháp tiếp cận khác để quyết định có nên kiểm thử một phần
mảnh có nên tiếp tục hoặc đánh giá số lượng lỗi gọi là phân tích độ tin cậy.
Phương pháp phân tích độ tin cậy có thể được sử dụng để cung cấp thông số
ước tính còn bao nhiêu lỗi hoặc lồ hổng còn tồn tại.
- Có vô số phương pháp để xác định thông số ước tính của số lỗi hoặc lỗ hổng
còn tồn tại nhưng chúng đều có một ý tưởng chung, ta xét ví dụ dưới đây:
Giả sử một thành phần đã được kiểm thử trong vòng 1 tuần. 23 lỗi được tìm
thấy vào ngày thứ hai, thứ ba 7 lỗi, thứ tư 5 lỗi, thứ năm 2 lỗi, và không có
lỗi nào vào ngày thứ sáu. Bởi vì số lượng lỗi giảm đều đặn từ 23 lỗi một
ngày xuống còn không lỗi nào, ta có thể xác định gần như mọi lỗi đã được
tìm thấy và có thể dừng việc kiểm thử.
18.  Vấn đề tái thực thi hay gỡ lỗi 
- Khi nhóm quản lý chất lượng phần mềm phát hiện lỗi, thành phần mã bị lỗi
sẽ được chuyển giao cho lập trình viên đã viết nó để gỡ lỗi, quá trình đó có
thể gọi là phát hiện lỗi và điều chỉnh đoạn mã. 
- Trong một số trường hợp, thành phần mã bị lỗi nên được bỏ đi và thiết kế
cũng như thực thi lại từ đầu. Để hiểu tại sao điều này là cần thiết, ta xem xét
biểu đồ sau:
 Biểu đồ thể hiện một khái niệm rằng khả năng còn tồn đọng những lỗi trong
một thành phần tỷ lệ thuận với số lỗi đã được tìm thấy. Để giải thích cho
điều này, ta giả sử có 2 thành phần mã a1 và a2 có độ dài như nhau và cả hai
đều đã được kiểm thử cùng một lượng thời gian như nhau. Cho rằng chỉ có 2
lỗi được tìm thấy ở thành phần a1, trong khi đó có 48 lỗi được tìm thấy ở
thành phần a2, vì vậy rất có khả năng thành phần a2 sẽ còn tồn tại nhiều lỗi
hơn cả thành phần a1.
 Việc kiểm thử bổ sung hay gỡ lỗi một thành phần có nhiều lỗi có thể tốn
rất nhiều thời gian và chi phí. Để thuận lợi cho việc phát triển trước mắt
và lâu dài, tốt hơn nên bỏ thành phần đó và xây dựng lại từ đầu.
- Tuy vậy, sự phân bố của các lỗi giữa các module là không đồng dạng với nhau.
Theo một nghiên cứu của Endres[1975] khi xem xét 212 module có 512 lỗi
được phát hiện, thì chỉ có một lỗi được tìm thấy trong 112 module, các module
còn lại tồn tại một số lượng lỗi nhất định từ 14 đến 28 lỗi. Những module bất ổn
như vậy nên được xem xét bỏ đi và thực thi lại từ đầu.
- Một cách cho công việc quản lý nếu gặp các trường hợp như trên đó là định ra
giới hạn lỗi tối đa có thể được phát hiện bởi một thành phần, nếu vượt quá giới
hạn này, thành phần sẽ bị bỏ đi và nên được thực hiện lại bởi lập trình viên có
chuyên môn cao hơn. Giới hạn tối đa này thay đổi tuỳ theo ứng dụng và các
thành phần khác nhau. Nếu xét một thành phần mã có nhiệm vụ đọc dữ liệu từ
cơ sở dữ liệu và xử lý sẽ có giới hạn lỗi nhỏ hơn nhiều so với một thành phần
phức tạp trong hệ thống hỗ trợ ngắm bắn của xe tăng. Một cách để quyết định
xem giới hạn lỗi cho một thành phần là tham khảo số lỗi từ các thành phần
tương tự cần bảo trì. Nhưng việc loại bỏ thành phần nếu vượt quá giới hạn lỗi
vẫn phải được đảm bảo.
19.  Kiểm thử tích hợp
- Kiểm thử tích hợp: mỗi thành phần cần phải được kiểm thử trước khi được
tích hợp. Điểm mấu chốt ở đây là thành phần mới cần phải được kiểm thử
như bằng phương pháp chuyên dụng và sau đó cần phải kiểm tra để đảm các
thành phần đã được tích hợp hoạt động bình thường như cũ.
- Công cụ CASE: là một loại gói phần mềm hỗ trợ việc thiết kế và thực thi
phần mềm.
- Về cơ bản, quá trình kiểm thử phần mềm có thể được đơn giản hoá bằng
cách lưu trữ dữ liệu đầu vào cho test case trong một file. Phần mềm sau đó
được khởi chạy, và lấy các dữ liệu liên quan cần thiết đã được lưu trữ. Với
sự hỗ trợ của công cụ CASE, cả chu trình này đều có thể được tự động hoá.
Công cụ CASE chạy từng test case đã được thiết lập và so sánh với kết quả
mong muốn, sau đó gửi báo cáo lại cho từng test case. Các test cases sau đó
được lưu trữ lại cho mục đích kiểm thử hồi quy bất cứ khi nào phần mềm
được chỉnh sửa. SilkTest là một ví dụ cho công cụ hỗ trợ việc này.
- Vấn đề đặt ra khi phần mềm có một giao diện người dùng, thì cách tiếp cận
như trên sẽ không khả thi. Dữ liệu test như mở một menu hay nhấp một nút
không thể lưu trữ trên file như những dữ liệu thông thường và nếu kiểm thử
giao diện bằng cách thủ công thì sẽ rất tốn thời gian và công sức. Giải pháp
cho vấn đề này là sử dụng các công cụ CASE đặc biệt hỗ trợ việc ghi lại các
thao tác nhấp chuột, gõ phím,… Giao diện sẽ được kiểm thử thủ công chỉ
một lần để tạo kịch bản cho file dữ liệu test sau đó dữ liệu sẽ được sử dụng
cho những lần kiểm thử tự động sau. Một số công cụ case hỗ trợ kiểm thử
giao diện là QARun và XRunner.
20. Thử nghiệm sản phẩm
Có hai loại phần mềm chính:
 phần mềm thương mại bán sẵn (COTS) : Mục đích của thử nghiệm sản
phẩm COTS: là để đảm bảo rằng toàn bộ sản phẩm không có lỗi. Khi quá
trình kiểm tra sản phẩm hoàn tất, sản phẩm sẽ trải qua quá trình kiểm tra
alpha và beta.
 Phần mềm tùy chỉnh trải qua quá trình thử nghiệm sản phẩm hơi khác
nhau.Nhóm SQA phải đảm bảo rằng sản phẩm sẽ không thất bại trong
quá trình kiểm tra chấp nhận. Việc một sản phẩm không thể vượt qua
kiểm tra chấp nhận sẽ gây tác động xấu đến tổ chức phát triển.
Nhóm SQA phải kiểm thử sản phẩm gần giống với kiểm thử chấp nhận:
 Kiểm thử hộp đen cho toàn bộ sản phẩm phải được chạy.
 Kiểm thử độ bền của toàn bộ sản phẩm. Phải chắc chắn rằng độ bền của
các tạo tác và lớp mã riêng lẻ đã được kiểm tra trong quá trình tích hợp.
Ngoài ra, sản phẩm phải được thử nghiệm chắc chắn để đảm bảo rằng
nó hoạt động chính xác khi hoạt động dưới mức tải cao nhất. Sản phẩm
cũng phải được thử nghiệm âm lượng, chẳng hạn như đảm bảo rằng nó
có thể xử lý các tệp đầu vào lớn.
 kiểm tra xem sản phẩm có thỏa mãn tất cả các ràng buộc của nó hay
không.
 Kiểm tra tất cả tài liệu sẽ được chuyển giao cho khách hàng cùng với
mã, phải kiểm tra xem tài liệu có phù hợp với các tiêu chuẩn được quy
định trong SPMP hay không.
Khi nhóm SQA đảm bảo với ban quản lý rằng sản phẩm có thể xử lý bất cứ
thứ gì mà người kiểm tra chấp nhận có thể ném vào nó thì sản phẩm (đó là mã
cộng với tất cả tài liệu) được giao cho tổ chức khách hàng để kiểm tra chấp
nhận.

21. Kiểm thử chấp nhận


Mục đích: để khách hàng xác định xem sản phẩm có thực sự đáp ứng các
thông số kỹ thuật như nhà phát triển yêu cầu hay không.
 Kiểm thử chấp nhận được thực hiện bởi
 tổ chức khách hàng
 nhóm SQA với sự có mặt của đại diện khách hàng 
 hoặc một nhóm SQA độc lập được khách hàng thuê. 
Bốn thành phần chính của kiểm tra chấp nhận: đánh giá tính đúng đắn, độ
bền, hiệu suất và tài liệu) là những gì được nhà phát triển kiểm thử trong quá
trình thử nghiệm sản phẩm.
Kiểm thử chấp nhận phải được thực hiện trên dữ liệu thực tế hơn là trên dữ
liệu kiểm tra. Cho dù bản chất các trường hợp thử nghiệm được thiết lập tốt
như thế nào thì chúng vẫn là nhân tạo. Dữ liệu thử nghiệm quan trọng hơn
phải phản ánh trung thực dữ liệu thực tế tương ứng nhưng trong thực tế không
phải lúc nào cũng vậy. Các trường hợp thử nghiệm kết quả không phản ánh
đúng dữ liệu thực tế dẫn đến sản phẩm được thử nghiệm không phù hợp. 
Khi một sản phẩm mới thay thế một sản phẩm hiện có, sản phẩm mới phải
được cài đặt để chạy song song với sản phẩm hiện có. Lý do là có thể sản
phẩm mới bị lỗi theo một cách nào đó. Sản phẩm hiện có hoạt động chính xác
nhưng không đầy đủ ở một số khía cạnh. Nếu sản phẩm hiện có được thay thế
bằng một sản phẩm mới hoạt động không chính xác thì khách hàng sẽ gặp rắc
rối. Do đó cả hai sản phẩm phải chạy song song cho đến khi khách hàng hài
lòng thì sản phẩm mới có thể đảm nhiệm các chức năng của sản phẩm hiện
có. Chạy song song thành công kết thúc kiểm tra chấp nhận và sản phẩm hiện
có có thể ngừng hoạt động.
Khi sản phẩm đã vượt qua kiểm tra chấp nhận, nhiệm vụ của các nhà phát
triển đã hoàn thành. Bất kỳ thay đổi nào hiện được thực hiện đối với sản phẩm
đó đều cấu thành việc bảo trì sau giao hàng.

22. Quy trình thử nghiệm: Nghiên cứu điển hình về MSG
Foundation
Các triển khai C++ và Java của sản phẩm MSG Foundation (có sẵn để tải
xuống tại www.mhhe.comSchach) đã được kiểm tra dựa trên các trường hợp
kiểm tra hộp đen của Hình 15.13 và 15.14 cũng như các trường hợp kiểm tra
hộp kính của Vấn đề 15.35 đến 15.39
23. Công cụ CASE để thực hiện
1. Công cụ CASE cho Quy trình Phần mềm Hoàn chỉnh
Một workbench hỗ trợ một hoặc hai hoạt động trong quy trình phần mềm bao
gồm:
 Thiết bị CASE đơn giản nhất là một công cụ đơn lẻ như trình kiểm tra
giao diện trực tuyến hoặc công cụ xây dựng.
 Các công cụ như kiểm soát cấu hình hoặc mã hóa. 
Tuy nhiên, một workbench như vậy có thể không cung cấp thông tin quản lý
ngay cả đối với một phần giới hạn của quy trình phần mềm mà nó có thể áp
dụng cho riêng dự án nói chung.
→Các tổ chức phát triển phần mềm nên sử dụng một môi trường cung cấp sự
hỗ trợ của máy tính. Nhưng chi phí của một môi trường có thể lớn. Đối với tổ
chức nhỏ hơn, một workbench hoặc có lẽ chỉ một bộ công cụ là đủ. Nhưng
nếu có thể, một môi trường tích hợp nên được sử dụng để hỗ trợ nỗ lực phát
triển và duy trì.
2. Môi trường phát triển tích hợp
Môi trường phát triển tích hợp trong ngữ cảnh CASE nghĩa là tích hợp giao
diện người dùng. Đó là tất cả các công cụ trong môi trường chia sẻ một giao
diện người dùng chung. Ý tưởng là nếu tất cả các công cụ có hình thức trực
quan giống nhau thì người sử dụng một công cụ sẽ gặp ít khó khăn trong việc
học và sử dụng một công cụ khác trong môi trường. Ví dụ: Macintosh là một
dòng sản phẩm máy tính cá nhân, nơi hầu hết các ứng dụng đều có giao diện
giống nhau
Thuật ngữ tích hợp công cụ có nghĩa là tất cả các công cụ giao tiếp thông qua
cùng một định dạng dữ liệu. Ví dụ: trong Workbench của Lập trình viên
UNIX, giả định rằng tất cả dữ liệu đều ở dạng một luồng ASCII, thì có thể dễ
dàng kết hợp hai công cụ bằng cách hướng luồng đầu ra từ công cụ này sang
luồng đầu vào của công cụ kia. Eclipse là một môi trường mã nguồn mở để
tích hợp công cụ.
Môi trường dựa trên kỹ thuật: 
 chỉ hỗ trợ một kỹ thuật cụ thể để phát triển phần mềm hơn là một quy
trình hoàn chỉnh.
 cung cấp hỗ trợ đồ họa cho phân tích và thiết kế và kết hợp một từ điển
dữ liệu. 
 Một số kiểm tra tính nhất quán.
 Hỗ trợ quản lý quá trình phát triển thường xuyên được đưa vào môi
trường. 
Hầu hết tất cả các môi trường hướng đối tượng hiện hỗ trợ UML.
3. Môi trường cho các ứng dụng kinh doanh
Môi trường cho các ứng dụng kinh doanh nhấn mạnh tính dễ sử dụng. Đặc
biệt, môi trường kết hợp một số màn hình tiêu chuẩn và chúng có thể được
sửa đổi liên tục thông qua trình tạo GUI thân thiện với người dùng. Một tính
năng phổ biến của những môi trường như vậy là một trình tạo mã. Mức độ
trừu tượng thấp nhất của một sản phẩm sau đó là thiết kế chi tiết.
Các ngôn ngữ để chỉ định thiết kế chi tiết cũng có thể là các ngôn ngữ lập
trình của tương lai. Mức độ trừu tượng của các ngôn ngữ lập trình đã tăng từ
mức máy vật lý của ngôn ngữ thế hệ thứ nhất và thứ hai lên mức máy tính
trừu tượng của ngôn ngữ thế hệ thứ ba và thứ tư. Ngày nay, mức trừu tượng
của các môi trường kiểu này là mức thiết kế chi tiết, mức di động. Mục 15.2
nêu rõ rằng một mục tiêu khi sử dụng ngôn ngữ thế hệ thứ tư là mã ngắn hơn
và do đó phát triển nhanh hơn và bảo trì sau giao hàng dễ dàng hơn. Việc sử
dụng trình tạo mã còn đưa những mục tiêu này đi xa hơn ở chỗ lập trình viên
phải cung cấp ít chi tiết hơn cho trình tạo mã so với trình thông dịch hoặc
trình biên dịch cho 4GL. Do đó, người ta mong đợi rằng việc sử dụng các môi
trường hướng tới doanh nghiệp có hỗ trợ trình tạo mã sẽ làm tăng năng suất.
Một số môi trường thuộc loại này hiện có sẵn bao gồm Oracle Developer
Suite. Lưu ý đến quy mô của thị trường dành cho môi trường CASE định
hướng kinh doanh, có khả năng nhiều môi trường kiểu này sẽ được phát triển
trong những năm tới.
4. Cơ sở hạ tầng công cụ công cộng
Một cơ sở hạ tầng để hỗ trợ các công cụ CASE là PCTE. Mặc dù có tên là
portable common tool environment (tạm dịch môi trường công cụ công
cộng) nhưng nó không phải là một môi trường. PCTE là một cơ sở hạ tầng
cung cấp các dịch vụ cần thiết của các công cụ CASE giống như cách mà
UNIX cung cấp các dịch vụ hệ điều hành cần thiết cho các sản phẩm của
người dùng. (Từ phổ biến trong PCTE có nghĩa là công khai hoặc không có
bản quyền.)
PCTE đã được chấp nhận rộng rãi. Ví dụ: PCTE và các giao diện C và Ada
đối với PCTE đã được thông qua như là Tiêu chuẩn ISOIEC 13719 vào năm
1995. Việc triển khai PCTE bao gồm các triển khai của Emeraude và IBM.
5. Các vấn đề tiềm ẩn với môi trường
Không có một môi trường nào là lý tưởng cho tất cả các sản phẩm và tất cả
các tổ chức thì bất kỳ ngôn ngữ lập trình nào cũng có thể được coi là tốt
nhất. Môi trường nào cũng có điểm mạnh và điểm yếu của nó và việc lựa
chọn một môi trường không phù hợp có thể còn tệ hơn là không sử dụng môi
trường nào cả.
Tình huống tồi tệ hơn xảy ra khi một tổ chức chọn bỏ qua lời khuyên: việc sử
dụng môi trường CASE nên được tránh thực hiện cho đến khi tổ chức đạt
được CMM cấp độ 3. Tất nhiên mọi tổ chức nên sử dụng các công cụ CASE
và nói chung là có rất ít tác hại trong việc sử dụng workbench. Tuy nhiên, một
môi trường áp đặt một quy trình phần mềm tự động cho một tổ chức sử dụng
nó. Nếu một quy trình tốt đang được sử dụng mà tổ chức ở cấp độ 3 trở lên thì
việc sử dụng môi trường sẽ hỗ trợ trong tất cả các khía cạnh của sản xuất phần
mềm bằng cách tự động hóa quy trình đó. Nhưng nếu tổ chức đang ở cấp độ 1
hoặc thậm chí là cấp độ 2 do khủng hoảng điều khiển thì không có quy trình
nào như vậy được thực hiện. Việc tự động hóa quy trình không tồn tại này là
sự ra đời của môi trường CASE (trái ngược với công cụ CASE hoặc bàn làm
việc CASE) chỉ có thể dẫn đến hỗn loạn.

24. Công cụ CASE cho Quy trình Kiểm tra


Thử nghiệm đơn vị: Các khung công tác kiểm thử XUnit bao gồm JUnit cho
Java và CppUnit cho C++ là một tập hợp các công cụ tự động mã nguồn mở
để kiểm thử đơn vị, chúng được sử dụng để kiểm tra lần lượt từng lớp. Một
tập hợp các trường hợp kiểm tra được chuẩn bị và công cụ kiểm tra xem mỗi
tin nhắn được gửi đến lớp có kết quả là câu trả lời mong đợi được trả về hay
không. Các công cụ thương mại thuộc loại này được sản xuất bởi nhiều nhà
cung cấp bao gồm cả Parasoft.
Thử nghiệm tích hợp: Ví dụ về các công cụ thương mại hỗ trợ kiểm tra tích
hợp tự động (cũng như kiểm thử đơn vị) bao gồm SilkTest và IBM Rational
Functional Tester. Các công cụ thuộc loại này thường gộp chung các trường
hợp thử nghiệm đơn vị và sử dụng tập hợp các trường hợp thử nghiệm kết quả
để thử nghiệm tích hợp và thử nghiệm hồi quy. Trong quá trình làm việc thử
nghiệm, điều cần thiết là cấp quản lý phải biết tình trạng của tất cả các khuyết
tật. Đặc biệt, điều quan trọng là phải biết những khiếm khuyết nào đã được
phát hiện nhưng chưa được sửa chữa. Công cụ theo dõi lỗi nổi tiếng nhất là
Bugzilla, một sản phẩm mã nguồn mở.
Điều quan trọng là phải phát hiện ra các lỗi mã hóa càng sớm càng tốt. Một
cách để đạt được điều này là sử dụng công cụ CASE để phân tích mã tìm
kiếm các lỗi hoặc cấu trúc phổ biến về cú pháp và ngữ nghĩa có thể dẫn đến
các vấn đề sau này. Ví dụ về các công cụ như vậy bao gồm lint Số liệu mã
nguồn IBM Rational Purify Suns Jackpot và ba công cụ của Microsoft PREfix
PREfast và SLAM.
Dự án Hyades (dự án công cụ kiểm tra và hiệu suất Eclipse) là một môi
trường theo dõi và giám sát kiểm tra tích hợp mã nguồn mở hiện có thể được
sử dụng với Java và C++. Nó có cơ sở cho nhiều loại công cụ kiểm tra khác
nhau. Khi ngày càng nhiều nhà cung cấp công cụ điều chỉnh các công cụ của
họ để hoạt động trong Eclipse, người dùng sẽ có thể chọn từ nhiều lựa chọn
công cụ kiểm tra hơn, tất cả chúng sẽ hoạt động cùng với nhau.

25. Các chỉ số cho quy trình thực thi


Một số chỉ số độ phức tạp khác nhau cho quy trình thực thi được thảo luận
trong Phần 15.13.2, bao gồm các dòng mã và độ phức tạp theo chu kỳ của
McCabe. 
Từ quan điểm thử nghiệm, các chỉ số liên quan bao gồm tổng số trường hợp
thử nghiệm và số trường hợp thử nghiệm dẫn đến thất bại. Các số liệu thống
kê lỗi thông thường phải được kiểm tra chính xác để kiểm tra mã. Tổng số lỗi
rất quan trọng, bởi vì nếu số lỗi được phát hiện trong phần mềm mã vượt quá
mức tối đa được xác định trước, thì cấu phần mã đó phải được thiết kế lại và
giải mã, như đã thảo luận trong Phần 15.19. Ngoài ra, cần lưu giữ các số liệu
thống kê chi tiết về các loại lỗi được phát hiện. Các dạng lỗi điển hình bao
gồm hiểu sai thiết kế, thiếu khởi tạo và sử dụng các biến không nhất quán. Dữ
liệu lỗi có thể được đưa vào danh sách kiểm tra để sử dụng trong quá trình
kiểm tra mã của các sản phẩm trong tương lai.
Một số chỉ số đo cụ thể đối với mô hình hướng đối tượng đã được đưa ra, ví
dụ, chiều cao của cây kế thừa [Chidamber và Kemerer, 1994]. Nhiều số liệu
trong số này đã được đặt câu hỏi về cả lý thuyết và thực nghiệm [Binkley và
Schach, 1996; Năm 1997]. Hơn nữa, Alshayeb và Li [2003] đã chỉ ra rằng,
trong khi các số liệu hướng đối tượng có thể dự đoán tương đối chính xác số
lượng dòng mã được thêm vào, thay đổi và xóa trong các quy trình nhanh,
chúng rất ít được sử dụng trong việc dự đoán các công việc nhỏ giống nhau
trong một quy trình dựa trên khuôn khổ (xem Phần 8.5.2). Nó vẫn được chỉ ra
rằng cần có các số liệu hướng đối tượng cụ thể, trái ngược với các số liệu cổ
điển có thể được áp dụng như nhau cho phần mềm hướng đối tượng. 

26. Một số thách thức đối với quy trình thực thi
Nghịch lý thay, một thách thức lớn của quy trình thực thi phải được đáp ứng
trong quy trình thực hiện trước đó. Như đã giải thích trong Chương 8, tái sử
dụng lại mã là một cách hiệu quả để giảm chi phí phát triển phần mềm và thời
gian giao hàng. Tuy nhiên, rất khó để đạt được khả năng tái sử dụng mã nếu
nó được thử quá muộn trong quy trình thực hiện. 
Ví dụ, giả sử quyết định được đưa ra để triển khai một sản phẩm bằng ngôn
ngữ L. Bây giờ, sau khi một nửa mã tạo tác đã được triển khai và thử nghiệm,
ban quản lý quyết định sử dụng gói P cho các giao diện người dùng đồ họa
của sản phẩm phần mềm. Cho dù các quy trình của P có thể mạnh đến mức
nào, nếu chúng được triển khai bằng một ngôn ngữ khó giao tiếp với L, thì
chúng không thể được sử dụng lại trong sản phẩm phần mềm. 
Ngay cả khi khả năng tương tác ngôn ngữ không phải vấn đề, cũng sẽ có rất ít
điểm trong việc cố gắng sử dụng lại một mã hiện có trừ khi mục được sử dụng
lại phù hợp với thiết kế chính xác. Có thể cần nhiều công việc hơn để sửa đổi
cấu phần mã hiện có hơn là tạo một cấu phần mã mới từ đầu. 
Do đó, việc sử dụng lại mã phải được tích hợp vào một sản phẩm phần mềm
ngay từ đầu. Việc sử dụng lại phải là một yêu cầu của người dùng cũng như
một rằng buộc của tài liệu cụ thể. Kế hoạch quản lý dự án phần mềm (Phần
9.4) phải kết hợp sử dụng lại. Ngoài ra, tài liệu thiết kế phải nêu rõ những mã
nào sẽ được triển khai và những gì sẽ được sử dụng lại. 
Vì vậy, như đã nêu ở đầu phần này, mặc dù việc sử dụng lại mã là một thách
thức quan trọng của việc triển khai, việc sử dụng lại mã phải được kết hợp với
các yêu cầu, phân tích và quy trình thiết kế. 
Từ quan điểm kỹ thuật thuần túy, quy trình thực hiện tương đối thẳng. Nếu
các yêu cầu, phân tích và quy trình thiết kế được thực hiện một cách thỏa
đáng, thì nhiệm vụ thực hiện sẽ gây ra ít vấn đề cho các lập trình viên có năng
lực. Tuy nhiên, việc quản lý hội nhập là quan trọng hàng đầu; những thách
thức của quy trình thực hiện sẽ được tìm thấy trong lĩnh vực này. 
Các vấn đề điển hình bao gồm việc sử dụng các công cụ CASE thích hợp
(Phần 15.24), lập kế hoạch kiểm tra sau khi khách hàng ký tên vào các trích
dẫn cụ thể (Phần 9.6), đảm bảo rằng các thay đổi đối với thiết kế được truyền
đạt cho tất cả những người có liên quan nhân sự (Mục 15.6.5), và quyết định
thời điểm ngừng thử nghiệm và giao sản phẩm cho khách hàng (Mục 6.1.2). 

You might also like