Đề tài: Môn Nguyên Lý Lập Trình 1 LÝ THUYẾT VỀ KIỂM CHỨNG CHƯƠNG TRÌNH Để khái quát hóa lý thuyết kiểm chứng chương trình trước tiên chúng ta tìm hiểu các mô hình phát triển phần mềm cơ bản thể hiện các bước phát triển phần mềm và trong đó có tầm quan trọng của giai đoạn kiểm chứng chương trình.
Đề tài: Môn Nguyên Lý Lập Trình 1 PHẦN I LÝ THUYẾT VỀ KIỂM CHỨNG CHƯƠNG TRÌNH. I. CÁC MÔ HÌNH PHÁT TRIỂN PHẦN MỀM 1. Mô hình phần mềm Để khái quát hóa lý thuyết kiểm chứng chương trình trước tiên chúng ta tìm hiểu các mô hình phát triển phần mềm cơ bản thể hiện các bước phát triển phần mềm và trong đó có tầm quan trọng của giai đoạn kiểm chứng chương trình. Mô thác nước truyền thống. Mô hình có mối quan hệ song song Để tránh các khuyết điểm trong quá trình phát triển phần mềm do không có liên kết chặt chẽ giữa các khâu trọng yếu thì mô hình mới ra đời như sau còn gọi là (Defect Prevention) Lê Hùng – Vũ Thế Hiển - Nguyễn Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 1 Đề tài: Môn Nguyên Lý Lập Trình 1 Mô hình V-MODEL Mô hình V-MODEL static test Lê Hùng – Vũ Thế Hiển - Nguyễn Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 2 Đề tài: Môn Nguyên Lý Lập Trình 1 Mô hình V-MODEL Dynamic Test Trong tất cả các mô hình phát triển phần mềm trên thì trong đó giai đoạn kiểm chứng chương trình (test) là rất quan trọng quyết định đến giá trị của phần mềm được sản xuất ra. 2. GIỚI THIỆI VỀ KIỂM CHỨNG CHƯƠNG TRÌNH Kiểm chứng chương trình là một trong những bước quan trọng trong quy trình phát triển sản phẩm phần mềm. Đảm bảo cho chương trình phần mềm chạy ổn định tránh nhưng sai sót chủ quan khi đưa vào ứng dụng thực tế. Vậy để thực hiện tốt việc kiểm chứng chương trình sao cho có hiệu quả và có quy trình rõ ràngcần có các nguyên lý và tính chất sau: II. PHẨM CHẤT CỦA CHƯƠNG TRÌNH. Các chương trình phần mềm khi được phát triển và đưa vào ứng dụng thực tế cần phải đạt được những phẩm chất cơ bản sau: - Tính đúng đắn, chính xác (Correctness) - Tính chắc chắn (robustness) - Tính thân thiện với người dùng (User friendliness) - Khả năng thích nghi (adapability):chương trình phần mềm có khả năng thích ứng và tiến hóa theo yêu cầu chung phù hợp với thực tế đưa ra. - Tính tái sử dụng (reuseability): chương trình có thể dùng để làm một phần trong một chương trình khác lớn hơn. - Tính tương liên (Interoperability) Lê Hùng – Vũ Thế Hiển - Nguyễn Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 3 Đề tài: Môn Nguyên Lý Lập Trình 1 - Tính hiệu quả (efficiency) - Tính khả chuyển (porability): có khả năng chuyển đổi dễ dàng giữa các môi trường phát triển khác nhau. - Tính an toàn hệ thống (Security). Ngoài 9 phẩm chất trên còn có phẩm chất quan trọng nữa là tính dừng của chương trình. Năm 1985-1986 LENARD nói rằng “ Không thể tồn tại một chương trình kiểm tra tính dừng của một chương trình”. II. CÁC PHƯƠNG PHÁP KIỂM CHỨNG CHƯƠNG TRÌNH 1. Cấu trúc kiểm chứng chương trình Có các phương thức chính để kiểm chứng tính đúng đắn của chương trình dưa trên các công trình nghiên cứu đã đưa ra như sau: - Kiểm chứng toàn bộ các nhánh rẽ của chương trình. Sao cho mỗi lệnh của chương trình đều phải qua ít nhất một lần (Black-Box). - Tạo bộ dữ liệu thử nghiệm ngẫu nhiên để phát hiện ra lỗi giả hay lỗi thật. - Kiểm tra ỡ những điểm nút - Chèn các lệnh kiểm tra logic ở mỗi đoạn chương trình.(White -Box) 2. Tính đúng đắn của chương trình Khi chương trình thực hiện mà xảy ra sai sót thì có rất nhiều nguyên nhân nhưng có 3 nguồn gốc xảy rai sót chính là. - Dữ liệu đầu vào: do dữ liệu nhập vào ban đầu thiếu tính ràng buộc nên sẽ xảy ra sai sót khi thực hiện khi đó để kiểm chứng thì dùng bộ kiểm tra dữ liệu ngẫu nhiên, hay đặc trưng tuỳ ý. - Cú pháp : Dùng trình biên dịch để phát hiện - Ngữ nghĩa: Lỗi này rất khó phát hiện dùng test logic, Heuristic test để kiểm tra. Mỗi chương trình đều có ràng buộc về tính đúng đắn đối với điều kiện input đầu vào. ∀x,P(x) : điều kiện đối với x Q(y): điều kiện đối với y Ta có : P(x)^Program(x,y) Q(y) Lê Hùng – Vũ Thế Hiển - Nguyễn Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 4 Input: a,b,c Program (ax 2 +bx+c=0) Output: x1,x2 ∀a,b,c,P(a,b,c): b 2 -4ac>=0 X1,x2:Q(ax 1 2 +bx 1 +c=0,a x 2 2 +bx2+c=0) Đề tài: Môn Nguyên Lý Lập Trình 1 Ví dụ 1: Kiểm chứng chương trình giải phương trình bậc 2 Ta có phân tích sơ đồ kiểm chứng như sau: Ví dụ 2: Kiểm chứng tính đúng đắn của chương trình tính thương và dư số a/b với chương trình như sau: r:=a;q:=0; While r>b do Begin r:=r-1; q:=q+1; end; Kết quả: q: là thương số, r : là dư số. Kiểm tra : - Điều kiện của phép chia b<>0. Nếu b=0 vòng lặp sẽ không dừng được dẫn đến chương trình sai. - Các cận : với a=b dẫn đến kết quả sai vì dứ số r=x và thương q=0. Lê Hùng – Vũ Thế Hiển - Nguyễn Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 5 Input:x Program(x,y) Output:y ∀x,P(x) Q(y) Đề tài: Môn Nguyên Lý Lập Trình 1 Chương trình đúng được viết lại như sau : r:=a;q:=0; While r>=b do Begin r:=r-1; q:=q+1; end; 3. Tính chắc chắn của chương trình Cần phân tích chương trình thành các chương trình con sao cho tính độc lập giữa các chương trình con càng cao càng tốt. Ví dụ : i :=n While i>0 do Begin Read(a[i]); i:=i-1; end; for j:=1 to n do i:=i+a[j]; writeln(‘tong so=’,i); Chương trình sẽ thực hiện sai nếu n<0 do biến i được dùng chung cho cả hai vòng lặp. 4. Kiểm chứng chương trình với mô hình nghịch đảo Để kiểm tra tính logic của chương trình ta có thể sử dụng phương pháp nghịch đảo để kiếm chứng lại tính đúng đắn thực tế của chương trình: Ví dụ 1: Thuật toán nhân Ấn Độ được phát triển như sau: Input: x,y Output: z=x*y Thuật Toán : Nhập x,y If x le then z=y; Else z=0 End if Lê Hùng – Vũ Thế Hiển - Nguyễn Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 6 Đề tài: Môn Nguyên Lý Lập Trình 1 While x>1 do Begin x:=x div 2; y:=y*2; If x lẻ then z:=z+y; End; z:=z+y; Để kiểm chứng chương trình trên ta lập trình lại và chèn thêm dòng lệnh kiểm chứng nghịch đảo để kiểm chứng chương trình như sau : Promgram nhan_ando ; var x,y,k,m,n :word ; BEGIN repeat write(‘nhap gia tri x=’) ;readln(x) until x>=0 ; repeat write(‘nhap gia tri y=’) ;readln(y) until y>=0 ; m :=x ; n :=y ; if (x mod 2)=1 then k:=y; else k :=0 ; if y<>0 then begin while x>1 do begin x :=x shr 1 ; y :=y shl 1 ; if ((x mod 2)=1) then k :=k+y ; end ; k :=k+y ; writeln(‘x*y=’,k) ; (* chèn thêm đoạn lệnh kiểm chứng*) if ((k/n)=m) and ((k/m)=n) then write(‘Thuat toan dung’) ; else writeln(‘thuat toan sai !’) ; readln ; end ; (* END OF IF*) END ; 5. Kiểm chứng chương trình dùng phương pháp quy nạp. Phương pháp này dựa vào phương pháp chứng minh quy nạp trong toán học. được phát biểu như sau : Lê Hùng – Vũ Thế Hiển - Nguyễn Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 7 Đề tài: Môn Nguyên Lý Lập Trình 1 Để chứng minh một tân từ P(n) phụ thuộc vào số tự nhiên là đúng với mọi n. thì ta cần chứng minh hai điều sau đây : (i) P(0) là đúng. (ii) Nếu P(n) được giả định là đúng thì sẽ suy ra P(n+1) cũng đúng. Khẳng định P(0) được gọi là cơ sở và bước chứng minh (ii) là bước quy nạp. Khi đã có hai điều chứng minh (i) và (ii), đựa vào nguyên lý quy nạp toán học ta kết luận P(n) đúng với mọi số tự nhiên n. Ngoài ra còn có phương pháp chứng minh quy nạp mạnh được phát biểu như sau : Để chứng minh P(n) đúng với mọi số tự nhiên ta chứng minh hai điều sau : (i) P(0) đúng (ii) Nếu giả định là P(0),P(1), P(n) đều đúng thì P(n+1) cũng đúng. Ví dụ 1 : Đầu vào là x,y,n để có đầu ra là x=x.yn ta viết đoạn chương trình tính như sau : while n<>0 do begin x :=x*y ; n :=n-1 ; end ; ketqua :=x ; Hãy chứng minh đoạn chương trình trên thực hiện đúng ý đồ của người viết. Xét vị từ S(n) cho đoạn chương trình sau : ‘’∀ x,y ∈ R, n ∈ N : nếu đầu vào là x,y,n thì đầu ra là : x=x*y n ‘’ ta chứng minh bằng nguyên lý quy nạp : Khi n=0 thì vòng lặp không thực hiện được, ketqua cua đoạn chương trình là x, vậy S(0) đúng. Ta giả sử S(k) đúng, tức đầu ra là x=x*y k Ta cần chứng minh S(k+1) đúng : Lê Hùng – Vũ Thế Hiển - Nguyễn Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 8 Đề tài: Môn Nguyên Lý Lập Trình 1 Thật vậy do k>=0 ==> k+1>0 nền vòng lặp sẽ thực hiện ít nhất là thêm 1 lần nữa suy ra x=x*y=x*y k *y = x=y k+1 nghĩa là S(k+1) đúng Vậy đoạn chương trình trên là đúng với ý đồ của người lập trình. Ví dụ 2 : Đầu vào là x,y,n để có đầu ra là x=x+n*y ta viết đoạn chương trình như sau : While n<>0 do begin x :=x+y ; n :=n-1 ; end ; ketqua :=x ; Hãy chứng minh đoạn chương trình trên đúng với ý đồ của người viết. Ta xét vị từ S(n) cho đoân chương trình trên như sau : ‘’ ∀ x,y ∈ R, n ∈ N : nếu đầu vào là x,y,n thì đầu ra là : x=x+n*y ‘’ Chứng minh bằng quy nạp : Với n=0 thì vòng lặp không thực hiện được chương trình thực hiện có kế quả = x+0*y=x vậy S(0) đúng. Ta giả sử S(k) đúng tức đầu ra của đoạn chương trình là x=x+k*y. Ta cần chứng minh S(k+1) đúng. Thật vập do k>=0 ==> k>0 nên vòng lặp sẽ thực hiện thêm ít nhất là một lần nữa suy ra x=x+y=x+k*y+y=x+(k+1)*y nghĩa là S(k+1) đúng. Vậy đoạn chương trình trên là đúng với ý đồ của người viết. Đối tượng của những phương pháp kiểm chứng logic là tìm ra những bằng chứng tổng quát sao cho bạn không cần theo dõi hết mọi điều kiện có thể. Thực hiện điều này liên quan đến một vài dạng đại diện logic bằng biểu tượng và các kỹ thuật thực hiện những phép suy luận logic. Một trong những kỹ thuật mạnh nhất cho mục đích này là phương pháp toán học gọi là phép qui nạp. Phương pháp này áp dụng cho những biểu thức logic với những tham số nguyên. Nó có tình trạng như sau : 1. Nếu biểu thức f (n) có thể được chứng minh là đúng đối với một giá trị n 0 nào đó 2. Khi n > n 0 và khi f (n) đúng, f (n + 1) cũng được chứng minh là đúng 3. Thì f (k) đúng với mọi k >= n 0 Sử dụng khái niệm này có thể tiết kiệm nhiều thời gian trong kiểm tra logic. Bạn bắt đầu bằng cách chứng minh rằng logic của một chương trình Lê Hùng – Vũ Thế Hiển - Nguyễn Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 9 Đề tài: Môn Nguyên Lý Lập Trình 1 (ở đây là một biểu thức logic) là đúng cho trường hợp cơ bản. Sau đó bạn chứng minh rằng nếu logic này đúng cho một giá trị n lớn hơn nào đó thì nó cũng đúng cho n + 1, điều này là một bằng chứng đầy dủ cho mọi giá trị lớn hơn của n và bạn không cần tìm thêm một bằng chứng nào nữa. Đây là một nguyên lý mạnh mẽ, nó phải được quan tâm sử dụng. Giả sử rằng bạn đang thực hiện một vòng lặp như sau: For i = 1 to 1000 BEGIN Do x y z END Nếu bạn kiểm tra và chứng thực rằng logic hợp lý ở những giá trị i = 1 , i =5 , i = 6 bạn có thể kết luận rằng nó đúng với mọi giá trị cao hơn của i. Tuy nhiên rõ ràng ở đây có một vấn đề khi mà i = 1001. Bài toán ở đây là cách mà kiểm chứng được thực hiện. Sau khi cho rằng logic là đúng ở i = 1, kế đến bạn cần kiểm tra trường hợp i = n. Bạn cho rằng logic là đúng khi giá trị i = n, nó cũng đúng cho i = n + 1. Chú ý rằng bạn không có chứng minh nó đúng cho i = n ; bạn giả sử điều này. Khảo sát bài toán, bạn có thể thấy rằng logic sẽ không làm việc khi n = 1000. Để tránh điều này bạn nên thực hiện cuộc kiểm tra với logic được sửa đổi như sau: For i = 1 to limit BEGIN Do x y z END Đầu tiên bạn chứng thực rằng hàm logic đúng ở limit = 1 ; kế đến bạn chứng minh rằng nếu đúng với limit = n thì nó cũng đúng cho limit = n + 1. Khi đó nó cũng đúng với mọi giá trị cao hơn của limit. Ở đây n là một giá trị nguyên dương. Lại nữa bạn cũng cần bảo đảm rằng không có những giá trị phi số trong hàm xyz nó có thể làm sai lệch các cuộc thực nghiệm này. Một cách khác để tiếp cận nguyên lý này là xem có thể tìm thấy bất kỳ một giá trị n hay không, nơi mà chương trình thì đúng ở limit = n nhưng không đúng ở limit n + 1. Những vấn đề như thế được gây nên bởi những ràng buộc về bộ nhớ hoặc là kích thước của hệ thống số 6. Thực hiện bằng biểu tượng Logic sau đây đưa ra bởi Mills cho thấy thực hiện bằng biểu tượng làm việc như thế nào trong trường hợp đơn giản Procedure Substitution (V1, V2, V3, V4) Lê Hùng – Vũ Thế Hiển - Nguyễn Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 10 [...]... Trang 32 Đề tài: Môn Nguyên Lý Lập Trình 1 Biên dịch và thực hiện chương trình Chương trình được thực hiện và báo rằng mọi chuyện diễn biến tốt đẹp và không có test nào được thực thi hết 3 Thiết lập chế độ kiểm tra (test) tự động ngay sau khi biên dịch chương trình Kiểm tra tự động ngay sau khi biên dịch chương trình là gì? Điều này có nghĩa là cứ mỗi lần bạn biên dịch chương trình, những bài test sẽ... với VC++ rằng “hãy thực thi chương trình ngay saukhi biên dịch xong” Chú ý rằng dòng lệnh cuối cùng trong hàm main() của dự án trả về các mã lỗi khác nhau phụ thuộc vào việc kiểm tra chương trình có thành công hay không Nếu mã lỗi khác 0, điều đó có nghĩa là quá trình biên dịch chương trình đã có “vấn đề” Biên dịch lại chương trình và chúng ta sẽ thấy là ngay sau khi chương trình được biên dịch xong... phải kiểm tra cẩn thận trong suốt quá trình thiết kế Lê Hùng – Vũ Thế Hiển - Nguyễn Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 19 Đề tài: Môn Nguyên Lý Lập Trình 1 PHẦN II THỰC NGHIỆM KIỂM CHỨNG CHƯƠNG TRÌNH 1 Trường hợp đơn giản Bạn muốn biết đọan mã lệnh có thực hiện hay không ? Làm sao kiểm chứng điều này? Có rất nhiều cách Sử dụng kỹ thuật bẫy lỗi (debug) hay chạy từng bước để kiểm. .. tượng, tuy nhiên bạn nên kiểm tra chương trình của mình và sử dụng điều này trong bất kỳ trường hợp nào mà bạn thấy trong thực tế Một trong những điểm hay nhất của những phương pháp kiểm chứng bằng toán học là nó cung cấp một cách được cấu trúc hóa để kiểm chứng một chương trình một cách logic 7 CHỨNG THỰC ĐỐI TƯỢNG STATE MACHINE Khi mà sản phẩm của bạn có một state machine, bạn nên chứng minh rằng nó được... logic đúng với k = q, chứng tỏ rằng nó vẫn đúng với k = q + 1 Rõ ràng trường hợp q + 1 là thêm vào một vòng quay cho bảng lưu vết trước và tạo ra Output thích hợp Dầu kiểm chứng bằng lưu vết rất mất thới gian, nó không có nhiều phân định cho tất cả các trường hợpkiểm tra logic của chương trình Nếu bạn muốn phát triển cuộc kiểm tra như trên thì bạn sẽ kiểm chứng tính đúng đắn cũa chương trình Tuy nhiên nếu... bạn thấy tự tin về chất lượng đọan mã lệnh Để thực hiện việc kiểm chứng, tất cả những gì bạn phải làm là tạo 1 lớp con TestCase, được Override phương thức runTest() Khi bạn muốn kiểm tra, gọi CPPUNIT_ASSERT(bool) và truyền vào biểu thức cần kiểm tra Nếu kết quả trả về là True thì việc kiểm chứng thành công Đây là một ví dụ cho việc kiểm chứng so sánh hai số phức: Class ComplexNumberTest: public CppUnit::TestCase... là trực giao III LƯU VẾT CHƯƠNG TRÌNH : Có nhiều cách khác nhau để kiểm chứng Logic Specification Template trước khi bạn cài đặt hoặc test một chương trình Nó bao gồm bảng thi hành, bảng lưu vết và kiểm chứng bằng toán học Phần này và các mô tả theo sau sẽ minh họa các tiếp cận làm việc như thế nào • Bảng thi hành (Execution Table) Bảng thi hành cung cấp một cách thứ tự để kiểm tra dòng logic trong... Nguyễn Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 18 Đề tài: Môn Nguyên Lý Lập Trình 1 Theo nguyên lý qui nạp, ta cần kiểm tra các trường hợp 0 và 1 sau đó kiểm chứng logic với số q và q + 1 nào đó Nếu bạn chứng tỏ logic đúng cho các trường hợp này bạn có thể tin rằng logic là đúng Rõ ràng chương trình thao tác đúng đắn khi chuỗi rỗng Nó để lại Length = 0 và State = 0 Cũng thế, bước... Runner.addTest(registry.makeTest()); Runner.run (); Return 0; 8 Post- build check Bây giờ, chúng ta có chương trình kiểm chứng Việc tích hợp modul này vào tiến trình buid thì sao? Để làm điều này, ứng dụng phải trả về một giá trị khác 0 để chỉ ra một lỗi TestRunner::run() trả về TRUE nếu thành công Cập nhật lại chương trình chính như sau: #include #include ... Đình Hiển –Phạm Đào Minh Vũ – Trương Quang Bình Long Trang 30 Đề tài: Môn Nguyên Lý Lập Trình 1 PHẦN III DỰ ÁN MONEY – MỘT VÍ DỤ CỤ THỂ I Chuẩn bị cho dự án Money 1 Biên dịch và cài đặt thư viện CppUnit Thư viện CppUnit là thư viện cần thiết cho các chương trình muốn bổ sung thêm chức năng kiểm chứng tính đúng đắn của chương trình mà mình đang phát triển Trước tiên hãy truy cập vào địa chỉ http://cppunit.sourceforge.net