É o mesmo que dizer que
Isto é, todas as linhas de código precisam ser cobertas com testes. Devemos lutar para evitar exceções. Exceções criam lacunas potenciais.
Emmet: build>plugins>plugin:jacoco
Live Template: plugin:jacoco
mvn clean verify
Etapas que serão executadas em sequência:
clean
: apaga tudo da pasta target
;verify
: executa todos os testes e gera relatório de cobertura de testes do JaCoCoopen target/site/jacoco/index.html
Alcançar 100% é o ideal a ser buscado.
Benefícios gerados de um código desacoplado e testado:
devido
Quer dizer, menos de 100%.
Estar entre 90% e 99.999...% pode ser tolerável em algumas circunstâncias específicas, como em partes mais complexas de se testar (artefatos de configuração). Devemos justificar a razão para tal.
é o mesmo que
Riscos:
"À medida que os testes ficam mais específicos, o código fica mais genérico." (Uncle Bob em Clean Craftsmanship).
while
é um if
generalizadoint f(int n) {
int i = 1, r = -1;
if (n < 1) return r;
r = g(n, i);
i++;
if (n == i) return r;
r = g(n, i);
i++;
if (n == i) return r;
r = g(n, i);
i++;
if (n == i) return r;
return r;
}
int f(int n) {
int i = 1;
int r = -1;
while (n >= i) {
r = g(n, i);
i++;
}
return r;
}
if
é um while
degenerado (simples)Podemos desfazer um while
numa sequência de ifs
. Só fazer o processo inverso do exemplo anterior.
Na página 59 (Clean Craftsmanship), Bob aponta a Regra 5: generalize sempre que possível.
Edmonds apresenta algumas generalizações de algoritmos em "How to Think about Algorithms" (2008).
Edmond estabelece que todo código iterativo é definido como
Podemos resumir em Java como
// Zona de pre-loop
int i = 0;
// Loop
while (true) {
// Zona de verificacao de invariante de loop
// Condicao de saida do loop
if (true) break;
// Codigo do loop
i++;
}
// Zona do pos loop
É a verdade que se mantém a cada iteração de um loop.
Se antes do código do loop o invariante for falso, o código está incorreto.
No exemplo do FindMax, veremos que isso por si só não é o suficiente.
FactTest
canFact
Para entender melhor este exemplo, mais à frente veremos as Leis do Anamorfismo e Catamorfismo do Cálculo de Programas.
Esta alternativa combina características:
A rua está molhada porque choveu.
- Causa: A chuva
- Efeito: Fez a rua ficar molhada
Devemos descobrir o "Como" fazer dar certo.
int r = n;
int i = 1;
var list = new ArrayList<Integer>();
while (true) {
// Invariante de Loop
list.add(n - i + 1);
assertEquals(list.stream().reduce((a, b) -> a * b).get(), r);
if (i == n) break;
r = r * (n - i);
i++;
}
n = 2
iteracao (i = 1)
t = n - i + 1 = 2 - 1 + 1 = 2
L = [t] = [2]
r = L[0] = 2
iteracao (i = 2)
t = n - i + 1 = 2 - 2 + 1 = 1
L = [2, t] = [2, 1]
r = L[0] * L[1] = 2
n = 3
iteracao (i = 1)
t = n - i + 1 = 3 - 1 + 1 = 3
L = [t] = [3]
r = L[0] = 3
iteracao (i = 2)
t = n - i + 1 = 3 - 2 + 1 = 2
L = [3, t] = [3, 2]
r = L[0] * L[1] = 6
iteracao (i = 3)
t = n - i + 1 = 3 - 3 + 1 = 1
L = [3, 2, t] = [3, 2, 1]
r = L[0] * L[1] * L[2] = 6
Clique no link acima.
assertEquals(4, findMax(List.of(1, 2, 3, 3, 4)));
private int findMax(List<Integer> list) {
if (list.isEmpty()) return -1;
else if (list.size() == 1) return 0;
int i = 0, j = 0;
System.out.println("Analise de asserções de invariante de loop");
while (true) {
int nextIndex = i + 1;
// Invariante de Loop: L[j] == max(L[0...i+1])
System.out.println(list.get(j) + " é o max de " + list.subList(0, nextIndex));
assertEquals(list.get(j), max(list.subList(0, nextIndex)));
if (i == list.size() - 1) break;
if (list.get(i) < list.get(nextIndex)) {
j = nextIndex;
}
i++;
}
System.out.println("-------");
return j;
}