You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
title: Code Coverage, Testes de Objeto e Componente
3
3
description: >-
4
4
Code Coverage: statement, branch, condition e path coverage.
5
+
Testes de Objeto (Object Testing)
6
+
Testes de Componente (Component Testing)
5
7
path: /es/code-coverage
6
8
type: content
7
9
---
8
10
9
-
# Code Coverage
11
+
# Code Coverage, Testes de Objeto e Componente
10
12
11
13
```toc
12
14
13
15
```
14
16
17
+
## Code Coverage
18
+
15
19
Em _white-box testing_, podemos definir uma métrica que nos indica a percentagem
16
20
do nosso código que é testado, chamada de _code coverage_.
17
21
22
+
:::tip[Code Coverage]
23
+
24
+
Consiste numa aplicação de _**white-box testing**_ para determinar a percentagem de código
25
+
que é executado quando um dado conjunto de testes é corrido.
26
+
Quanto maior for a _code coverage_, há mais código a ser executado, o que **aumenta a
27
+
probabilidade de encontrar bugs**.
28
+
29
+
:::
30
+
18
31
No entanto, existem diversos critérios que podemos aplicar, cada um com as suas
19
32
vantagens e desvantagens:
20
33
@@ -23,30 +36,159 @@ vantagens e desvantagens:
23
36
-[**_Condition Coverage_**](color:yellow)
24
37
-[**_Path Coverage_**](color:blue)
25
38
26
-
<!-- TODO: colocar exemplo visual de código com grafo de flow para explicar as coverages -->
39
+
Para exemplificar cada um dos critérios acima, teremos em conta o pseudocódigo seguinte, assim
40
+
como o gráfico correspondente às suas possíveis execuções:
27
41
28
-
## Statement Coverage
42
+

