270 likes | 498 Views
Kiểm thử và đảm bảo chất lượng phần mềm. Kiểm thử luồng dữ liệu. Nội dung. Kiểm thử cấu trúc Tổng quan Kiểm thử theo luồng điều khiển Kiểm thử theo luồng dữ liệu Phương pháp kết hợp Tổng kết về kiểm thử cấu trúc. Ý tưởng của kiểm thử luồng dữ liệu.
E N D
Kiểm thử và đảm bảo chất lượng phần mềm Kiểm thử luồng dữ liệu
Nội dung • Kiểm thử cấu trúc • Tổng quan • Kiểm thử theo luồng điều khiển • Kiểm thử theo luồng dữ liệu • Phương pháp kết hợp • Tổng kết về kiểm thử cấu trúc
Ý tưởng của kiểm thử luồng dữ liệu • Kiểmthửluồngdữliệuliênquanđếnviệcchọnđườngđivớimụctiêubaophủcáccặpgán (definition) vàdùng (use) dữliệu, đượcgọilàcáctiêuchuẩnluồngdữliệu • Qui trìnhtổngquátcủakiểmthửluồngdữliệulà: • Vẽđồ thị luồngdữliệuchochươngtrình • Chọntiêuchuẩnkiểmthửluồngdữliệu • Xácđịnhcácđườngđitrongđồ thị đểthỏamãntiêuchuẩnlựachọn (all-defs, all-uses, all-P-uses/some-C-uses, v.v..) • Tạo các ca kiểmthửchocácđườngđiđãxácđịnh
Đỉnh gán • Đỉnh n trong CFG của chương trình P là đỉnh gán của biến v, viết là DEF(v, b), nếu và chỉ nếu giá trị của v được xác định không mơ hồ tại lệnh ở đỉnh n
Đỉnh dùng • Đỉnh n trong đồ thị CFG của chương trình P là đỉnh dùng của biến v, viết là USE(v, n), nếu và chỉ nếu giá trị của biến v được dùng ở lệnh tại đỉnh n. • Một đỉnh dùng là dùng vị từ (predicate), ký hiệu P-use nếu và chỉ nếu lệnh tương ứng ở đỉnh n là lệnh vị từ • Trái lại, nó là dùng tính toán, ký hiệu C-use • Đỉnh tương ứng với P-use luôn có bậc ra >= 2 và các đỉnh tương ứng với C-use luôn có bậc ra <= 1
Ví dụ luồng điều khiển có chú thích • Luồng dữ liệu cho biến Z: 1 INPUT X,Y Z:= X+Y Y:= X-Y 3 IF Z>=0 GOTO SAM 4 JOE: Z:=Z-1 5 SAM: Z:=Z+V U:=0 6 LOOP B(U),Q(V):=(Z+V)*U 7 IF B(U)=0 GOTO JOE Z:=Z-1 8 IF Z=0 GOTO ELL U:=U+1 9 UNTIL U=z B(U-1):=B(U+1)+Q(V-1) 10 ELL: B(U+Q(V)):=U+V 11 IF U=V GOTO JOE 12 IF U>V THEN U:=Z 13 YY:Z:=U 2 END p LOOP B(U)? JOE d 1 3 4 5 6 7 p cd cd c SAM Z? cd END p 2 ELL d p p c 13 12 11 10 9 8 U,Z? YY U,V? U,V? p
Một số định nghĩa • Gọi PATHS(P) làtậptấtcảcácđườngđicóthểtrong CFG củachươngtrình P. • Mộtđườngđi du-path (def-use) chobiến v làđườngđitrong PATHS(P) thỏamãn • Tồntại DEF(v, m) và USE(v, n) sao cho m và n tươngứnglàđỉnhđầuvàcuốicủađườngđi • Mộtđườngđi dc-path vớibiến v làmột du-path vớicácđỉnhđầu DEF(v, m) và USE(v,n) sao chokhôngcóđỉnhnào ở trênđườngđiđógángiátrịcho v.
Một số định nghĩa • Gán toàn cục của biến x ở đỉnh n là DEF(x, n) và tồn tại một đường đi từ n đến một đỉnh m nào đó chứa C-use hoặc P-use toàn cục của x. • Một C-use toàn cục của x tại đỉnh n là một C-use của x ở n và x chưa được gán ở đỉnh nào khác ngoài n
Một số định nghĩa • Đường điđơngiảnlàđườngcóđỉnhđầuvàcuốikhôngtrùngnhau. • Đường đikhôngcóvònglặplàđườngtấtcảcácđỉnhkotrùngnhau. • Đường điđầyđủlàđườngtừđỉnhvàođếnđỉnhracủa CFG • Du-path vớibiến x ở đỉnh n1 làđườngđi n1..nk mà • n1 cógántoàncụccho x và • nk có c-use của x vàđườngđinàylàđơngiản, hoặc • nk có p-use của x vàđườngđinàylàkhôngcóvònglặpvới x.
Ví dụ liên kết def-use • Liên kết def-use của chương trình dươi đây là gì? read (z) x = 0 y = 0 if (z 0) { x = sqrt (z) if (0 x && x 5) y = f (x) else y = h (z) } y = g (x, y) print (y)
Ví dụ liên kết def-use read (z)x = 0 y = 0if (z 0){ x = sqrt (z) if (0 x && x 5) y = f (x) else y = h (z) } y = g (x, y) print (y) def-use chobiến z.
Tiêu chuẩn bao phủ kiểm thử DU-Path • Ý tưởng • Sử dụng thông tin def-use và tiêu chuẩn cụ thể để nhận được các đường đi cụ thể trong đồ thị CFG • Từ đó xác định các ca kiểm thử • Chúng ta giả sử T là tập các đường đi đầy đủ và khả thi trong CFG của chương trình P và V là tập tất cả các biến trong P
Tiêu chuẩn bao phủ DU-Path • T thỏamãntiêuchuẩn All-Defsnếuvàchỉnếuvớimọi v, T chứacácđườngđi dc-path từmọiđỉnhgáncủa v đếnmộtđỉnhdùngcủa v • Tậpđếnđượccủacácgán • T thỏamãntiêuchuẩn All-Uses nếuvàchỉnếuvớimọi v, T chứacácđườngđi dc-path từmọiđỉnhgáncủa v đếnmọiđỉnhdùng v vàđếnđỉnhtiếptheocủamỗi USE(v, n) • Chúng ta cóthểlàmmịnhơnbằng All-C-Uses và All-P-Uses
Tiêu chuẩn bao phủ DU-Path • All-P-Uses/Some-C-Uses • Với mọi v, T gồm các đường đi dc-path từ mọi đỉnh gán của v đến mọi đỉnh p-use của v và nếu một định nghĩa của v không có p-use thì tồn tại một đường đi dc-path đến ít nhất một c-use • All-C-Uses/Some-P-Uses • Với mọi v, T gồm các đường đi dc-path từ mọi đỉnh gán của v đến mọi đỉnh c-use của v và nếu một định nghĩa của v không có c-use thì tồn tại một đường đi dc-path đến ít nhất một p-use
Tiêu chuẩn bao phủ DU-Path • All-DU-Paths • Với mọi v, T gồm các đường đi dc-path từ mọi đỉnh gán của v đến mọi đỉnh dùng của v và đến đỉnh tiếp theo của mỗi USE(v, n) và các đường đi này hoặc là lặp một lần hoặc không lặp
Ví dụ All-DU-Paths: pow(x,y) /* pow(x,y) tính x mũ y với x, y làsốnguyên INPUT: giátrịcủa x và y. OUTPUT: in x mũ y ramànhình. */ • void pow (int x, y) • { • float z; • int p; • if (y < 0) • p = 0 – y; • else p = y; • z = 1.0; • while (p != 0) • { • z = z * x; • p = p – 1; • } • if (y < 0) • z = 1.0 / z; • printf(z); • } b g a f i d 1 5 8 9 14 16 17 c h e
All-DU-Paths vơi biến x 1 void pow (int x, y) 2 { 3 float z; 4 int p; b g 5 if (y < 0) a f i 6 p = 0 – y; d 7 else p = y; 1 5 8 9 14 16 17 8 z = 1.0; 9 while (p != 0) c h e 10 { 11 z = z * x; 12 p = p – 1; 13 } 14 if (y < 0) 15 z = 1.0 / z; 16 printf(z); 17 }
All-DU-Paths với biến x 1 void pow (int x, y) 2 { 3 float z; 4 int p; b g 5 if (y < 0) a f i 6 p = 0 – y; d 7 else p = y; 1 5 8 9 14 16 17 8 z = 1.0; 9 while (p != 0) c h e 10 { 11 z = z * x; 12 p = p – 1; 13 } 14 if (y < 0) 15 z = 1.0 / z; 16 printf(z); 17 }
All-DU-Paths với biến y 1 void pow (int x, y) 2 { 3 float z; 4 int p; b g 5 if (y < 0) a f i 6 p = 0 – y; d 7 else p = y; 1 5 8 9 14 16 17 8 z = 1.0; 9 while (p != 0) c h e 10 { 11 z = z * x; 12 p = p – 1; 13 } 14 if (y < 0) 15 z = 1.0 / z; 16 printf(z); 17 }
All-DU-Paths với biến y 1 void pow (int x, y) 2 { 3 float z; 4 int p; b g 5 if (y < 0) a f i 6 p = 0 – y; d 7 else p = y; 1 5 8 9 14 16 17 8 z = 1.0; 9 while (p != 0) c h e 10 { 11 z = z * x; 12 p = p – 1; 13 } 14 if (y < 0) 15 z = 1.0 / z; 16 printf(z); 17 }
All-DU-Paths với biến y 1 void pow (int x, y) 2 { 3 float z; 4 int p; b g 5 if (y < 0) a f i 6 p = 0 – y; d 7 else p = y; 1 5 8 9 14 16 17 8 z = 1.0; 9 while (p != 0) c h e 10 { 11 z = z * x; 12 p = p – 1; 13 } 14 if (y < 0) 15 z = 1.0 / z; 16 printf(z); 17 }
Ví dụ tính trung bình public static double ReturnAverage(int value[], int AS, int MIN, int MAX) { int i, ti, tv, sum; double av; i = 0; ti = 0; tv = 0; sum = 0; while (ti < AS && value [i] != -999) { ti++; if (value[i] >= MIN && value[i} <= MAX) { tv++; sum = sum + value[i]; } i++; } if (tv > 0) av = (double) sum/tv; else av = (double) -999; return (av) }
CFG của hàm tính trung bình Initialize: value[] AS, MIN, MAX 1 i=0; ti=0; tv=0, sum=0 2 ((ti < AS) && (value[i] != -999)) 3 T F ti++; (value[i] >= MIN && value[i] <= MAX) 7 4 tv > 0 T T F F tv++; sum= sum+value[i] av = (double) sum/tv 9 av = (double) -999 5 8 i++ 10 return(av) 6
Đường đi • c-use toàn cục cho biến tv: đỉnh 9 (tv được gán ở đỉnh 2 và 5) • Các đường đi def-clear cho biến tv: 2-3-4-5, 2-3-4-6 • Đường đi đơn giản: 2-3-4-5 và 3-4-6-3 • Đường đi thỏa mãn All-defs cho biến tv: • 1-2-3-4-5-6-3-7-9-10, • Và với p-uses 1-2-3-7-8-10 và 1-2-3-4-5-6-3-7-9-10
Đường đi • Đường đi cho tiêu chuẩn All-c-uses cho biến ti: • 1-2-3-4-5-6-3-7-8-10, • 1-2-3-4-5-6-3-7-9-10, • 1-2-3-4-6-3-7-8-10, • 1-2-3-4-6-3-7-9-10 • Đường đi cho tiêu chuẩn All-p-uses cho biến tv: • 1-2-3-7-8-10 • 1-2-3-7-9-10 • 1-2-3-4-5-6-3-7-8-10 • 1-2-3-4-5-6-3-7-9-10
Đường đi • All-p-uses/some-c-uses cho i: • 1-2-3-4-5-6-3-7-9-10 • All-c-uses/some-p-uses cho AS: • 1-2-3-4-5-6-3-7-9-10 • All-uses: • Hợp của all-c-uses và all-p-uses • All-du-paths choh tv: • 1-2-3-4-5-6-3-7-8-10 …. 1-2-3-7-9-10