Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 100 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
100
Dung lượng
1,62 MB
Nội dung
LỜI CẢM ƠN Trong suốt quá trình học tập và làm luận văn, đã nhận được sự hướng dẫn, giúp đỡ quý báu của quý thầy cô, các anh chị và các bạn Với lòng kính trọng và biết ơn sâu sắc xin được 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 và tạo mọi điều kiện thuận lợi cho suốt quá trình học tập và 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 các thầy cô hội đồng đã cho những đóng góp quý báu để hoàn chỉnh luận văn này Tác giả Phạm Thị Miên Luận văn Thạc Sĩ MỤC LỤC LỜI CẢM ƠN .1 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Ẽ .3 LỜI MỞ ĐẦU .4 CHƯƠNG – KHÁI QUÁT VỀ KIỂM THỬ PHẦN MỀM CHƯƠNG – KỸ THUẬT KIỂM THỬ ĐỘT BIẾN 25 CHƯƠNG - MỘT SỐ CẢI TIẾN KỸ THUẬT 34 KIỂM THỬ ĐỘT BIẾN 34 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) 52 KẾT LUẬN .84 TÀI LIỆU THAM KHẢO 86 PHỤ LỤC .89 PHỤ LỤC .92 PHỤ LỤC .98 PHỤ LỤC .102 PHỤ LỤC .103 LỜI CẢM ƠN .1 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Ẽ .3 LỜI MỞ ĐẦU .4 CHƯƠNG – KHÁI QUÁT VỀ KIỂM THỬ PHẦN MỀM CHƯƠNG – KỸ THUẬT KIỂM THỬ ĐỘT BIẾN 25 CHƯƠNG - MỘT SỐ CẢI TIẾN KỸ THUẬT 34 KIỂM THỬ ĐỘT BIẾN 34 Luận văn Thạc Sĩ 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) 52 KẾT LUẬN .84 TÀI LIỆU THAM KHẢO 86 PHỤ LỤC .89 PHỤ LỤC .92 PHỤ LỤC .98 PHỤ LỤC .102 PHỤ LỤC .103 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 Luận văn Thạc Sĩ 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# 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 Luận văn Thạc Sĩ 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á 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 Thạc Sĩ 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ử 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ụ Luận văn Thạc Sĩ 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 Kiểm thử thử mức mức đơn đơn vị vị lập lập trình trình (Unit (Unit test) test) Các Các bộ phận phận đơn đơn lẻ lẻ Kiểm Kiểm thử thử mức mức tích tích hợp hợp các đơn đơn vị vị (Integration (Integration test) test) Các Các nhóm nhóm bộ phận phận Kiểm Kiểm thử thử mức mức hệ hệ thống, sau thống, sau tích tích hợp hợp (System (System test) test) Kiểm Kiểm thử thử để để chấp chấp nhận nhận sản sản phẩm phẩm (Acceptance (Acceptance test) test) Toàn Toàn bộ hệ hệ thống thống Toàn Toàn bộ hệ hệ thống thống nhìn từ khách nhìn từ khách hàng hàng Hình 1.1- Bốn cấp độ kiểm thử phần mềm Luận văn Thạc Sĩ 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: Luận văn Thạc Sĩ − Kiểm thử cấu trúc (Structure test): Kiểm thử nhằm bảo đảm thành phần bên chương trình chạy đúng, trọng đến hoạt động thành phần cấu trúc nội chương trình, chẳng hạn lệnh nhánh bên − Kiểm thử chức (Functional test): Kiểm thử trọng đến chức chương trình, không quan tâm đến cấu trúc bên trong, khảo sát chức chương trình theo yêu cầu kỹ thuật − Kiểm thử hiệu (Performance test): Kiểm thử việc vận hành hệ thống − Kiểm thử khả chịu tải (Stress test): Kiểm thử giới hạn hệ thống 1.2.3 Kiểm thử hệ thống (System Test) Mục đích kiểm thử hệ thống kiểm thử xem thiết kế toàn hệ thống (sau tích hợp) có thỏa mãn yêu cầu đặt hay không Kiểm thử hệ thống kiểm tra hành vi chức phần mềm lẫn yêu cầu chất lượng độ tin cậy, tính tiện lợi sử dụng, hiệu bảo mật Kiểm thử hệ thống bắt đầu tất phận phần mềm tích hợp thành công Thông thường loại kiểm thử tốn nhiều công sức thời gian Trong nhiều trường hợp, việc kiểm thử đòi hỏi số thiết bị phụ trợ, phần mềm phần cứng đặc thù, đặc biệt ứng dụng thời gian thực, hệ thống phân bố, hệ thống nhúng Ở mức độ hệ thống, người kiểm thử tìm kiếm lỗi, trọng tâm đánh giá hoạt động, thao tác, tin cậy yêu cầu khác liên quan đến chất lượng toàn hệ thống Điểm khác then chốt kiểm thử tích hợp kiểm thử hệ thống kiểm thử hệ thống trọng hành vi lỗi toàn hệ thống, kiểm thử tích hợp trọng giao tiếp đơn thể đối tượng chúng làm việc Thông thường ta phải thực kiểm thử đơn vị kiểm Luận văn Thạc Sĩ thử tích hợp để bảo đảm Unit tương tác chúng hoạt động xác trước thực kiểm thử hệ thống Sau hoàn thành kiểm thử tích hợp, hệ thống phần mềm hình thành với thành phần kiểm tra đầy đủ Tại thời điểm này, lập trình viên kiểm thử viên (Tester) bắt đầu kiểm thử phần mềm hệ thống hoàn chỉnh Việc lập kế hoạch cho kiểm thử hệ thống nên giai đoạn hình thành phân tích yêu cầu Đòi hỏi nhiều công sức, thời gian tính xác, khách quan, kiểm thử hệ thống thực nhóm kiểm tra viên hoàn toàn độc lập với nhóm phát triển dự án để đảm bảo tính xác khách quan Kiểm thử hệ thống thường có loại kiểm thử sau: − Kiểm thử chức (Functional test): Bảo đảm hành vi hệ thống thỏa mãn yêu cầu thiết kế − Kiểm thử khả 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ụ nhớ) nhằm đạt tiêu thời gian xử lý hay đáp ứng câu truy vấn, − Kiểm thử khả chịu tải (Stress test hay Load test): Bảo đảm hệ thống vận hành áp lực cao (ví dụ nhiều người truy xuất lúc) Stress test tập trung vào trạng thái tới hạn, "điểm chết", tình bất thường giao dịch ngắt kết nối (xuất nhiều test thiết bị POS, ATM), − Kiểm thử cấu hình (Configuration test): Đảm bảo hệ thống hoạt động tương thích với loại phần cứng khác − Kiểm thử khả bảo mật (Security test): Bảo đảm tính toàn vẹn, bảo mật liệu hệ thống − Kiểm thử khả phục hồi (Recovery test): Bảo đảm hệ thống có khả khôi phục trạng thái ổn định trước tình tài nguyên liệu; đặc biệt quan trọng hệ thống giao 10 Luận văn Thạc Sĩ get { return fCurrency; } } public override bool Equals(Object anObject) { if (IsZero) if (anObject is IMoney) 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(); } } } 86 Luận văn Thạc Sĩ 87 Luận văn Thạc Sĩ 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"); new Money( 7, "USD"); f7USD= 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[] Money(14, bag = { new Money(24, "CHF"), new "USD") }; MoneyBag expected= new MoneyBag(bag); Assertion.AssertEquals(expected, fMB1.Multiply(2)); Assertion.AssertEquals(fMB1, fMB1.Multiply(1)); Assertion.Assert(fMB1.Multiply(0).IsZero); 88 Luận văn Thạc Sĩ } public void TestBagNegate() { // {[12 CHF][7 USD]} negate == {[-12 CHF][-7 USD]} Money[] bag= { new Money(-12, "CHF"), new Money(- "USD") }; 7, 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= { 14, new Money(-2, "CHF"), new Money(- "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[] Money(28, bag= { new Money(26, "CHF"), "USD") }; MoneyBag expected= 89 new MoneyBag(bag); new Luận văn Thạc Sĩ 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") }; 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()); } 90 Luận văn Thạc Sĩ public void TestMoneyEquals() { Assertion.Assert(!f12CHF.Equals(null)); new Money(12, "CHF"); Money equalMoney= Assertion.AssertEquals(f12CHF, f12CHF); Assertion.AssertEquals(f12CHF, equalMoney); Assertion.AssertEquals(f12CHF.GetHashCode(), equalMoney.GetHashCode()); Assertion.Assert(!f12CHF.Equals(f14CHF)); } public void TestMoneyHash() { Assertion.Assert(!f12CHF.Equals(null)); Money equal= new Money(12, "CHF"); Assertion.AssertEquals(f12CHF.GetHashCode(), equal.GetHashCode()); } public void TestNormalize() { Money[] Money(28, bag= { new Money(26, "CHF"), "CHF"), new Money(6, "CHF") }; MoneyBag moneyBag= new MoneyBag(bag); new Money(60, "CHF") }; Money[] expected = { // 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() { 91 new Luận văn Thạc Sĩ // {[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); 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= { "USD") }; 92 new Money(26, "CHF"), new Money(7, Luận văn Thạc Sĩ 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() { // [14 CHF] - [12 CHF] == [2 CHF] Money expected= new Money(2, "CHF"); Assertion.AssertEquals(expected, f14CHF.Subtract(f12CHF)); } } } 93 Luận văn Thạc Sĩ 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); } 94 Luận văn Thạc Sĩ public MoneyBag(MoneyBag m1, MoneyBag m2) { AppendBag(m1); AppendBag(m2); } 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) 95 Luận văn Thạc Sĩ 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; } 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(); 96 Luận văn Thạc Sĩ 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() { 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(); } } } 97 Luận văn Thạc Sĩ 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); } } 98 Luận văn Thạc Sĩ PHỤ LỤC Code Assemblyinfo.cs using System.Reflection; using System.Runtime.CompilerServices; // // General Information about an assembly is controlled through the following // set of attributes Change these attribute values to modify the 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 for more information on assembly signing // 99 Luận văn Thạc Sĩ // 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("")] 100