29
43
30
-
:::warning[Secção Incompleta]
31
-
Esta secção encontra-se incompleta. Procuram-se contribuidores.
32
-
:::
44
+
Existem [mais exemplos de code coverage disponíveis no StackExchange](https://sqa.stackexchange.com/questions/20226/how-do-we-calculate-statement-coverage-branch-coverage-path-coverage-and-cond).
45
+
46
+
### Statement Coverage
47
+
48
+
A [_Statement Coverage_](color:green) de um programa relaciona-se com a percentagem das linhas de
49
+
código que são executadas com um dado conjunto de testes. Temos _Statement Coverage_ completa quando
50
+
os testes garantem que **todas as linhas de código são executadas pelo menos uma vez**.
51
+
52
+
Tendo em conta o exemplo acima, consideremos dois casos de teste:
53
+
54
+
- Test Case 1: `(b0 && b1) = true`, `b2 = true`
55
+
- Test Case 2: `(b0 && b1) = false`, `b2 = false`
56
+
57
+
Verifica-se que, para executar 100% das linhas do programa, basta ter o Test Case 1, o que nos dá
58
+
uma _Statement Coverage_ completa, enquanto o Test Case 2 apenas excuta 75% das linhas.
59
+
60
+

61
+
62
+
### Branch Coverage
63
+
64
+
A [_Branch Coverage_](color:orange) de um programa relaciona-se com a percentagem de condições que são
65
+
avaliadas com um dado conjunto de teste. Temos _Branch Coverage_ completa quando os testes garantem que
66
+
**todas as condições são avaliadas como verdadeiras e falsas**.
33
67
34
-
## Branch Coverage
68
+
Tendo em conta o exemplo acima, consideremos dois casos de teste:
69
+
70
+
- Test Case 1: `(b0 && b1) = true`, `b2 = true`
71
+
- Test Case 2: `(b0 && b1) = false`, `b2 = false`
72
+
73
+
Verifica-se que ambos os testes apenas testam 50% das condições possíveis, pelo que, para termos
74
+
_Branch Coverage_ completa, temos de considerar, pelo menos, ambos os test cases.
75
+
76
+

77
+
78
+
### Condition Coverage
79
+
80
+
A [_Condition Coverage_](color:yellow) de um programa relaciona-se com a percentagem de subexpressões
81
+
booleanas de condições que são avaliadas como verdadeiro e falso. Temos _Condition Coverage_ completa
82
+
quando os testes garantem que **todas as componentes de uma condição são avaliadas como verdadeiras e
83
+
como falsas**.
84
+
85
+
Tendo em conta o exemplo acima, consideremos três casos de teste:
86
+
87
+
- Test Case 1: `b0 = true`, `b1 = false`, `b2 = false`
88
+
- Test Case 2: `b0 = false`, `b1 = true`, `b2 = true`
89
+
- Test Case 3: `b0 = true`, `b1 = true`, `b2 = true`
90
+
91
+
Verifica-se que, tendo em conta apenas os dois primeiros test cases, as condições `b0` e `b2` são
92
+
ambas avaliadas como verdadeiro e falso. No entanto, devido à presença da conjunção (`&&`), a condição
93
+
`b1` apenas é avaliada como falsa, dado que `b0 = false` e `(b0 && _)` vai ser sempre falso independentemente
94
+
da segunda condição, que acaba por não ser avaliada. Assim, para ter _Condition Coverage_ completa, temos
95
+
de incluir todos os três test cases.
96
+
97
+

98
+
99
+
:::danger[Disjunções e Conjunções]
100
+
101
+
Para verificar _Condition Coverage_, é preciso ter em atenção as disjunções (`||`) e as conjunções (`&&`)
102
+
presentes no código, assim como a ordem pela qual as condições aparecem.
35
103
36
-
:::warning[Secção Incompleta]
37
-
Esta secção encontra-se incompleta. Procuram-se contribuidores.
38
104
:::
39
105
40
-
## Condition Coverage
106
+
### Path Coverage
107
+
108
+
A [_Path Coverage_](color:blue) de um programa relaciona-se com todos os caminhos independentes que podem ser
109
+
percorridos. Temos _Path Coverage_ completa quando **todos os caminhos independentes são executados**.
110
+
111
+
:::tip[Caminho Independente]
112
+
113
+
Um caminho independente num programa é um que atravessa pelo menos uma nova aresta do grafo de execução
114
+
do programa.
115
+
116
+
O número de caminhos independentes pode ser obtido a partir da seguinte maneira:
117
+
118
+
- Um corresponde ao caminho default;
119
+
- Há mais um caminho por cada instrução `if`, `while`, `repeat`, `for`, `and` e `or`;
120
+
- Há mais um caminho por cada `case` numa instrução `switch`, havendo ainda mais um
121
+
caso não haja um caso default.
122
+
123
+
$ \text{Número de Caminhos Independentes} = \text{Número de Decisões} + 1 $
41
124
42
-
:::warning[Secção Incompleta]
43
-
Esta secção encontra-se incompleta. Procuram-se contribuidores.
44
125
:::
45
126
46
-
## Path Coverage
127
+
Tendo em conta o exemplo acima, consideremos dois casos de teste:
128
+
129
+
- Test Case 1: `(b0 && b1) = true`, `b2 = true`
130
+
- Test Case 2: `(b0 && b1) = false`, `b2 = true`
131
+
- Test Case 3: `(b0 && b1) = true`, `b2 = false`
132
+
133
+
Verifica-se que, a cada test case, estamos a percorrer uma aresta no grafo que ainda não tinha sido percorrida,
134
+
pelo que necessitamos dos três test cases para ter _Path Coverage_ completa.
135
+
136
+

137
+
138
+
## Testes de Objeto
139
+
140
+
Os testes de objeto são usados especialmente no contexto de programação orientada a objetos. Ao contrário dos testes
141
+
unitários, que testam funções e métodos de forma isolada, os testes de objeto testam **sequências de métodos**.
142
+
143
+
No contexto dos testes de objeto, é importante saber o conceito de **Classe Modal**.
144
+
145
+
:::tip[Classe Modal]
146
+
147
+
Uma classe modal é uma classe onde o seu estado interno afeta o resultado de certas sequências de invocação
148
+
de métodos. Costumam ser o alvo principal dos testes de objeto.
47
149
48
-
:::warning[Secção Incompleta]
49
-
Esta secção encontra-se incompleta. Procuram-se contribuidores.
As sequências de métodos a testar dependem de fatores como a longevidade do objeto em questão e devem ser feitas
153
+
de acordo com o diagrama de estados desse objeto.
154
+
155
+
## Testes de Componente
156
+
157
+
Os testes de componente costumam ser os **últimos testes** a ser executados (após os testes de unidade e de objeto) e
158
+
tratam de verificar a **interação entre interfaces** de diferentes componentes e classes. O principal objetivo destes
159
+
testes é [encontrar fragilidades que resultem da interação entre unidades](color:red).
160
+
161
+
Alguns dos erros relacionados com o uso de interfaces são:
162
+
163
+
-**_Interface Misuse_**: quando uma interface é usada incorretamente (como por exemplo, chamar uma função ou método
164
+
com os parâmetros por ordem errada);
165
+
-**_Interface Misunderstanding_**: quando uma componente invoca outra assumindo comportamentos errados acerca dela;
166
+
-**_Timing Errors_**: as componentes invocadora e invocada operam a velocidades diferentes, resultando em operações
167
+
fora de ordem ou informação desatualizada.
168
+
169
+
Podemos testar as componentes todas ao mesmo tempo (_Big Bang Integration_) ou incrementalmente (_Bottom-up_ ou _Top-down
170
+
integration_), sendo que a escolha depende de fatores como a dependência entre unidades e a dificuldade de encontrar falhas
171
+
no sistema.
172
+
173
+
-[**_Big Bang Integration_**](color:orange): testa todas as componentes e todas as interações ao mesmo tempo.
174
+
175
+

176
+
177
+
-[**_Bottom-up Integration_**](color:purple): testa primeiro as componentes de mais baixo nível e vai acrescentando
178
+
incrementalmente módulos de mais alto nível.
179
+
180
+

181
+
182
+
-[**_Top-down Integration_**](color:green): testa primeiro as componentes de mais alto nível (recorrendo a _test doubles_ para
183
+
simular o comportamento de componentes mais baixas) e vai acrescentando incrementalmente módulos de mais baixo nível.
184
+
185
+

186
+
187
+
## Pirâmide de Teste
188
+
189
+
A pirâmide de teste (**_Test Pyramid_**) é um indicador de quantos testes de cada tipo devem ser criados para avaliar corretamente
190
+
um sistema. Há vários modelos de pirâmides de teste, sendo que as versões faladas em aula são a de Mike Cohn (descrita no livro
191
+
_Succeeding with Agile: Software Development Using Scrum_ ou no post [_The Practical Test Pyramid_](https://martinfowler.com/articles/practical-test-pyramid.html))
192
+
e a da Google (descrita no livro _Software Engineering at Google_).
193
+
194
+

0 commit comments