Bài giảng Công cụ kiểm thử phần mềm - Bài 2: Kiểm thử phần mềm - Trần Mạnh Thắng
• Đã nghe:
– Máy tính là thiết bị
tính toán nhiều tính năng
– Máy tính gồm 3 thành phần:
• Bộ xử lý
• Bộ nhớ
• Các thiết bị nhập xuất
• Đã sử dụng máy tính:
– Chơi game
– Nghe nhạc
– Lập trình
• Đã sử dụng máy tính như thế nào, có dễ không?
• Một lớp phần mềm ở giữa phần cứng và các chương trình ứng dụng/người
dùng.
• Ảo hóa (virtualize) các thành phần phần cứng nhằm giúp việc giao tiếp: dễ
dàng và an toàn
• Quản lý việc sử dụng chia sẻ các tài nguyên máy tính của các chương
trình/người dùng: công bằng và hiệu quả
• Cung cấp một tập các hàm thư viện để đơn giản hóa việc phát triển ứng
dụng
Lưu ý khi tiến hành kiểm thử:
• Chất lượng phần mềm do khâu thiết kế quyết định là chủ yếu, chứ không phải
khâu kiểm thử;
• Tính dễ kiểm thử phụ thuộc vào cấu trúc chương trình;
• Người kiểm thử và người phát triển nên khác nhau;
• Dữ liệu thử cho kết quả bình thường thì không có ý nghĩa nhiều, cần có những dữ
liệu kiểm thử mà phát hiện ra lỗi;
• Khi thiết kế trường hợp thử, không chỉ dữ liệu kiểm thử nhập vào, mà phải thiết kế
trước cả dữ liệu kết quả sẽ có;
• Khi phát sinh thêm trường hợp thử thì nên thử lại những trường hợp thử trước đó
để tránh ảnh hưởng lan truyền sóng.
Trang 1
Trang 2
Trang 3
Trang 4
Trang 5
Trang 6
Trang 7
Trang 8
Trang 9
Trang 10
Tải về để xem bản đầy đủ
Tóm tắt nội dung tài liệu: Bài giảng Công cụ kiểm thử phần mềm - Bài 2: Kiểm thử phần mềm - Trần Mạnh Thắng
109225 VÍ DỤ •CôngtySTTviếtchương trình trong đócómộthàmtínhgiátrị tuyệt đốicủa mộtsố nguyên. Hãy kiểmthử xem hàm này có thựchiện đúng hay không bằng phương pháp kiểmthử hộp đen theo phân chia tương đương. •Thựchiện: Chia các dữ liệu đầu vào thành hai lớp: Cách chia 1: . Lớphợplệ là lớpcóloạidữ liệusố nguyên đạidiện đầuvàovàra yêu cầu là (2/2); . Lớpkhônghợplệ là lớpcóloạidữ liệusố không nguyên: đạidiện đầuvàovàrayêucầu là (2,5/2,5). Cách chia 2: . Lớphợplệ là lớpcóloạidữ liệusố dương: Đạidiện đầuvàovàra yêu cầu là (2/2); . Lớpkhônghợplệ là lớpcóloạidữ liệusố âm: Đạidiện đầuvàovàra yêu cầulà(-5/-5). 35 v1.1013109225 KIỂM THỬ HỘP ĐEN THEO PHÂN TÍCH GIÁ TRỊ BIÊN - BVA (BOUNDARY VALUE TESTING) • BVA là kỹ thuậtkiểmthử bổ sung thêm cho phân hoạch tương đương, nó dựatrên giá trị biên củavùngdữ liệuhợplệ; •Thayvìchọnbấtcứ phầntử nào củalớptương đương, BVA chọn các ca kiểmthử sát vớilớptương đương; •Thayvìtậptrungvàođiềukiện vào, BVA còn đưaracáccakiểmthử từ miềnra; •BVAchorằng số lớncácsaixuấthiện ở biên nhiềuhơn là vùng dữ liệu trung tâm. Không những chú ý đếndữ liệu trong và sát biên mà còn chú ý đếndữ liệungoài và sát biên; •Thựchiện: Phân đoạntương tương tậpcácgiátrị dữ liệu vào thành các lớp; Chọncácgiátrịởbiên củamỗilớp; Chọncácgiátrị trên và dướicủabiên. 36 v1.1013109225 VÍ DỤ •Mộttrường dữ liệucóđịnh dạng dữ liệusố nguyên là 3. Tứclàchỉ chấpnhậncácgiá trị nguyên, lớnhơnhoặcbằng 0, và nhỏ hơnhoặcbằng 999 (0<= x <=999); •Cácgiátrị biên là 0 và 999; •Kiểmthử theo giá trị biên nhằm đảmbảohệ thống chỉ chấpnhậncácgiátrị xlớnhơn hoặcbằng 0 và nhỏ hơnhoặcbằng 999 mà không chấpnhậncácgiátrị nhỏ hơn0 hoặclớnhơn 999. 37 v1.1013109225 3.1.2. KIỂM THỬ HỘP TRẮNG VỚI CÁC CÂU LỆNH (tiếp theo) Các bướckiểmthử hộptrắng vớicáccâulệnh: •Dùngtàiliệuthiếtkế hay mã nguồn để vẽ thuậttoáncủachương trình hay hàm; •Xácđịnh đồ thị V(G); •Từđồthị V(G) xác định tập đường độclậptuyếntínhlẫn nhau; •Xâydựng trường hợpkiểmthử dựatrêntập đường độclậptuyếntínhở trên. 38 v1.1013109225 ĐƯỜNG ĐỘC LẬP TUYẾN TÍNH • Để đảmbảocáccâulệnh đều đượckiểmthử ít nhấtmộtlần, ta cầntìmtấtcả các đường điềukhiển độclậptrongchương trình, tứclàmỗi đường khác vớicácđường khác ít nhấtmộtlệnh; •Số các củamộtchương trình là giớihạntrêncủasố các kiểmthử cầnphảitiếnhành. Nó đượcgọilàđộ phứctạpchutrìnhcủachương trình; •Mộttậpcơ bảnconđường độclậplàtập: Mọicạnh của đồ thị dòng đềucómặttrongmộtconđường củatậpnày; Mỗiconđường củatập đó đềuchứaítnhấtmột cung không có mặttrongmọi con đường khác củanó; Số lượng các con đường củatậpnàychotasốđo độ phứctạpchutrìnhcủamột chương trình. 39 v1.1013109225 ĐÁNH GIÁ ĐỘ PHỨC TẠP CỦA ĐỒ THỊ DÒNG Đánh giá độ phứctạpcủa đồ thị dòng: Độ phứctạpchutrìnhV(G)đốivới1đồ thị dòng G được định nghĩalà: V(G) = Số miềnphẳng; V(G)=E-N+2; V(G)=P+1. Trong đó: E là số cạnh; Nlàsố nút của đồ thị dòng; Plàsố nút vị từ. V(G) cung cấpsố các đường đi độclậptrongmộtchương trình và nó đượccoilàcận trên củasố lượng kiểmthử phảitiếnhànhđể đảmbảomỗilệnh đều đượcthựchiệnít nhấtmộtlần. 40 v1.1013109225 CÁC ĐƯỜNG CƠ BẢN CỦA ĐỒ THỊ DÒNG Tuần tự if while until case • Đồ thị dòng (đồ thị chương trình) gầngiống dòng điềukhiển. •Nólàmột đồ thị cấutrúcgồm: Mỗi nút (hình tròn) biểuthị mộtsố (hoặccóthể là 0) câu lệnh thủ tục; Mỗicạnh nối hai nút biểudiễndòngđiềukhiển; Chia mặtphẳng thành nhiềumiền; Một nút là vị từ nếunóbiểuthị sự phân nhánh hoặchộinhậpcủacung. • Đồ thị dòng dùng để biểudiễnthiếtkế thủ tục. 41 v1.1013109225 VÍ DỤ 1 s1 1 float foo(int a, int b, int c, int d) { c1 2 float e; 3 if (a==0) s2 4 return 0; s3 5 int x = 0; 6 if ((a==b) || ((c==d) && bug(a))) c2 7 x = 1; 8 e = 1/x; s4 9 return e; s5 10 } 42 v1.1013109225 VÍ DỤ 2 double average(double value[], double min, double max, int& tcnt, int& vcnt) { double sum = 0; 1 1 int i = 1; tcnt = vcnt = 0; 2 2 while (value[i] -999 && tcnt <100) { 3 tcnt++; 4 5 6 10 if (min<=value[i] && value[i] <= max) 4 sum += value[i]; 11 12 7 5 vcnt ++; } 8 6 i++; 11 } 9 7 8 if (vcnt > 0) return sum/vcnt; return -999; 10 9 } 12 43 v1.1013109225 VÍ DỤ 2 (tiếp theo) 1 Đồ thị bên có 5 nút quyết định nhị phân nên có độ phứctạpC=5+1=6.6đường thi hành tuyếntính 2 độclậplà: •1 2 10 11 3 10 •1 2 3 10 11 •1 2 10 12 4 12 •1 2 3 4 5 8 9 11 5 •1 2 3 4 5 6 8 9 •1 2 3 4 5 6 7 8 9 6 7 8 9 44 v1.1013109225 VÍ DỤ 2 (tiếp theo) • Test case cho đường 1 2 10 11: value(k) -999, với 1< k < i; value(i) = -999 với 2 ≤ i ≤ 100; Kết quả kỳ vọng: (1) average = Giá trị trung bình của k giá trị hợp lệ. (2) tcnt = k. (3) vcnt = k; Chú ý: không thể kiểm thử đường 1 này riêng biệt mà phải khiểm thử chung với đường 4 hay 5 hay 6. • Test case cho đường 1 2 3 10 11: value(k) -999, với k 100; Kết quả kỳ vọng: (1) average = Giá trị trung bình của 100 giá trị hợp lệ. (2) tcnt = 100. (3) vcnt = 100. • Test case cho đường 1 2 10 12: value(1) = -999; Kết quả kỳ vọng: (1) average = -999. (2) tcnt = 0. (3) vcnt = 0; 45 v1.1013109225 VÍ DỤ 2 (tiếp theo) • Test case cho đường 1 2 3 4 5 8 9: value(i) -999 i <= 100; và value(k) < min với k < I; Kết quả kỳ vọng: (1) average = Giá trị trung bình của n giá trị hợp lệ. (2) tcnt = 100. (3) vcnt = n (số lượng giá trị hợp lệ). • Test case cho đường 1 2 3 4 5 6 8 9: value(i) -999 với i <= 100 và value(k) > max với k <= i Kết quả kỳ vọng: (1) average = Giá trị trung bình của n giá trị hợp lệ. (2) tcnt = 100. (3) vcnt = n (số lượng giá trị hợp lệ). • Test case cho đường 1 2 3 4 5 6 7 8 9: value(i) -999 và min <= value(i) <= max với i <= 100 Kết quả kỳ vọng: (1) average = Giá trị trung bình của 100 giá trị hợp lệ. (2) tcnt = 100. (3) vcnt = 100. 46 v1.1013109225 KIỂM THỬ HỘP ĐEN THEO ĐỒ THỊ CAUSE-EFFECT (CAUSE-EFFECT GRAPHING) •Làkỹ thuậtkiểmthử phân tích việckếthợpcácđiềukiệnvào,tạomột đồ thị kếtnối nguyên nhân – kếtquả (cause-effect). Trong đó, nguyên nhân (cause) là đầuvàovà kếtquả (effect) là đầura. •Cácbướctiến hành: Lập danh sách các nguyên nhân (điềukiệnvào)vàkếtquả (hành động) cho từng môđun và gán giá trịđịnh danh cho chúng; Phát triển đồ thị nhân quả; Chuyển đồ thịđóthànhbảng quyết định; Sử dụng các quy luậtcủabảng quyết định để xây dựng các ca kiểmthử. 47 v1.1013109225 KIỂM THỬ HỘP ĐEN THEO ĐỒ THỊ CAUSE-EFFECT (CAUSE-EFFECT GRAPHING) Các ký hiệutrongđồ thị nhân quả a b a b c a b c a b a b a b a b a b 48 v1.1013109225 KIỂM THỬ HỘP ĐEN THEO ĐỒ THỊ CAUSE-EFFECT (CAUSE-EFFECT GRAPHING) STT Ký hiệu Ý nghĩa Giải thích 1 Tương đương Nếu đúng thì đúng. 2 AND (và) Nếu đúng và đúng, thì đúng. 3 OR (hoặc) Nếu đúng hoặc đúng, thì đúng. 4 NOT (phủ định) Nếu sai, thì đúng. Nếu đúng, thì sai, hoặc nếu sai, 5 Loại trừ thì đúng. 6 Bao hàm bao hàm 7 Yêu cầu yêu cầu 49 v1.1013109225 VÍ DỤ KIỂM THỬ HỘP ĐEN THEO ĐỒ THỊ CAUSE-EFFECT Có modun chương trình tính thuế thu nhập, có mô tả sau: •Ngườivôgiacư nộp4%thuế thu nhập; •Người có nhà ở nộpthuế như sau: Tổng thu nhập<=5.000.000đồng thì nộpthuế 4%; Tổng thu nhập > 5.000.000 đồng thì nộpthuế 6%. Bảng quan hệ nguyên nhân và kếtquả Nguyên nhân Kết quả Người có nhà ở: Tổng thu nhập <= 5.000.000 đồng Nộp 4% thuế Tổng thu nhập > 5.000.000 đồng Nộp 6% thuế 50 v1.1013109225 VÍ DỤ KIỂM THỬ HỘP ĐEN THEO ĐỒ THỊ CAUSE-EFFECT Đồ thị nguyên nhân và kếtquả Trường hợp kiểm thử 1 2 3 4 Nguyên nhân và kết quả Nguyên nhân Người có nhà ở Y Y N -- Có tổng thu nhập <= 5.000.000 N Y -- Y Có tổng thu nhập > 5.000.000 Y N -- -- K ế t qu Nộp thuế 4% -- X X X ả Nộp thuế 6% X -- -- -- 51 v1.1013109225 4. CÁC CHIẾN LƯỢC KIỂM THỬ 4.1. Kiểmthử trên xuống (Top-down Test) 4.2. Kiểmthử từ dưới lên (Bottom-up Test) 4.3. Kiểmthử cộttrụ (Big bang Test) 4.5. Kiểmthử kẹp(SandwichTest) 52 v1.1013109225 4.1. KIỂM THỬ TỪ TRÊN XUỐNG DƯỚI – TOP-DOWN TEST •Môđun điềukhiển chính đượcdùngnhư trình điềukhiểnkiểmthử chính, gắndầncác mô đun từ trên xuống theo trậttự dòng điềukhiển. Bắt đầutừ mô đun điềukhiển chính, sau đógắntừng mô đun phụ trợ vào mô đun điềukhiểnthượng cấp. Có thể theo hai cách: Theo chiềusâutrước; Theo chiềurôngtrước. •Kiểmthửđượctiếnhànhkhitừng môđun đượctíchhợpvàohệ thống. Các nút thử xong thì thử tiếpnútkhác; •Cầncócáccuống kéo theo những khó khăndànhchocuống, có ngay chứcnăng điều khiểnhệ thống. 53 v1.1013109225 TIẾN TRÌNH KIỂM THỬ TỪ TRÊN XUỐNG Tiếntrìnhnàygồm6bướcnhư sau: •Môđun điềukhiểnchínhđượcdungnhư bộ lái kiểmthử (Test Driver) và tấtcả các mô đun phụ trợ trựctiếp đượcthaythế bởicáccuống (Stub); •Thaythế dầntừng cuống bằng các mô đun thựcthitương ứng; •Saukhitíchhợpmôđun đó, tiếnhànhkiểmthử tương ứng; • Khi hoàn thành kiểmthử này thì thay thế mộtcuống khác bằng mô đun thực (nghĩalàquaylạibước2); •Cóthể kiểmthử lại(toànbộ hoặc1phầncáckiểmthử trước - kiểmthử hồiquy) để đảmbảokhôngcósaimớinàosinhra; •Tiếptụclặplạibướchaichođếnkhitoànbộ chương trình cấutrúcđượcxâydựng. Kết hợp Kết hợp Hệ cần kiểm thử theo chiều rộng theo chiều sâu 54 v1.1013109225 Sơ đồ ví dụ kiểm thử từ trên xuống 4.2. KIỂM THỬ TỪ DƯỚI LÊN (BOTTOM-UP TEST) •Bắt đầuxâydựng kiểmthử từ các mô đun nguyên tố; •Việcxử lý nếucóđòi hỏicácmôđun phụ trợ thì các mô đun chính đãsẵnsàng (cuống đãbị loại); • Luôn chưacóchương trình chỉnh thể,thiếtkế các ca kiểmthử dễ không cầncuống; •Thựchiệntheo4bước: Các mô đun mứcthấp đượctíchhợpthànhcáccụmthựchiệnmộtchứcnăng phụ trợ nhất định; Mộtbộ lái đượcviết để phốihợp đầuvàovàđầuracủa các ca kiểmthử; Kiểmthử cụm đó; Tháo bỏ các Driver và các cụmtổ hợpngượclêntrongcầutrúcchương trình. 55 v1.1013109225 VÍ DỤ Vòng 1 Vòng 2 Vòng 3 56 v1.1013109225 4.3. KIỂM THỬ CỘT TRỤ (BIG BANG TEST) •Tíchhợpkhôngtăng dần; •Tấtcáccácmôđun đều đượctổ hợptrước; •Toànbộ chương trình đượckiểmthử tổng thể; •Khókhăn:Khócôlậplỗi, khi chữaxonglỗinàycóthể lỗimớilạiphátsinh. 57 v1.1013109225 4.4. KIỂM THỬ KẸP (SANDWICH TEST) Phương pháp kiểmthử hỗnhợp(Sandwich)cóthể là phương pháp phù hợpnhất: •Tíchhợptrênxuống cho các mứctrêncấutrúcchương trình; •Tíchhợpdướilênchocácmứcphụ thuộc. 58 v1.1013109225 5. CÁC CẤP ĐỘ KIỂM THỬ 5.1. Kiểmthửđơnvị 5.2. Kiểmthử tích hợp 5.3. Kiểmthử hệ thống 5.4. Kiểmthử chấpnhậnsảnphẩm 5.5. Mộtsố cấp độ kiểmthử khác 59 v1.1013109225 5.1. KIỂM THỬ ĐƠN VỊ (UNIT TESTING) •UnitTestinglàviệckiểmthửởmức độ thấpnhấtlàcácphương thức(Method),hàm (Function), lớp (Class) trong mã nguồn. Nhằm đảmbảocácthànhphầntrênhoạt động đúng như yêu cầu; •Việckiểmtraở mức độ này thường do chính các lập trình viên (Developer) thựchiện trong quá trình mã hóa (Coding, Implement); •Mộtmôhìnhthường được ứng dụng vớiUnitTestinglàPháttriểntheođịnh hướng kiểmthử (Test-Driven Development): Các Unit Test viếttrướcdựatheoyêucầukếtquả trả về ban đầu là sai (False); Mã nguồnsẽđượcviếtsauvàđượckiểmtratựđộng bằng các Unit Test; Việcpháttriển được hoàn thành khi các Unit Test trả về kếtquảđúng (True). •TrongISTQB(phiênbản 2007), khái niệmUnitTestingđượchiểu là Component Testing. Lý do là các công việctrênđượcthựchiệnbởilậptrìnhviên.Cáctàiliệutrên phân loạidướiquanđiểmcủamộtkiểmthử viên. 60 v1.1013109225 ĐẶC ĐIỂM CỦA KIỂM THỬ ĐƠN VỊ (UNIT TEST) •Ngườitiếnhànhkiểmthử thông thường là ngườilậptrìnhmôđun đóhoặc lập trình viên cùng nhóm; •Kiểmthử riêng biệttừng đơnvị phầnmềm; •Số lượng nhiềunhưng đơngiản; •Xuyênsuốtthờigianlậptrìnhvàcả chu kỳ phầnmềm; •Kiểmthử Unit là mứcthấpnhấttrongtiếntrìnhkiểmthử,thường là áp dụng phương pháp kiểmthử hộptrắng; •Thường là đượcthựchiệnbớinhàpháttriểntrướckhicácmôđun đượctích hợpvớicácmôđun khác; •Kếtquả củakiểmthử Unit thường tìm ra khoảng 20% lỗitrongtấtcả cá lỗi củadự án. 61 v1.1013109225 PHƯƠNG PHÁP GÌ ĐƯỢC ÁP DỤNG CHO KIỂM THỬ ĐƠN VỊ •Nókiểmthử các phầnsau: Thử nghiệmgiaodiện; Khám nghiệncấutrúcdữ liệucụcbộ; Thử nghiệmvớicácđiềukiệnbiên; Các đường độclập; Các đường xử lý sai. •Kiểmthửđơnvị sử dụng các kỹ thuật: Kiểmthửđường cơ sở; Kiểmthử vòng lặp; Kiểmthử biên. 62 v1.1013109225 5.2. KIỂM THỬ TÍCH HỢP •Kiểmthử Tích hợp (Intergration Testing): Là mộtkỹ thuậtcótínhhệ thống để xây dựng cấutrúcchương trình ngay khi đang tiếnhànhkiểmthửđểphát hiện sai liên kếtvớigiaodiện. •Phảikiểmthử tích hợpvì: Dữ liệucóthể bị mấtkhiđiquamộtgiaodiện; Mộtmođun có thehẻ có mộthiệu ứng bấtlợivôtìnhlêncácmôđun khác; Các chứcnăng phụ khi kếthợplạicóthể không sinh ra chứcnăng chính mong muốn; Các điềukhôngchínhxácriêngrẽ có thể bị phóng đại đếnmức không chấp nhận được; Các cấutrúcdữ liệutoàncụccóthểđểlộ ra các vấn đề •Phương pháp đượcápdụng cho kiểmthử tích hợp Phương pháp “big-bang”; Phương pháp trên xuống; Phương pháp dướilên. 63 v1.1013109225 5.3. KIỂM THỬ HỆ THỐNG Kiểmthử hệ thống (System Testing): •Làmức độ kiểmthử toàn bộ các chứcnăng củahệ thống phầnmềm. Bao gồmtấtcả các thành phầntương tác với nhau, và hoạt động trong môi trường giống như môi trường thựctế như hệđiềuhành,cơ sở dữ liệu, kếtnốimạng, khả năng tương thích vớicácphầnmềmkhác, •Kiểmthử hệ thống cũng chú ý đếnvấn đề bảomật, thân thiện, khả năng đáp ứng, tốc độ thựchiệncủahệ thống phầnmềm. 64 v1.1013109225 5.4. KIỂM THỬ CHẤP NHẬN SẢN PHẨM Kiểmthử chấpnhận (Acceptance Testing, User Acceptance Testing): •Mức độ này đượcthựchiệnbởiphíangười dùng vớimộtnhómđộclậpvới nhóm phát triển. Mục đích củagiaiđoạnnàylàkiểmtra,đánh giá phầnmềmcóđáp ứng đượccácyêucầucủangườidùngđã đề ra hay không? Có thể triển khai cho công việcthựctế củangườidùnghaykhông; •Việc đượcngườidùngchấpnhậnsẽđánh dấuchosự kếtthúccủagiaiđoạnphát triển, mở ra giai đoạntriểnkhai,bảotrìvànângcấpphầnmềm. •Cácloạikiểmthử chấpnhậnsảnphẩm: Kiểmthử Alpha (Alpha Testing): . Do người dùng thựchiện; . Trong môi trường đượcquảnlý. Kiểmthử Beta (Beta Testing): . Do người dùng thựchiện; . Trong môi trường thực. 65 v1.1013109225 5.5. MỘT SỐ CẤP ĐỘ KIỂM THỬ KHÁC •Kiểmthử hộp xám (Gray-box Testing): Là hình thức“lai”giữakiểmthử hộp đen và kiểmthử hộptrắng; •Kiểmthử bằng tay (Manual Testing): Là kỹ thuậtkiểmthử mà các công đoạn được làmhoàntoànbằng sứcngười; •Kiểmthử tựđộng (Automation Testing): Là kỹ thuậtkiểmthử vớicáccôngđoạn được tựđộng hóa bởi máy tính thông qua các “đoạnmãkiểmthử”(Test Script) 66 v1.1013109225 TÓM LƯỢC CUỐI BÀI • Đã trình bày các khái niệmvề kiểmthử,vòngđờicủakiểmthử và mối tương quan giữaquátrìnhxấydựng phầnmềm và các giai đoạnkiểmthử phầnmềm; • Đãtrìnhbàyđượccácphương pháp kiểmthử và mộtsố ví dụ tương ứng; • Đãtrìnhbàyđượccáckỹ thuậtkiểmthử và mộtsố vì dụ tương ứng; • Đãtrìnhbàyđượccácmức độ kiểmthử và mộtsố ví dụ tương ứng 67 v1.1013109225
File đính kèm:
- bai_giang_cong_cu_kiem_thu_phan_mem_bai_2_kiem_thu_phan_mem.pdf