Metody przewidywania jakości produktu: szacowanie defektów w kodzie Adam Roman Instytut Informatyki i Matematyki Komputerowej UJ TestWell, 21 IV 2015, Kraków
i wtedy powiedziałam PMowi, że po 6 tygodniach prac nad projektem wiemy, że będzie w nim w sumie 146 defektów i jeśli zrobimy release już za 4 tygodnie, to w kodzie wciąż zostanie 12 defektów polowych; ich naprawa będzie kosztować 3 razy więcej, niż koszt wydłużenia prac o 2 tygodnie, w których znajdziemy 9 z tych defektów, ale z drugiej strony nie opłaci się nam szukać ich dalej
i wtedy powiedziałam PMowi, że po 6 tygodniach prac nad projektem wiemy, że będzie w nim w sumie 146 defektów i jeśli zrobimy release już za 4 tygodnie, to w kodzie wciąż zostanie 12 defektów polowych; ich naprawa będzie kosztować 3 razy więcej, niż koszt wydłużenia prac o 2 tygodnie, w których znajdziemy 9 z tych defektów, ale z drugiej strony nie opłaci się nam szukać ich dalej
Ile waży wół? Czyli mądrość tłumu
Wisdom of crowd 2.0: metoda delficka RUNDA 1 RUNDA 2 RUNDA 3 RUNDA 4 WYNIK X X X X X X 0 10 20 30 40 50 X X X X X 0 10 20 30 40 50 X X X X 0 10 20 30 40 50 X X 0 10 20 30 40 50 X 0 10 20 30 40 50
Dane historyczne: metoda naiwna PROJEKT A - zakończony KLOC 45 Defekty / KLOC 1.4 Defekty wykryte 63 Defekty polowe 8 PROJEKT B w trakcie KLOC (ew. estymacja KLOC) 70 Defekty / KLOC 1.4 Predykcja wykrytych defektów 98 Defekty polowe 12 =70*1.4 =98*(8/63)
Dane historyczne: metoda naiwna PROJEKT A - zakończony KLOC 45 Defekty / KLOC 1.4 Defekty wykryte 63 Defekty polowe 8 PROJEKT B w trakcie KLOC (ew. estymacja KLOC) 70 Defekty / KLOC 1.4 Predykcja wykrytych defektów 98 Defekty polowe 12 =70*1.4 =98*(8/63) technologia? doświadczenie zespołu? proces testowy? czas trwania projektu? złożoność/trudność projektu? typ projektu?
Dane historyczne: Rome Lab Model
Barry Boehm Model COCOMO II: COnstructive COst MOdel
COCOMO II dla defektów: COQUALMO
Jak policzyć ryby w stawie?
Jak policzyć ryby w stawie? POŁÓW złowiono 8 rybek OZNACZENIE oznaczono 8 rybek Wypuszczenie rybek do stawu
Jak policzyć ryby w stawie? POŁÓW złowiono 8 rybek OZNACZENIE oznaczono 8 rybek Wypuszczenie rybek do stawu PONOWNY POŁÓW
Jak policzyć ryby w stawie? POŁÓW złowiono 8 rybek OZNACZENIE oznaczono 8 rybek Wypuszczenie rybek do stawu 2 spośród 8 rybek są oznaczone Przewidujemy, że w stawie pływa ok. 32 rybek! PONOWNY POŁÓW
Testowanie mutacyjne 1. read X, Y 2. if (X>0) then { 3. Y = Y + 1 4. } 5. return X+Y PROGRAM 1. read X, Y 2. if (X>0) then { 3. Y = X + 1 4. } 5. return X+Y MUTANT Test 1: X=5, Y=5 Oczekiwany wynik: 11 Test 1: X=5, Y=5 Wynik: 11 Test 2: X=6, Y=5 Oczekiwany wynik: 12 Test 2: X=6, Y=5 Wynik: 13 Tester jest zmuszony dodać nowy test, aby zabić mutanta M2!
Jak szacować defekty przy użyciu mutacji? w analogiczny sposób jak przy zliczaniu rybek w stawie! załóżmy, że testy wykryły D prawdziwych defektów, które zostały naprawione (usunięte) tworzymy N mutantów (symulujemy N sztucznych defektów) testy zabiły M spośród nich, czyli wykryły M/N całości D wynosi około M/N wszystkich prawdziwych defektów czyli szacujemy liczbę wszystkich prawdziwych defektów na (N/M)*D a skoro już usunęliśmy D z nich, w kodzie pozostało: (N/M)*D D = (N/M 1)*D
Model bazujący na pokryciu defekty vs. czas defekty vs. pokrycie w przybliżeniu funkcja liniowa pokrycie vs. czas może nie być obserwowane w niektórych programach eksperymenty dla pokryć: instrukcyjnego, gałęzi, p-use
Model bazujący na pokryciu
Modele zmian w kodzie (churn models) Microsoft, 2005 rok pozwalają na predykcję gęstości defektów na podstawie analizy repozytorium kodu wykorzystują metryki zmian w kodzie: LOC zmienione LOC usunięte LOC liczba plików użytych w kompilacji całkowity czas, w którym plik mógł być edytowany liczba zmian pomiędzy kolejnymi wersjami zmienione pliki
liczba znalezionych defektów Model Rayleigha czas t to pole wynosi ok. 40% pola pod całą krzywą zastosowanie naiwne: oblicz sumę S defektów znalezionych do czasu t szacuj całkowitą liczbę defektów na S/0.4
Model Rayleigha - przykład Tydzień 1 2 3 4 5 6 7 8 9 Liczba defektów 20 41 48 52 62 59 52 44 33 zastosowanie naiwne: max w tygodniu 5 do tygodnia nr 5 znaleziono 20+41+48+52+62 = 223 defektów całkowita liczba defektów szacowana jest na: 223/0.4=557
Model Rayleigha - przykład 1> obs <- data.frame(t=c(1:9), d=c(20,41,48,52,62,59,52,44,33)) 2> pred <- data.frame(t=c(10:15), d=na) 3> points <- rbind(obs, pred) 4> plot(points$t, points$d, xlim=c(1, 15), ylim=c(0, 65), pch=16) 5> model <- nls(d ~ K*2*(t/c^2)*exp(-(t/c)^2), data=points[1:9,], start=list(k=450, c=8)) 6> summary(model) 7> points$predval <- predict(model, newdata=points) 8> lines(points$t, points$predval, type="o", pch=1) 4>
Model Rayleigha - przykład 1> obs <- data.frame(t=c(1:9), d=c(20,41,48,52,62,59,52,44,33)) 2> pred <- data.frame(t=c(10:15), d=na) 3> points <- rbind(obs, pred) 4> plot(points$t, points$d, xlim=c(1, 15), ylim=c(0, 65), pch=16) 5> model <- nls(d ~ K*2*(t/c^2)*exp(-(t/c)^2), data=points[1:9,], start=list(k=450, c=8)) 6> summary(model) 7> points$predval <- predict(model, newdata=points) 8> lines(points$t, points$predval, type="o", pch=1) 6> Formula: d ~ K * 2 * (t/c^2) * exp(-(t/c)^2) Parameters: Estimate Std. Error t value Pr(> t ) K 489.7381 13.2938 36.84 2.82e-09 *** c 7.0245 0.1687 41.65 1.20e-09 *** --- Signif. codes: 0 *** 0.001 ** 0.01 * 0.05. 0.1 1 Residual standard error: 2.977 on 7 degrees of freedom Number of iterations to convergence: 4 Achieved convergence tolerance: 3.137e-06
Model Rayleigha - przykład 1> obs <- data.frame(t=c(1:9), d=c(20,41,48,52,62,59,52,44,33)) 2> pred <- data.frame(t=c(10:15), d=na) 3> points <- rbind(obs, pred) 4> plot(points$t, points$d, xlim=c(1, 15), ylim=c(0, 65), pch=16) 5> model <- nls(d ~ K*2*(t/c^2)*exp(-(t/c)^2), data=points[1:9,], start=list(k=450, c=8)) 6> summary(model) 7> points$predval <- predict(model, newdata=points) 8> lines(points$t, points$predval, type="o", pch=1) 8>
Wykorzystanie modeli niezawodności 1> library("maxlik") 2> i <- 1:10 3> x <- c(7, 11, 8, 10, 15, 22, 20, 25, 28, 35) 4> LL <- function(params) { 5> N <- params[1] 6> Phi <- params[2] 7> sum(log(phi*(n-(i-1))))-sum(phi*(n-(i-1))*x) 8> } 9> fit <- maxlik(ll, start=c(n=14,phi=0.5)) 10> summary(fit) -------------------------------------------- Maximum Likelihood estimation Newton-Raphson maximisation, 9 iterations Return code 2: successive function values within tolerance limit Log-Likelihood: -37.80457 2 free parameters Estimates: Estimate Std. error t value Pr(> t) N 11.5964263 3.5454784 3.2708 0.001073 ** Phi 0.0096343 0.0066917 1.4398 0.149937 --- Signif. codes: 0 *** 0.001 ** 0.01 * 0.05. 0.1 1 -------------------------------------------- czasy pomiędzy kolejnymi awariami magiczna funkcja, korzysta z metody największej wiarygodności główna instrukcja: obliczenie modelu szacunkowa całkowita liczba awarii średni czas do następnej awarii
Wykorzystanie modeli niezawodności 1> library("maxlik") 2> i <- 1:10 3> x <- c(7, 11, 8, 10, 15, 22, 20, 25, 28, 35) 4> LL <- function(params) { 5> N <- params[1] 6> Phi <- params[2] 7> sum(log(phi*(n-(i-1))))-sum(phi*(n-(i-1))*x) 8> } 9> fit <- maxlik(ll, start=c(n=14,phi=0.5)) 10> summary(fit) -------------------------------------------- Maximum Likelihood estimation Newton-Raphson maximisation, 9 iterations Return code 2: successive function values within tolerance limit Log-Likelihood: -37.80457 2 free parameters Estimates: Estimate Std. error t value Pr(> t) N 11.5964263 3.5454784 3.2708 0.001073 ** Phi 0.0096343 0.0066917 1.4398 0.149937 --- Signif. codes: 0 *** 0.001 ** 0.01 * 0.05. 0.1 1 -------------------------------------------- czasy pomiędzy kolejnymi awariami magiczna funkcja, korzysta z metody największej wiarygodności główna instrukcja: obliczenie modelu szacunkowa całkowita liczba awarii średni czas do następnej awarii