Xác minh và thẩm định là sự kiểm tra việc phát triển phần mềm. Là công việc xuyên suốt quá trình phát triển phần mềm, chứ không chỉ ở khâu kiểm thử khi đã có mã nguồn. Xác minh (verification) là sự kiểm tra xem sản phầm có đúng với đặc tả không, chú trọng vào việc phát hiện lỗi lập trình. Thẩm định (validation) là sự kiểm tra xem sản phẩm có đáp ứng được nhu cầu người dùng không, có hoạt động hiệu quả không, tức là chú trọng vào việc phát hiện lỗi phân tích, lỗi thiết kế.
Tóm lại, mục đích của thẩm định và xác minh là
Có hai khái niệm là thẩm định/xác minh tĩnh và thẩm định/xác minh động. Thẩm định và xác minh tĩnh là sự kiểm tra mà không thực hiện chương trình, ví dụ như xét duyệt thiết kế, xét duyệt yêu cầu, nghiên cứu mã nguồn, sử dụng các biến đổi hình thức (suy luận) để kiểm tra tính đúng đắn của chương trình. Thẩm định và xác minh tĩnh được tiến hành ở mọi khâu trong vòng đời phần mềm. Về lý thuyết, có thể phát hiện được hầu hết các lỗi lập trình, tuy nhiên phương pháp này không thể đánh giá được tính hiệu quả của chương trình.
Thẩm định và xác minh động là sự kiểm tra thông qua việc thực hiện chương trình, được tiến hành sau khi đã phát triển chương trình (mã nguồn). Hiện vẫn là kỹ thuật kiểm tra chính. Cả hai hướng nêu trên đều rất quan trọng và chúng bổ khuyết lẫn nhau. Trong chương này, chúng ta đi sâu vào tìm hiểu về thẩm định và xác minh động, gọi là sự thử nghiệm (kiểm thử) chương trình.
Có hai loại thử nghiệm (động) là:
Thử nghiệm cần phải có
Một phép thử được gọi là thành công nếu nó phát hiN 79;n ra khiếm khuyết của phần mềm. Chú ý là phép thử chỉ chứng minh được sự tồn tại của lỗi trong hệ thống chứ không chứng minh được hệ thống không có lỗi. Một phép thử (ca thử nghiệm) bao gồm
Các ca thử nghiệm nên được thiết kế khi chúng ta tạo các tài liệu phân tích và thiết kế, chứ không phải là khi đã viết xong mã nguồn.
Có hai kỹ thuật thử nghiệm tìm khuyết tật chính là thử nghiệm chức năng và thử nghiệm cấu trúc.
Thử ngiệm chức năng (functional testing) còn gọi là thử nghiệm hộp đen (black box testing) là sự thử nghiệm sử dụng các ca thử nghiệm được thiết kế dựa trên đặc tả yêu cầu, tài liệu người dùng nhằm mục đích phát hiện ra các khiếm khuyết. Thử nghiệm chức năng nhìn nhận mô đun được thử nghiệm như là một hộp đen, và chỉ quan tâm đến chức năng (hành vi) của mô đun, tức là kiểm tra xem có hoạt động đúng với đặc tả hay không. Các ca kiểm thử bao gồm các trường hợp bình thường và không bình thường (dữ liệu không hợp lệ...) của mô đun. Thông thường, không thể thử nghiệm với mọi dữ liệu, chiến lược chung khi thiết kế dữ liệu thử nghiệm là phân hoạch (dữ liệu) tương đương. Phân hoạch tương đương chia miền dữ liệu vào ra thành các vùng, mà mỗi vùng chứa các dữ liệu có cùng hành vi. Do đó, đối với mỗi vùng dữ liệu chỉ cần xây dựng một ca thử nghiệm. Thêm vào đó là các ca sử dụng đối với biên giới của các vùng. Theo kinh nghiệm, các sai sót về lập trình thường sảy ra đối với các dữ liệu biên.
Đối với hàm tính trị tuyệt đối của số nguyên, có thể chia miền đối số thành 2 vùng:
Do đó các dữ liệu đầu vào dể kiểm thử có thể là 100, 20, 0
Ngoài các ca thử nghiệm trên, thông thường còn cần kiểm tra với các dữ liệu đặc thù như:
Thử nghiệm chức năng có thể giúp chúng ta
Tuy nhiên thử nghiệm chức năng chỉ dựa trên đặc tả nên không thể kiểm thử được các trường hợp không được khai báo trong đặc tả, không đảm bảo thử hết được các khối mã nguồn của mô đun.
Thử nghiệm chức năng cũng không phát hiện được các đoạn mã yếu (có khả năng sinh lỗi với một trạng thái đặc biệt nào đó của hệ thống), và trong nhiều trường hợp việc đảm bảo xây dựng đầy đủ các ca thử nghiệm là khó khăn.
Hàm tính trị tuyệt đối sau có thể thoát được thử nghiệm chức năng tuy có lỗi.
int abs(int n) { if (n>0) return n; else (n<0) return ưn; }
Thử nghiệm cấu trúc (structural testing) là sự thử nghiệm dựa trên phân tích chương trình. Kỹ thuật chính ở đây là xác định đường đi (path) của chương trình (điều khiển) từ input đến output. Mục 73;ích của thử nghiệm cấu trúc là kiểm tra tất cả các đường đi có thể. Tức là đảm bảo mọi lệnh đều được thực hiện ít nhất một lần trong một ca thử nghiệm nào đó. Thử nghiệm cấu trúc chú trọng vào phân tích các cấu trúc rẽ nhánh và các vòng lặp.
int max(int x, int y, int z) { if (x>y) { if (x>z) return x; else return z; } else { if (y > z) return y; else return z; } }
Trong ví dụ trên có 4 đường đi có thể do đó cần ít nhất 4 ca thử nghiệm để thử nghiệm tất cả các đường đi này. Thử nghiệm cấu trúc xem xét chương trình ở mức độ chi tiết và phù hợp khi kiểm tra các mô đun nhỏ. Tuy nhiên thử nghiệm cấu trúc có thể không đầy đủ vì kiểm thử hết các lệnh không chứng tỏ là chúng ta đã kiểm thử hết các trường hợp có thể. Có khả năng tồn tại các tổ hợp lệnh khác nhau gây lỗi. Ngoài ra, chúng ta không thể kiểm thử hết các đường đi đối với các vòng lặp lớn.
Tóm lại, thử nghiệm chức năng và thử nghiệm cấu trúc đều rất quan trọng và chúng bổ khuyết lẫn nhau.
Quá trình thử nghiệm có thể chia làm các giai đoạn như sau:
Các bước thử nghiệm ban đầu nặng về kiểm tra lỗi lập trình (xác minh), các bước thử nghiệm cuối thiên về kiểm tra tính dùng được của hệ thống (thẩm định). Ngoài ra còn một bước hay một khái niệm thử nghiệm khác được gọi là thử nghiệm quay lui. Thử nghiệm quay lui được tiến hành mỗi khi chúng ta sửa mã chương trình:
Đối với một số hệ thống quan trọng, người ta còn tiến hành thử nghiệm gây áp lực (stress testing). Đây là loại (bước) thử nghiệm được tiến hành khi đã có phiên bản làm việc, nhằm tìm hiểu hoạt động của hệ thống trong các trường hợp tải trọng lớn (dữ liệu lớn, số người sử dụng lớn, tài nguyên hạn chế...). Mục đích của thử nghiệm áp lực là
Ngoài ra thử nghiệm áp lực còn nhằm xác định các trạng thái đặc biệt như tổ hợp một số điều kiện dẫn đến sự sụp đổ của hệ thống; tính an toàn của dữ liệu, của dịch vụ khi hệ thống sụp đổ.
Khi thử nghiệm hệ con và thử nghiệm hệ thố ;ng (tích hợp), có các chiến lược thử nghiệm chính là thử nghiệm dưới lên (bottomưup testing) và thử nghiệm trên xuống (topưdown testing).
Thử nghiệm dưới lên tiến hành thử nghiệm với các mô đun ở mức độ thấp trước. Mô đun thượng cấp (mô đun gọi) được thay thế bằng chương trình kiểm thử có nhiện vụ đọc dữ liệu kiểm thử, gọi mô đun cần kiểm thử và kiểm tra kết quả. Nhược điểm của thử nghiệm dưới lên là
Thử nghiệm trên xuống tiến hành thử nghiệm với các mô đun ở mức cao trước, các mô đun mức thấp được tạm thời phát triển với các chức năng hạn chế, có giao diện giống như trong đặc tả. Mô đun mức thấp có thể chỉ đơn giản là trả lại kết quả với một vài đầu vào định trước.
Thử nghiệm trên xuống có ưu điểm là
Nhược điểm của kiểm thử trên xuống là các chức năng của mô đun cấp thấp nhiều khi rất phức tạp do đó khó có thể mô phỏng được, dẫn đến không kiểm thử đầy đủ chức năng hoặc phải đình chỉ kiểm thử cho đến khi các mô đun cấp thấp xây dựng xong.