3. Code Coverage
dado un conjunto de pruebas
¿qué porcentaje del total del
software bajo prueba (código)
es cubierto por las pruebas?
4. Code Coverage
dado el siguiente método
public class Foo {
public void methodUnderTest(int a, int b, int c) {
System.err.println("do something with a: " + a);
System.err.println("do something with b: " + b);
System.err.println("do something with c: " + c);
}
}
¿cómo lo probamos?
(de forma satisfactoria)
5. Line Coverage
public class Foo {
public void methodUnderTest(int a, int b, int c) {
System.err.println("do something with a: " + a);
System.err.println("do something with b: " + b);
System.err.println("do something with c: " + c);
}
}
@Test
public void foo_line_coverage() {
Foo foo = new Foo();
foo.methodUnderTest(1, 2, 3);
}
¿se ejecutan todas las líneas de código?
cobertura de líneas de código del 100%
¿será suficiente?
6. Code Coverage
veamos otro ejemplo
public class Faa {
public void methodUnderTest(int a, int b) {
if (a < b) {
System.out.println("do something when a < b");
}
System.out.println("always do something here");
}
}
¿cómo lo probamos?
(de forma satisfactoria)
7. Code Coverage
public class Faa {
public void methodUnderTest(int a, int b) {
if (a < b) {
System.out.println("do something when a < b");
}
System.out.println("always do something here");
}
}
@Test
public void faa_line_coverage() {
Faa faa = new Faa();
faa.methodUnderTest(1, 2);
}
¿se ejecutan todas las líneas de código?
cobertura de líneas de código del 100%
¿será suficiente?
8. Code Coverage
public class Faa {
public void methodUnderTest(int a, int b) {
if (a < b) {
System.out.println("do something when a < b");
}
System.out.println("always do something here");
}
}
@Test
public void faa_line_coverage() {
Faa faa = new Faa();
faa.methodUnderTest(1, 2);
}
se ejecutan todas las líneas de código,
pero no se prueban todos las posibles
salidas del if, es decir, no hay un 100%
de cobertura de ramas
9. Branch Coverage
public class Faa {
public void methodUnderTest(int a, int b) {
if (a < b) {
System.out.println("do something when a < b");
}
System.out.println("always do something here");
}
}
@Test @Test
public void faa_branch_coverage1() { public void faa_branch_coverage2() {
Bar bar = new Bar(); Bar bar = new Bar();
bar.methodUnderTest(1, 2); bar.methodUnderTest(3, 2);
} }
ahora no solo se ejecutan el 100% de las
líneas de código, sino que se ejecutan todas las
alternativas de cada estructura de control
(100% cobertura de ramas)
¿será suficiente?
10. Code Coverage
aún otro ejemplo
public class Bar {
public void methodUnderTest(int a, int b, int c) {
if (a < c) {
System.out.println("do something when a < c");
} else {
System.out.println("do something when a >= c");
}
if (b < c) {
System.out.println("do something when b < c");
} else {
System.out.println("do something when b >= c");
}
}
}
¿cómo lo probamos?
(de forma satisfactoria)
11. Code Coverage
aún otro ejemplo
public class Bar {
public void methodUnderTest(int a, int b, int c) {
if (a < c) {
System.out.println("do something when a < c");
} else {
System.out.println("do something when a >= c");
}
if (b < c) {
System.out.println("do something when b < c");
} else {
System.out.println("do something when b >= c");
}
}
}
no hay manera de obtener
100% de cobertura
de líneas de código con un sólo test
12. Code Coverage
if (a < c) {
System.out.println("do something when a < c");
} else {
System.out.println("do something when a >= c");
}
if (b < c) {
System.out.println("do something when b < c");
} else {
System.out.println("do something when b >= c");
}
@Test @Test
public void bar_branch_coverage1() { public void bar_branch_coverage2() {
Bar bar = new Bar(); Bar bar = new Bar();
bar.methodUnderTest(1, 1, 2); bar.methodUnderTest(3, 3, 2);
} }
¿se ejecutan todas las líneas de código?
¿se prueban todas las ramas?
cobertura de líneas de código del 100%
cobertura de ramas del 100%
¿será suficiente?
13. Code Coverage
if (a < c) {
System.out.println("do something when a < c");
} else {
System.out.println("do something when a >= c");
}
if (b < c) {
System.out.println("do something when b < c");
} else {
System.out.println("do something when b >= c");
}
@Test @Test
public void bar_branch_coverage1() { public void bar_branch_coverage2() {
Bar bar = new Bar(); Bar bar = new Bar();
bar.methodUnderTest(1, 1, 2); bar.methodUnderTest(3, 3, 2);
} }
¿se prueban todas las combinaciones posibles
entre las distintas ramas?
(cobertura de caminos)
para tener un 100% de cobertura de caminos
no es suficiente con 2 pruebas
14. Code Coverage
if (a < c) {
System.out.println("do something when a < c");
} else {
System.out.println("do something when a >= c");
}
if (b < c) {
System.out.println("do something when b < c");
} else {
System.out.println("do something when b >= c");
}
@Test @Test
public void bar_path_coverage1() { public void bar_path_coverage3() {
Bar bar = new Bar(); Bar bar = new Bar();
bar.methodUnderTest(1, 1, 2); bar.methodUnderTest(1, 3, 2);
} }
@Test @Test
public void bar_path_coverage2() { public void bar_path_coverage4() {
Bar bar = new Bar(); Bar bar = new Bar();
bar.methodUnderTest(3, 3, 2); bar.methodUnderTest(3, 1, 2);
} }
ahora hay 100% de cobertura de caminos
15. Code Coverage
if (a < c) {
System.out.println("do something when a < c");
} else {
System.out.println("do something when a >= c");
}
if (b < c) {
System.out.println("do something when b < c");
} else {
System.out.println("do something when b >= c");
}
@Test @Test
public void bar_path_coverage1() { public void bar_path_coverage3() {
Bar bar = new Bar(); Bar bar = new Bar();
bar.methodUnderTest(1, 1, 2); bar.methodUnderTest(1, 3, 2);
} }
@Test @Test
public void bar_path_coverage2() { public void bar_path_coverage4() {
Bar bar = new Bar(); Bar bar = new Bar();
bar.methodUnderTest(3, 3, 2); bar.methodUnderTest(3, 1, 2);
} }
ahora hay 100% de cobertura de caminos
17. Complejidad Ciclomática
¿complejidad ciclomática?
término acuñado por
Thomas J. McCabe (1976)
cuenta el número de caminos
linealmente independientes a lo largo de
un programa/función/método
es una forma de medir (metrica) la
complejidad del código fuente
18. Complejidad Ciclomática
public class Foo {
public void methodUnderTest(int a, int b, int c) {
System.err.println("do something with a: " + a);
System.err.println("do something with b: " + b); CC=1
System.err.println("do something with c: " + c);
}
}
public class Faa { CC=2
public void methodUnderTest(int a, int b) {
if (a < b) {
System.out.println("do something when a < b");
}
System.out.println("always do something here");
}
}
19. Complejidad Ciclomática
if (a < c) {
System.out.println("do something when a < c");
} else {
System.out.println("do something when a >= c");
}
if (b < c) {
System.out.println("do something when b < c");
} else {
System.out.println("do something when b >= c");
}
CC=3
20. Complejidad Ciclomática
CC = E – N + 2 * P
E: # de arístas (8)
N: # de nodos (7)
P: # de salidas (1)
CC = 8 – 7 + 2 * 1
CC = 3
en general
#pruebas 100% Cobertura de Ramas
<=
complejidad ciclomática
<=
#pruebas 100% Cobertura de Caminos
21. Code Coverage
Ejemplos Corriendo
Emma / EclEmma (http://www.eclemma.org/)
22. Code Coverage
Clover (Attlasian) Privativo
(http://www.atlassian.com/software/clover/)
Emma / EclEmma
http://www.eclemma.org/ y
http://emma.sourceforge.net/
Coverlipse
http://coverlipse.sourceforge.net/
Algunas otras en:
http://java-source.net/open-source/code-coverage