(Post 28/02/2006) Một hoạt động mang tính sống
còn trong các dự án sản xuất hoặc gia công phần mềm (PM), đó là kiểm tra
(Testing). Dân làm PM chắc hẳn không ai nghi ngờ vai trò quan trọng của
nó, tuy nhiên không phải ai (cả trong ngành và ngoài ngành) cũng hiểu
rõ hoạt động này. Bản thân công việc kiểm tra phần mềm (KTPM) cũng là
một lĩnh vực hoạt động độc lập và khá "hấp dẫn". Cùng với các
dự án gia công sản xuất PM, hiện cũng có khá nhiều dự án mà nội dung công
việc chỉ là kiểm tra những PM đã được khách hàng phát triển sẵn.
Hình 1: 4 mức độ cơ bản
của kiểm tra phần mềm |
|
Mặc dù công việc KTPM không xa lạ song những khái niệm
và kỹ thuật lại khá rắc rối. Bài viết này sẽ nhằm cung cấp một cái nhìn
tương đối bao quát về lĩnh vực "tưởng cũ nhưng không cũ” này.
KIỂM TRA PHẦN MỀM LÀ GÌ?
Thực ra KTPM là công việc mà bất cứ người nào từng tham
gia phát triển phần mềm (PTPM) đều biết và từng làm. Theo nghĩa thông
thường nhất, KTPM bao gồm việc "chạy thử" PM hay một chức năng
của PM, xem nó "chạy" đúng như mong muốn hay không. Việc kiểm
tra này có thể thực hiện từng chặng, sau mỗi chức năng hoặc module được
phát triển, hoặc thực hiện sau cùng, khi PM đã được phát triển hoàn tất.
KTPM đứng ở vị trí hết sức nhạy cảm, nó là bước đệm giữa
giai đoạn xây dựng PM và sử dụng PM, trước khi giao sản phẩm hoàn chỉnh
cho khách hàng. Bạn có thể tham khảo bài "Tổng quan các mô hình phát
triển phần mềm" trong TGVT A số tháng 8/2005 (ID: A0508_106) để biết
vị trí của KTPM trong các mô hình PTPM.
CÁC MỨC ĐỘ CỦA KTPM
Thực tế, KTPM không đơn giản như nhiều người thường nghĩ,
công việc này có nhiều mức độ khác nhau và có mối tương quan với các chặng
phát triển trong dự án PTPM. Hình 1 cho thấy 4 mức độ cơ bản của KTPM
và hình 2 cho thấy mối tương quan với các chặng PTPM trong mô hình V-model.
Phần sau sẽ làm rõ chi tiết về các mức độ KTPM, do một
số thuật ngữ không có từ tương đương sát nghĩa trong tiếng Việt, mặt khác
để các bạn tiện tham khảo sau này, chúng tôi xin giữ nguyên một số thuật
ngữ gốc tiếng Anh.
1. Unit Test – Kiểm tra mức đơn vị
Để có thể hiểu rõ về Unit Test, khái niệm trước tiên
ta cần làm rõ: thế nào là một đơn vị PM (Unit)?
Một Unit là một thành phần PM nhỏ nhất mà ta có thể kiểm
tra được. Theo định nghĩa này, các hàm (Function), thủ tục (Procedure),
lớp (Class), hoặc các phương thức (Method) đều có thể được xem là Unit.
Vì Unit được chọn để kiểm tra thường có kích thước nhỏ
và chức năng hoạt động đơn giản, chúng ta không khó khăn gì trong việc
tổ chức, kiểm tra, ghi nhận và phân tích kết quả kiểm tra. Nếu phát hiện
lỗi, việc xác định nguyên nhân và khắc phục cũng tương đối dễ dàng vì
chỉ khoanh vùng trong một đơn thể Unit đang kiểm tra. Một nguyên lý đúc
kết từ thực tiễn: thời gian tốn cho Unit Test sẽ được đền bù bằng việc
tiết kiệm rất nhiều thời gian và chi phí cho việc kiểm tra và sửa lỗi
ở các mức kiểm tra sau đó.
Unit Test thường do lập trình viên thực hiện. Công đoạn
này cần được thực hiện càng sớm càng tốt trong giai đoạn viết code và
xuyên suốt chu kỳ PTPM. Thông thường, Unit Test đòi hỏi kiểm tra viên
có kiến thức về thiết kế và code của chương trình. Mục đích của Unit Test
là bảo đảm thông tin được xử lý và xuất (khỏi Unit) là chính xác, trong
mối tương quan với dữ liệu nhập và chức năng của Unit. Điều này thường
đòi hỏi tất cả các nhánh bên trong Unit đều phải được kiểm tra để phát
hiện nhánh phát sinh lỗi. Một nhánh thường là một chuỗi các lệnh được
thực thi trong một Unit, ví dụ: chuỗi các lệnh sau điều kiện If và nằm
giữa then ... else là một nhánh. Thực tế việc chọn lựa các nhánh để đơn
giản hóa việc kiểm tra và quét hết Unit đòi hỏi phải có kỹ thuật, đôi
khi phải dùng thuật toán để chọn lựa.
Cũng như các mức kiểm tra khác, Unit Test cũng đòi hỏi
phải chuẩn bị trước các tình huống (test case) hoặc kịch bản (script),
trong đó chỉ định rõ dữ liệu vào, các bước thực hiện và dữ liệu mong chờ
sẽ xuất ra. Các test case và script này nên được giữ lại để tái sử dụng.
2. Integration Test – Kiểm tra tích hợp
Integration test kết hợp các thành phần của một ứng dụng
và kiểm tra như một ứng dụng đã hoàn thành. Trong khi Unit Test kiểm tra
các thành phần và Unit riêng lẻ thì Intgration Test kết hợp chúng lại
với nhau và kiểm tra sự giao tiếp giữa chúng.
Integration Test có 2 mục tiêu chính:
- Phát hiện lỗi giao tiếp xảy ra giữa các Unit.
- Tích hợp các Unit đơn lẻ thành các hệ thống nhỏ (subsystem) và
cuối cùng là nguyên hệ thống hoàn chỉnh (system) chuẩn bị cho kiểm
tra ở mức hệ thống (System Test).
Trong Unit Test, lập trình viên cố gắng phát hiện lỗi
liên quan đến chức năng và cấu trúc nội tại của Unit. Có một số phép kiểm
tra đơn giản trên giao tiếp giữa Unit với các thành phần liên quan khác,
tuy nhiên mọi giao tiếp liên quan đến Unit thật sự được kiểm tra đầy đủ
khi các Unit tích hợp với nhau trong khi thực hiện Integration Test.
Trừ một số ít ngoại lệ, Integration Test chỉ nên thực
hiện trên những Unit đã được kiểm tra cẩn thận trước đó bằng Unit Test,
và tất cả các lỗi mức Unit đã được sửa chữa. Một số người hiểu sai rằng
Unit một khi đã qua giai đoạn Unit Test với các giao tiếp giả lập thì
không cần phải thực hiện Integration Test nữa. Thực tế việc tích hợp giữa
các Unit dẫn đến những tình huống hoàn toàn khác.
Một chiến lược cần quan tâm trong Integration Test là
nên tích hợp dần từng Unit. Một Unit tại một thời điểm được tích hợp vào
một nhóm các Unit khác đã tích hợp trước đó và đã hoàn tất (passed) các
đợt Integration Test trước đó. Lúc này, ta chỉ cần kiểm tra giao tiếp
của Unit mới thêm vào với hệ thống các Unit đã tích hợp trước đó, điều
này làm cho số lượng kiểm tra sẽ giảm đi rất nhiều, sai sót sẽ giảm đáng
kể.
Có 4 loại kiểm tra trong Integration Test:
- Kiểm tra cấu trúc (structure): Tương tự White Box Test (kiểm tra
nhằm bảo đảm các thành phần bên trong của một chương trình chạy đúng),
chú trọng đến hoạt động của các thành phần cấu trúc nội tại của chương
trình chẳng hạn các lệnh và nhánh bên trong.
- Kiểm tra chức năng (functional): Tương tự Black Box Test (kiểm
tra chỉ chú trọng đến chức năng của chương trình, không quan tâm đến
cấu trúc bên trong), chỉ khảo sát chức năng của chương trình theo
yêu cầu kỹ thuật.
- Kiểm tra hiệu năng (performance): Kiểm tra việc vận hành của hệ
thống.
- Kiểm tra khả năng chịu tải (stress): Kiểm tra các giới hạn của
hệ thống.
3. System Test - Kiểm tra mức hệ thống
Mục đích System Test là kiểm tra thiết kế và toàn bộ
hệ thống (sau khi tích hợp) có thỏa mãn yêu cầu đặt ra hay không.
System Test bắt đầu khi tất cả các bộ phận của PM đã
được tích hợp thành công. Thông thường loại kiểm tra này tốn rất nhiều
công sức và thời gian. Trong nhiều trường hợp, việc kiểm tra đòi hỏi một
số thiết bị phụ trợ, phần mềm hoặc phần cứng đặc thù, đặc biệt là các
ứng dụng thời gian thực, hệ thống phân bố, hoặc hệ thống nhúng. Ở mức
độ hệ thống, người kiểm tra cũng tìm kiếm các lỗi, nhưng trọng tâm là
đánh giá về hoạt động, thao tác, sự tin cậy và các yêu cầu khác liên quan
đến chất lượng của toàn hệ thống.
Điểm khác nhau then chốt giữa Integration Test và System
Test là System Test chú trọng các hành vi và lỗi trên toàn hệ thống, còn
Integration Test chú trọng sự giao tiếp giữa các đơn thể hoặc đối tượng
khi chúng làm việc cùng nhau. Thông thường ta phải thực hiện Unit Test
và Integration Test để bảo đảm mọi Unit và sự tương tác giữa chúng hoạt
động chính xác trước khi thực hiện System Test.
Sau khi hoàn thành Integration Test, một hệ thống PM
đã được hình thành cùng với các thành phần đã được kiểm tra đầy đủ. Tại
thời điểm này, lập trình viên hoặc kiểm tra viên (tester) bắt đầu kiểm
tra PM như một hệ thống hoàn chỉnh. Việc lập kế hoạch cho System Test
nên bắt đầu từ giai đoạn hình thành và phân tích các yêu cầu. Phần sau
ta sẽ nói rõ hơn về một quy trình System Test cơ bản và điển hình.
System Test kiểm tra cả các hành vi chức năng của phần
mềm lẫn các yêu cầu về chất lượng như độ tin cậy, tính tiện lợi khi sử
dụng, hiệu năng và bảo mật. Mức kiểm tra này đặc biệt thích hợp cho việc
phát hiện lỗi giao tiếp với PM hoặc phần cứng bên ngoài, chẳng hạn các
lỗi "tắc nghẽn" (deadlock) hoặc chiếm dụng bộ nhớ. Sau giai
đoạn System Test, PM thường đã sẵn sàng cho khách hàng hoặc người dùng
cuối cùng kiểm tra để chấp nhận (Acceptance Test) hoặc dùng thử (Alpha/Beta
Test).
Đòi hỏi nhiều công sức, thời gian và tính chính xác,
khách quan, System Test thường được thực hiện bởi một nhóm kiểm tra viên
hoàn toàn độc lập với nhóm phát triển dự án.
Bản thân System Test lại gồm nhiều loại kiểm tra khác
nhau (xem hình 3), phổ biến nhất gồm:
- Kiểm tra chức năng (Functional Test): bảo đảm các hành vi của hệ
thống thỏa mãn đúng yêu cầu thiết kế.
- Kiểm tra khả năng vận hành (Performance Test): bảo đảm tối ưu việc
phân bổ tài nguyên hệ thống (ví dụ bộ nhớ) nhằm đạt các chỉ tiêu như
thời gian xử lý hay đáp ứng câu truy vấn...
- Kiểm tra khả năng chịu tải (Stress Test hay Load Test): bảo đảm
hệ thống vận hành đúng dưới áp lực cao (ví dụ nhiều người truy xuất
cùng lúc). Stress Test tập trung vào các trạng thái tới hạn, các "điểm
chết", các tình huống bất thường...
- Kiểm tra cấu hình (Configuration Test)
- Kiểm tra khả năng bảo mật (Security Test): bảo đảm tính toàn vẹn,
bảo mật của dữ liệu và của hệ thống.
- Kiểm tra khả năng phục hồi (Recovery Test): bảo đảm hệ thống có
khả năng khôi phục trạng thái ổn định trước đó trong tình huống mất
tài nguyên hoặc dữ liệu; đặc biệt quan trọng đối với các hệ thống
giao dịch như ngân hàng trực tuyến.
Nhìn từ quan điểm người dùng, các kiểm tra trên rất quan
trọng: bảo đảm hệ thống đủ khả năng làm việc trong môi trường thực.
Lưu ý không nhất thiết phải thực hiện tất cả các loại
kiểm tra nêu trên. Tùy yêu cầu và đặc trưng của từng hệ thống, tuỳ khả
năng và thời gian cho phép của dự án, khi lập kế hoạch, trưởng dự án sẽ
quyết định áp dụng những loại kiểm tra nào.
Hình 2: Mối tương quan giữa phát triển và kiểm tra phần mềm |
|
4. Acceptance Test - Kiểm tra chấp nhận sản phẩm
Thông thường, sau giai đoạn System Test là Acceptance
Test, được khách hàng thực hiện (hoặc ủy quyền cho một nhóm thứ ba thực
hiện). Mục đích của Acceptance Test là để chứng minh PM thỏa mãn tất cả
yêu cầu của khách hàng và khách hàng chấp nhận sản phẩm (và trả tiền thanh
toán hợp đồng).
Acceptance Test có ý nghĩa hết sức quan trọng, mặc dù
trong hầu hết mọi trường hợp, các phép kiểm tra của System Test và Accepatnce
Test gần như tương tự, nhưng bản chất và cách thức thực hiện lại rất khác
biệt.
Đối với những sản phẩm dành bán rộng rãi trên thị trường
cho nhiều người sử dụng, thông thường sẽ thông qua hai loại kiểm tra gọi
là Alpha Test và Beta Test. Với Alpha Test, người sử dụng (tiềm năng)
kiểm tra PM ngay tại nơi PTPM, lập trình viên sẽ ghi nhận các lỗi hoặc
phản hồi, và lên kế hoạch sửa chữa. Với Beta Test, PM sẽ được gửi tới
cho người sử dụng (tiềm năng) để kiểm tra ngay trong môi trường thực,
lỗi hoặc phản hồi cũng sẽ gửi ngược lại cho lập trình viên để sửa chữa.
Thực tế cho thấy, nếu khách hàng không quan tâm và không
tham gia vào quá trình PTPM thì kết quả Acceptance Test sẽ sai lệch rất
lớn, mặc dù PM đã trải qua tất cả các kiểm tra trước đó. Sự sai lệch này
liên quan đến việc hiểu sai yêu cầu cũng như sự mong chờ của khách hàng.
Ví dụ đôi khi một PM xuất sắc vượt qua các phép kiểm tra về chức năng
thực hiện bởi nhóm thực hiện dự án, nhưng khách hàng khi kiểm tra sau
cùng vẫn thất vọng vì bố cục màn hình nghèo nàn, thao tác không tự nhiên,
không theo tập quán sử dụng của khách hàng v.v...
Gắn liền với giai đoạn Acceptance Test thường là một
nhóm những dịch vụ và tài liệu đi kèm, phổ biến như hướng dẫn cài đặt,
sử dụng v.v... Tất cả tài liệu đi kèm phải được cập nhật và kiểm tra chặt
chẽ.
Hình 3: Các loại kiểm tra khác nhau trong System Test |
|
5. Regression Test - Kiểm tra hồi quy
Trước tiên cần khẳng định Regression Test không phải
là một mức kiểm tra, như các mức khác đã nói ở trên. Nó đơn thuần kiểm
tra lại PM sau khi có một sự thay đổi xảy ra, để bảo đảm phiên bản PM
mới thực hiện tốt các chức năng như phiên bản cũ và sự thay đổi không
gây ra lỗi mới trên những chức năng vốn đã làm việc tốt. Regression test
có thể thực hiện tại mọi mức kiểm tra.
Ví dụ: một PM đang phát triển khi kiểm tra cho thấy nó
chạy tốt các chức năng A, B và C. Khi có thay đổi code của chức năng C,
nếu chỉ kiểm tra chức năng C thì chưa đủ, cần phải kiểm tra lại tất cả
các chức năng khác liên quan đến chức năng C, trong ví dụ này là A và
B. Lý do là khi C thay đổi, nó có thể sẽ làm A và B không còn làm việc
đúng nữa.
Mặc dù không là một mức kiểm tra, thực tế lại cho thấy
Regression Test là một trong những loại kiểm tra tốn nhiều thời gian và
công sức nhất. Tuy thế, việc bỏ qua Regression Test là "không được
phép" vì có thể dẫn đến tình trạng phát sinh hoặc tái xuất hiện những
lỗi nghiêm trọng, mặc dù ta "tưởng rằng" những lỗi đó hoặc không
có hoặc đã được kiểm tra và sửa chữa rồi!
TÓM TẮT
Trên đây là tổng quan về các mức và loại kiểm tra PM
cơ bản. Thực tế nếu đi sâu vào từng mức và loại kiểm tra, còn có rất nhiều
kiểm tra đặc thù khác nữa, mang tính chuyên biệt cho từng vấn đề hoặc
từng loại ứng dụng. Tuy nhiên, những mức độ và loại kiểm tra nêu trên
là cơ bản nhất và có thể áp dụng trong hầu hết các loại ứng dụng PM khác
nhau.
Trong số báo tới chúng tôi sẽ giới thiệu những bước cơ
bản của một quy trình KTPM, làm thế nào để đánh giá và cải tiến năng lực
KTPM của một tổ chức thông qua mô hình TMM (Testing Maturity Model), một
mô hình được các chuyên gia đánh giá khá tốt dành cho hoạt động KTPM.
Ngô Văn Toàn
Công ty Global CyberSoft Vietnam
(theo PC World VN) |