Các kỹ thuật kiểm thử đột biến và ứng dụng kiểm thử chương trình C

96 132 0
Các kỹ thuật kiểm thử đột biến và ứng dụng kiểm thử chương trình C

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

Header Page of 16 LỜI CẢM ƠN Trong suốt trình học tập làm luận văn, nhận hướng dẫn, giúp đỡ quý báu quý thầy cô, anh chị bạn Với lòng kính trọng biết ơn sâu sắc xin bày tỏ lời cảm ơn chân thành tới:  Ban giám hiệu, Phòng đào tạo sau đại học trường Đại Học Khoa Học Tự Nhiên;  Phó giáo sư - Tiến sĩ Đoàn Văn Ban - người thầy hết lòng giúp đỡ, dạy bảo, động viên tạo điều kiện thuận lợi cho suốt trình học tập hoàn thành luận văn tốt nghiệp  Cùng tất thầy cô khoa, trường, anh chị lớp  Xin chân thành cảm ơn thầy cô hội đồng cho đóng góp quý báu để hoàn chỉnh luận văn Tác giả Phạm Thị Miên Footer Page of 16 Header Page of 16 MỤC LỤC LỜI CẢM ƠN MỤC LỤC I) DANH MỤC CÁC TỪ VIẾT TẮT, THUẬT NGỮ II) DANH MỤC CÁC BẢNG BIỂU III) DANH MỤC CÁC HÌNH VẼ LỜI MỞ ĐẦU CHƯƠNG – KHÁI QUÁT VỀ KIỂM THỬ PHẦN MỀM 1.1 Khái niệm 1.2 Các cấp độ kiểm thử phần mềm 1.2.1 Kiểm thử đơn vị (Unit Test) 10 1.2.2 Kiểm thử tích hợp (Integration Test) 10 1.2.3 Kiểm thử hệ thống (System Test) 11 1.2.4 Kiểm thử chấp nhận sản phẩm (Acceptance Test) 13 1.3 Kỹ thuật kiểm thử phần mềm 13 1.3.1 Kỹ thuật kiểm thử hộp đen (Black – box Testing) 13 1.3.1.1 Phân hoạch tương đương 15 1.3.1.2 Phân tích giá trị biên 17 1.3.2 Kỹ thuật kiểm thử hộp trắng (White – box Testing) 18 1.3.2.1 Kiểm thử đường dẫn sở 18 1.3.2.2 Kiểm thử cấu trúc điều khiển 23 1.4 Kết luận 26 CHƯƠNG – KỸ THUẬT KIỂM THỬ ĐỘT BIẾN 27 2.1 Một số khái niệm 27 2.1.1 Kiểm thử đột biến 27 2.1.2 Đột biến 27 2.1.3 Toán tử đột biến 30 2.2 Cơ sở kiểm thử đột biến 30 2.3 Toán tử đột biến 30 2.4 Quy trình kiểm thử đột biến 32 2.5 Hạn chế kiểm thử đột biến 34 2.6 Kết luận 35 Footer Page of 16 Header Page of 16 CHƯƠNG - MỘT SỐ CẢI TIẾN KỸ THUẬT KIỂM THỬ ĐỘT BIẾN 36 3.1 Giảm chi phí tính toán 36 3.1.1 Phương pháp làm (A “do fewer” approach) 36 3.1.1.1 Lấy mẫu đột biến (Mutant Sampling) 37 3.1.1.2 Đột biến ràng buộc (Constrained Mutation) 39 3.1.1.3 N - đột biến lựa chọn (N - Selective Mutation) 40 3.1.2 Phương pháp làm nhanh (A “do smarter” approach) 42 3.1.2.1 Phương pháp tạo lược đồ đột biến 43 3.1.2.2 Đột biến yếu (Weak Mutation) 45 3.2 Tăng tự động hóa 48 3.2.1 Tạo liệu thử tự động 48 3.2.2 Xác định đột biến tương đương tự động 50 3.3 Kết luận 53 CHƯƠNG - ỨNG DỤNG KỸ THUẬT KIỂM THỬ ĐỘT BIẾN ĐỂ KIỂM THỬ CÁC CHƯƠNG TRÌNH C (C – Sharp) 54 4.1 Tìm hiểu NUnit 55 4.1.1 Định nghĩa 55 4.1.2 Đặc điểm NUnit 55 4.1.3 Thuộc tính hay dùng thư viện NUnit.Framework 55 4.1.4 Phương thức tĩnh hay dùng NUnit.Framework.Assert 57 4.1.5 Cài đặt NUnit 59 4.1.6 Cách sử dụng NUnit 61 4.2 Công cụ Nester 69 4.2.1 Điều kiện tiên 69 4.2.2 Giải pháp cho đột biến 69 4.2.3 Chạy Nester 70 4.2.4 Lựa chọn Nester.exe.config 72 4.3 Quy trình ứng dụng kiểm thử đột biến để kiểm thử chương trình C - Sharp 72 4.3.1 Kiểm thử 73 4.3.2 Tạo đột biến 74 4.4 Kết luận 76 KẾT LUẬN 77 TÀI LIỆU THAM KHẢO 79 Footer Page of 16 Header Page of 16 PHỤ LỤC 82 PHỤ LỤC 84 PHỤ LỤC 90 PHỤ LỤC 94 PHỤ LỤC 95 Footer Page of 16 Header Page of 16 I) DANH MỤC CÁC TỪ VIẾT TẮT, THUẬT NGỮ - CBT (Constraint Based Testing): Kiểm thử dựa ràng buộc - MSG (Mutation Analysis Using Mutant Schemata): Phương pháp tạo lược đồ đột biến - PUT (Program Unit Test): Chương trình gốc II) DANH MỤC CÁC BẢNG BIỂU Bảng 1.1 Ví dụ lớp tương đương Bảng 2.1 22 toán tử chuẩn sử dụng Mothra Bảng 4.1 Lựa chọn Nester.exe.config Bảng 4.2 Kết chạy NUnit Bảng 4.3 Chất lượng trường hợp kiểm thử chương trình cs – money sau thực Nester III) DANH MỤC CÁC HÌNH VẼ Hình 1.1 Bốn cấp độ kiểm thử phần mềm Hình 1.2 Đồ thị luồng điều khiển Hình 1.3 Ví dụ minh hoạ phát sinh trường hợp kiểm thử theo đường dẫn sở Hình 1.4 Các kiểu vòng lặp Hình 2.1 Ví dụ đột biến tương đương Hình 2.2 Ví dụ đột biến Hình 3.1 Ba kịch có cho quan hệ tập liệu thử diệt đột biến yếu mạnh Hình 3.2 Phân bố đột biến toán tử đột biến cho Mothra Hình 3.3 Ví dụ phương thức gốc (PUT) Hình 3.4 Phiên đột biến PUT gốc hình 3.3 Hình 4.1 Quy trình ứng dụng kiểm thử đột biến C# Footer Page of 16 Header Page of 16 LỜI MỞ ĐẦU Kiểm thử phần mềm hoạt động giữ vai trò quan trọng để bảo đảm chất lượng phần mềm hoạt động mang tính sống dự án sản xuất gia công phần mềm Vì vậy, kiểm thử phần mềm trở thành qui trình bắt buộc dự án phát triển phần mềm giới Ở Việt Nam, ngành công nghiệp phần mềm phát triển xem nhẹ việc kiểm thử phần mềm xác suất thất bại cao, nữa, hầu hết công ty phần mềm có uy tín đặt yêu cầu nghiêm ngặt phần mềm tài liệu kiểm thử kèm không chấp nhận Tuy nhiên, hoạt động kiểm thử thường gặp nhiều khó khăn:  Thứ nhất, kiểm thử hệ thống phức tạp đòi hỏi nhiều nguồn tài nguyên chi phí cao  Thứ hai, tiến trình phát triển phần mềm trải qua nhiều hoạt động biến đổi thông tin, mát thông tin trình biến đổi yếu tố làm cho hoạt động kiểm thử khó khăn  Thứ ba, kiểm thử chưa trọng đào tạo người  Cuối cùng, không tồn kỹ thuật kiểm thử cho phép khẳng định phần mềm hoàn toàn đắn hay không chứa lỗi Với mục đích phát lỗi, kiểm thử phần mềm thường phải trải qua bước: tạo liệu thử, thực thi phần mềm liệu thử quan sát kết nhận Trong bước này, bước tạo liệu đóng vai trò quan trọng nhất, tạo liệu từ miền vào chương trình, mà tạo liệu thử có khả phát lỗi cao Vấn đề đặt làm để đánh giá khả phát lỗi liệu thử? Một kinh nghiệm để giúp giải vấn đề này, sử dụng khái niệm chất lượng liệu thử phương tiện để đánh giá liệu thử “tốt” kiểm thử chương trình Ở đây, “tốt” đánh giá Footer Page of 16 Header Page of 16 liên quan đến tiêu chuẩn chất lượng định trước, thường số dấu hiệu bao phủ chương trình Ví dụ, tiêu chuẩn bao phủ dòng lệnh đòi hỏi liệu thử thực dòng lệnh chương trình lần Nếu liệu thử tìm thấy không chất lượng liên quan đến tiêu chuẩn (tức tất câu lệnh thực lần), kiểm thử bắt buộc Do đó, mục tiêu tạo tập kiểm thử thực đầy đủ tiêu chuẩn chất lượng Tiêu chuẩn chất lượng tiêu biểu bao phủ câu lệnh kiểm thử định (thực tất đường dẫn sai qua chương trình) dựa vào việc thực chương trình với số lượng kiểm thử tăng dần để nâng cao độ tin cậy chương trình Tuy nhiên, chúng không tập trung vào nguyên nhân thất bại chương trình - gọi lỗi Kiểm thử đột biến tiêu chuẩn Tiêu chuẩn tạo phiên chương trình có chứa lỗi đơn giản sau tìm kiểm thử để dấu hiệu lỗi Nếu tìm thấy liệu thử chất lượng làm lộ dấu hiệu tất phiên bị lỗi, tin tưởng vào tính đắn chương trình tăng Kiểm thử đột biến áp dụng cho nhiều ngôn ngữ lập trình kỹ thuật kiểm thử hộp trắng Ý thức lĩnh vực nghiên cứu có nhiều triển vọng ứng dụng phát triển phần mềm, chọn hướng nghiên cứu “ Các kỹ thuật kiểm thử đột biến ứng dụng kiểm thử chương trình C” cho đề tài luận văn Luận văn tổ chức thành chương sau:  Chương – Trình bày khái quát kiểm thử phần mềm khái niệm kiểm thử phần mềm, mục đích, mục tiêu mức kiểm thử phần mềm Chương đề cập đến việc sử dụng kỹ thuật kiểm thử hộp trắng hộp đen để thiết kế liệu thử Footer Page of 16 Header Page of 16  Chương - Mô tả chi tiết thành phần kỹ thuật kiểm thử đột biến, giới thiệu giả thuyết cần thiết để thực phương pháp Chương cung cấp quy trình để phân tích đột biến, từ rút vấn đề hạn chế kỹ thuật kiểm thử đột biến, cải tiến chương  Chương – Giới thiệu số phương pháp cải tiến kỹ thuật kiểm thử đột biến nhằm giảm chi phí tính toán tăng tự động hóa  Chương – Tập trung vào ứng dụng kỹ thuật kiểm thử đột biến Phần đầu giới thiệu hai công cụ mã nguồn mở miễn phí NUnit dùng để kiểm thử đơn vị chương trình C#, Nester với chức phân tích tạo đột biến Tiếp ứng dụng kỹ thuật kiểm thử đột biến để kiểm thử chương trình C# sử dụng hai công cụ Footer Page of 16 Header Page of 16 CHƯƠNG – KHÁI QUÁT VỀ KIỂM THỬ PHẦN MỀM 1.1 Khái niệm Kiểm thử phần mềm trình thực thi hệ thống phần mềm để xác định xem phần mềm có với đặc tả không thực môi trường mong đợi hay không Mục đích kiểm thử phần mềm tìm lỗi chưa phát hiện, tìm cách sớm bảo đảm lỗi sửa Mục tiêu kiểm thử phần mềm thiết kế tài liệu kiểm thử cách có hệ thống thực cho có hiệu quả, tiết kiệm thời gian, công sức chi phí 1.2 Các cấp độ kiểm thử phần mềm Cấp độ kiểm thử phần mềm thể hình 1.1 [25]: Kiểm thử mức đơn vị lập trình (Unit test) Các phận đơn lẻ Kiểm thử mức tích hợp đơn vị (Integration test) Các nhóm phận Kiểm thử mức hệ thống, sau tích hợp (System test) Kiểm thử để chấp nhận sản phẩm (Acceptance test) Toàn hệ thống Toàn hệ thống nhìn từ khách hàng Hình 1.1- Bốn cấp độ kiểm thử phần mềm Footer Page of 16 Header Page 10 of 16 1.2.1 Kiểm thử đơn vị (Unit Test) Một đơn vị (Unit) thành phần phần mềm nhỏ mà ta kiểm thử được, ví dụ: hàm (Function), thủ tục (Procedure), lớp (Class), phương thức (Method) Kiểm thử đơn vị thường lập trình viên thực Công đoạn cần thực sớm tốt giai đoạn viết code xuyên suốt chu kỳ phát triển phần mềm Mục đích kiểm thử đơn vị bảo đảm thông tin xử lý kết xuất (khỏi Unit) xác, mối tương quan với liệu nhập chức xử lý Unit Điều thường đòi hỏi tất nhánh bên Unit phải kiểm tra để phát nhánh phát sinh lỗi Cũng mức kiểm thử khác, kiểm thử đơn vị đòi hỏi phải chuẩn bị trước ca kiểm thử (hay trường hợp kiểm thử) (test case) kịch (test script), định rõ liệu vào, bước thực liệu mong muốn xuất Các test case test script giữ lại để sử dụng sau 1.2.2 Kiểm thử tích hợp (Integration Test) Kiểm thử tích hợp kết hợp thành phần ứng dụng kiểm thử ứng dụng hoàn thành Trong kiểm thử đơn vị kiểm tra thành phần Unit riêng lẻ kiểm thử tích hợp kết hợp chúng lại với kiểm tra giao tiếp chúng Kiểm thử tích hợp có hai mục tiêu là:  Phát lỗi giao tiếp xảy Unit  Tích hợp Unit đơn lẻ thành hệ thống (gọi subsystem) cuối nguyên hệ thống hoàn chỉnh chuẩn bị cho kiểm thử mức hệ thống (system test) Có loại kiểm thử kiểm thử tích hợp sau: 10 Footer Page 10 of 16 Header Page 82 of 16 PHỤ LỤC Code Money.cs namespace NUnit.Samples.Money { using System; using System.Text; /// A simple Money. class Money: IMoney { private int fAmount; private String fCurrency; /// Constructs a money from the given amount and /// currency. public Money(int amount, String currency) { fAmount= amount; fCurrency= currency; } /// Adds a money to this money Forwards the request to /// the AddMoney helper. public IMoney Add(IMoney m) { return m.AddMoney(this); } public IMoney AddMoney(Money m) { if (m.Currency.Equals(Currency) ) return new Money(Amount+m.Amount, Currency); return new MoneyBag(this, m); } public IMoney AddMoneyBag(MoneyBag s) { return s.AddMoney(this); } public int Amount { get { return fAmount; } } public String Currency { get { return fCurrency; } } public override bool Equals(Object anObject) { if (IsZero) if (anObject is IMoney) 82 Footer Page 82 of 16 Header Page 83 of 16 return ((IMoney)anObject).IsZero; if (anObject is Money) { Money aMoney= (Money)anObject; return aMoney.Currency.Equals(Currency) && Amount == aMoney.Amount; } return false; } public override int GetHashCode() { return fCurrency.GetHashCode()+fAmount; } public bool IsZero { get { return Amount == 0; } } public IMoney Multiply(int factor) { return new Money(Amount*factor, Currency); } public IMoney Negate() { return new Money(-Amount, Currency); } public IMoney Subtract(IMoney m) { return Add(m.Negate()); } public override String ToString() { StringBuilder buffer = new StringBuilder(); buffer.Append("["+Amount+" "+Currency+"]"); return buffer.ToString(); } } } 83 Footer Page 83 of 16 Header Page 84 of 16 PHỤ LỤC Code Moneytest.cs namespace NUnit.Samples.Money.Port { using System; using NUnit.Framework; public class MoneyTest: TestCase { private Money f12CHF; private Money f14CHF; private Money f7USD; private Money f21USD; private MoneyBag fMB1; private MoneyBag fMB2; protected override void SetUp() { f12CHF= new Money(12, "CHF"); f14CHF= new Money(14, "CHF"); f7USD= new Money( 7, "USD"); f21USD= new Money(21, "USD"); fMB1= new MoneyBag(f12CHF, f7USD); fMB2= new MoneyBag(f14CHF, f21USD); } public void TestBagMultiply() { // {[12 CHF][7 USD]} *2 == {[24 CHF][14 USD]} Money[] bag = { new Money(24, "CHF"), new Money(14, "USD") }; MoneyBag expected= new MoneyBag(bag); Assertion.AssertEquals(expected, fMB1.Multiply(2)); Assertion.AssertEquals(fMB1, fMB1.Multiply(1)); Assertion.Assert(fMB1.Multiply(0).IsZero); } public void TestBagNegate() { // {[12 CHF][7 USD]} negate == {[-12 CHF][-7 USD]} 84 Footer Page 84 of 16 Header Page 85 of 16 Money[] bag= { new Money(-12, "CHF"), new Money(7, "USD") }; MoneyBag expected= new MoneyBag(bag); Assertion.AssertEquals(expected, fMB1.Negate()); } public void TestBagSimpleAdd() { // {[12 CHF][7 USD]} + [14 CHF] == {[26 CHF][7 USD]} Money[] bag= { new Money(26, "CHF"), new Money(7, "USD") }; MoneyBag expected= new MoneyBag(bag); Assertion.AssertEquals(expected, fMB1.Add(f14CHF)); } public void TestBagSubtract() { // {[12 CHF][7 USD]} - {[14 CHF][21 USD] == {[-2 CHF][-14 USD]} Money[] bag= { new Money(-2, "CHF"), new Money(14, "USD") }; MoneyBag expected= new MoneyBag(bag); Assertion.AssertEquals(expected, fMB1.Subtract(fMB2)); } public void TestBagSumAdd() { // {[12 CHF][7 USD]} + {[14 CHF][21 USD]} == {[26 CHF][28 USD]} Money[] bag= { new Money(26, "CHF"), new Money(28, "USD") }; MoneyBag expected= new MoneyBag(bag); Assertion.AssertEquals(expected, fMB1.Add(fMB2)); } public void TestIsZero() { Assertion.Assert(fMB1.Subtract(fMB1).IsZero); Money[] bag = { new Money(0, "CHF"), new Money(0, "USD") }; 85 Footer Page 85 of 16 Header Page 86 of 16 Assertion.Assert(new MoneyBag(bag).IsZero); } public void TestMixedSimpleAdd() { // [12 CHF] + [7 USD] == {[12 CHF][7 USD]} Money[] bag= { f12CHF, f7USD }; MoneyBag expected= new MoneyBag(bag); Assertion.AssertEquals(expected, f12CHF.Add(f7USD)); } public void TestMoneyBagEquals() { Assertion.Assert(!fMB1.Equals(null)); Assertion.AssertEquals(fMB1, fMB1); MoneyBag equal= new MoneyBag(new Money(12, "CHF"), new Money(7, "USD")); Assertion.Assert(fMB1.Equals(equal)); Assertion.Assert(!fMB1.Equals(f12CHF)); Assertion.Assert(!f12CHF.Equals(fMB1)); Assertion.Assert(!fMB1.Equals(fMB2)); } public void TestMoneyBagHash() { MoneyBag equal= new MoneyBag(new Money(12, "CHF"), new Money(7, "USD")); Assertion.AssertEquals(fMB1.GetHashCode(), equal.GetHashCode()); } public void TestMoneyEquals() { Assertion.Assert(!f12CHF.Equals(null)); Money equalMoney= new Money(12, "CHF"); Assertion.AssertEquals(f12CHF, f12CHF); Assertion.AssertEquals(f12CHF, equalMoney); Assertion.AssertEquals(f12CHF.GetHashCode(), equalMoney.GetHashCode()); Assertion.Assert(!f12CHF.Equals(f14CHF)); } public void TestMoneyHash() 86 Footer Page 86 of 16 Header Page 87 of 16 { Assertion.Assert(!f12CHF.Equals(null)); Money equal= new Money(12, "CHF"); Assertion.AssertEquals(f12CHF.GetHashCode(), equal.GetHashCode()); } public void TestNormalize() { Money[] bag= { new Money(26, "CHF"), new Money(28, "CHF"), new Money(6, "CHF") }; MoneyBag moneyBag= new MoneyBag(bag); Money[] expected = { new Money(60, "CHF") }; // note: expected is still a MoneyBag MoneyBag expectedBag= new MoneyBag(expected); Assertion.AssertEquals(expectedBag, moneyBag); } public void TestNormalize2() { // {[12 CHF][7 USD]} - [12 CHF] == [7 USD] Money expected= new Money(7, "USD"); Assertion.AssertEquals(expected, fMB1.Subtract(f12CHF)); } public void TestNormalize3() { // {[12 CHF][7 USD]} - {[12 CHF][3 USD]} == [4 USD] Money[] s1 = { new Money(12, "CHF"), new Money(3, "USD") }; MoneyBag ms1= new MoneyBag(s1); Money expected= new Money(4, "USD"); Assertion.AssertEquals(expected, fMB1.Subtract(ms1)); } public void TestNormalize4() { // [12 CHF] - {[12 CHF][3 USD]} == [-3 USD] Money[] s1 = { new Money(12, "CHF"), new Money(3, "USD") }; MoneyBag ms1= new MoneyBag(s1); 87 Footer Page 87 of 16 Header Page 88 of 16 Money expected= new Money(-3, "USD"); Assertion.AssertEquals(expected, f12CHF.Subtract(ms1)); } public void TestPrint() { Assertion.AssertEquals("[12 CHF]", f12CHF.ToString()); } public void TestSimpleAdd() { // [12 CHF] + [14 CHF] == [26 CHF] Money expected= new Money(26, "CHF"); Assertion.AssertEquals(expected, f12CHF.Add(f14CHF)); } public void TestSimpleBagAdd() { // [14 CHF] + {[12 CHF][7 USD]} == {[26 CHF][7 USD]} Money[] bag= { new Money(26, "CHF"), new Money(7, "USD") }; MoneyBag expected= new MoneyBag(bag); Assertion.AssertEquals(expected, f14CHF.Add(fMB1)); } public void TestSimpleMultiply() { // [14 CHF] *2 == [28 CHF] Money expected= new Money(28, "CHF"); Assertion.AssertEquals(expected, f14CHF.Multiply(2)); } public void TestSimpleNegate() { // [14 CHF] negate == [-14 CHF] Money expected= new Money(-14, "CHF"); Assertion.AssertEquals(expected, f14CHF.Negate()); } public void TestSimpleSubtract() 88 Footer Page 88 of 16 Header Page 89 of 16 { // [14 CHF] - [12 CHF] == [2 CHF] Money expected= new Money(2, "CHF"); Assertion.AssertEquals(expected, f14CHF.Subtract(f12CHF)); } } } 89 Footer Page 89 of 16 Header Page 90 of 16 PHỤ LỤC Code MoneyBag.cs namespace NUnit.Samples.Money { using System; using System.Collections; using System.Text; /// A MoneyBag defers exchange rate conversions. /// For example adding /// 12 Swiss Francs to 14 US Dollars is represented as a bag /// containing the two Monies 12 CHF and 14 USD Adding another /// 10 Swiss francs gives a bag with 22 CHF and 14 USD Due to /// the deferred exchange rate conversion we can later value a /// MoneyBag with different exchange rates /// A MoneyBag is represented as a list of Monies and provides /// different constructors to create a MoneyBag. class MoneyBag: IMoney { private ArrayList fMonies= new ArrayList(5); private MoneyBag() { } public MoneyBag(Money[] bag) { for (int i= 0; i < bag.Length; i++) { if (!bag[i].IsZero) AppendMoney(bag[i]); } } public MoneyBag(Money m1, Money m2) { AppendMoney(m1); AppendMoney(m2); } public MoneyBag(Money m, MoneyBag bag) { AppendMoney(m); AppendBag(bag); } public MoneyBag(MoneyBag m1, MoneyBag m2) { AppendBag(m1); AppendBag(m2); } 90 Footer Page 90 of 16 Header Page 91 of 16 public IMoney Add(IMoney m) { return m.AddMoneyBag(this); } public IMoney AddMoney(Money m) { return (new MoneyBag(m, this)).Simplify(); } public IMoney AddMoneyBag(MoneyBag s) { return (new MoneyBag(s, this)).Simplify(); } private void AppendBag(MoneyBag aBag) { foreach (Money m in aBag.fMonies) AppendMoney(m); } private void AppendMoney(Money aMoney) { IMoney old= FindMoney(aMoney.Currency); if (old == null) { fMonies.Add(aMoney); return; } fMonies.Remove(old); IMoney sum= old.Add(aMoney); if (sum.IsZero) return; fMonies.Add(sum); } private bool Contains(Money aMoney) { Money m= FindMoney(aMoney.Currency); return m.Amount == aMoney.Amount; } public override bool Equals(Object anObject) { if (IsZero) if (anObject is IMoney) return ((IMoney)anObject).IsZero; if (anObject is MoneyBag) { MoneyBag aMoneyBag= (MoneyBag)anObject; if (aMoneyBag.fMonies.Count != fMonies.Count) return false; foreach (Money m in fMonies) { if (!aMoneyBag.Contains(m)) return false; 91 Footer Page 91 of 16 Header Page 92 of 16 } return true; } return false; } private Money FindMoney(String currency) { foreach (Money m in fMonies) { if (m.Currency.Equals(currency)) return m; } return null; } public override int GetHashCode() { int hash= 0; foreach (Money m in fMonies) { hash^= m.GetHashCode(); } return hash; } public bool IsZero { get { return fMonies.Count == 0; } } public IMoney Multiply(int factor) { MoneyBag result= new MoneyBag(); if (factor != 0) { foreach (Money m in fMonies) { result.AppendMoney((Money)m.Multiply(factor)); } } return result; } public IMoney Negate() { MoneyBag result= new MoneyBag(); foreach (Money m in fMonies) { result.AppendMoney((Money)m.Negate()); } return result; } private IMoney Simplify() { 92 Footer Page 92 of 16 Header Page 93 of 16 if (fMonies.Count == 1) return (IMoney)fMonies[0]; return this; } public IMoney Subtract(IMoney m) { return Add(m.Negate()); } public override String ToString() { StringBuilder buffer = new StringBuilder(); buffer.Append("{"); foreach (Money m in fMonies) buffer.Append(m); buffer.Append("}"); return buffer.ToString(); } } } 93 Footer Page 93 of 16 Header Page 94 of 16 PHỤ LỤC Code Imoney.cs namespace NUnit.Samples.Money { /// The common interface for simple Monies and MoneyBags. interface IMoney { /// Adds a money to this money. IMoney Add(IMoney m); /// Adds a simple Money to this money This is a helper method for /// implementing double dispatch. IMoney AddMoney(Money m); /// Adds a MoneyBag to this money This is a helper method for /// implementing double dispatch. IMoney AddMoneyBag(MoneyBag s); /// True if this money is zero. bool IsZero { get; } /// Multiplies a money by the given factor. IMoney Multiply(int factor); /// Negates this money. IMoney Negate(); /// Subtracts a money from this money. IMoney Subtract(IMoney m); } } 94 Footer Page 94 of 16 Header Page 95 of 16 PHỤ LỤC Code Assemblyinfo.cs using System.Reflection; using System.Runtime.CompilerServices; // // General Information about attributes Change an assembly is controlled through the modify the following // set of these attribute values to information // associated with an assembly // [assembly: AssemblyTitle("")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("")] [assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: [assembly: AssemblyVersion("2.2.0.0")] // // In order to sign your assembly you must specify a key to use Refer to the // Microsoft NET Framework documentation assembly signing // 95 Footer Page 95 of 16 for more information on Header Page 96 of 16 // Use the attributes below to control which key is used for signing // // Notes: // // (*) If no key is specified, the assembly is not signed (*) KeyName refers to a key that has been installed in the Crypto Service // Provider (CSP) on your machine KeyFile refers to a file which contains // // a key (*) If the KeyFile and the KeyName values are both specified, the // following processing occurs: // (1) If the KeyName can be found in the CSP, that key is used // (2) If the KeyName does not exist and the KeyFile does exist, the key // // in the KeyFile is installed into the CSP and used (*) In order to create a KeyFile, you can use the sn.exe (Strong Name) utility // When specifying the KeyFile, the location of the KeyFile should be // relative to the project output directory which is // %Project Directory%\obj\ For example, if your KeyFile is // located in the project directory, you would specify the AssemblyKeyFile // attribute as [assembly: AssemblyKeyFile(" \\ \\mykey.snk")] // (*) Delay Signing is an advanced option - see the Microsoft NET Framework // documentation for more information on this // [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("")] [assembly: AssemblyKeyName("")] 96 Footer Page 96 of 16 ... phí NUnit dùng để kiểm thử đơn vị chương trình C# , Nester với ch c phân tích tạo đột biến Tiếp ứng dụng kỹ thuật kiểm thử đột biến để kiểm thử chương trình C# sử dụng hai c ng c Footer Page of... kỹ thuật kiểm thử thông thường dùng để thay cho kỹ thuật kiểm thử thông thường 2.1.2 Đột biến Kiểm thử đột biến bao gồm vi c tạo phiên lỗi chương trình g c kiểm thử nhờ vào toán tử đột biến C c. .. diện  C c lỗi c u tr c liệu truy c p sở liệu bên  C c lỗi th c  C c lỗi khởi tạo kết th c  Và lỗi kh c Không giống với kiểm thử hộp trắng th c sớm trình kiểm thử, kiểm thử hộp đen áp dụng

Ngày đăng: 12/03/2017, 12:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan