TESTES DE SISTEMA
Engenharia de Software I
Este trabalho tem como objetivo mostrar a importância dos testes no desenvolvimento
estruturado de software, passando pelas fases desta etapa e os tipos de teste utilizados em cada
fase. Aborda também os métodos para uma correta aplicação dos testes de forma eficiente,
2 Tipos de Teste
Durante as quatro fases de teste de um projeto são aplicados testes que podem ser
classificados em duas categorias: Testes Estruturais e Testes Funcionais. Antes de entrarmos
nas fases do teste veremos como são caracterizados estes dois tipos de teste.
Os testes estruturais podem ajudar a descobrir funções ausentes no programa, erro nas
expressões aritméticas, declaração de tipos necessária, diferenças entre áreas de dados
compartilhadas, erro nas interfaces de módulos (parâmetros) e não cumprimento de padrões.
Exemplos de técnicas aplicadas no testes estruturados:
• Análise da estrutura de controle;
• Técnicas baseadas em lógica matemática;
• Inspeções;
• Testes de mesa;
• Programas verificadores de estrutura;
• Teste baseado na cobertura: é aquele em cada comando do módulo é executado ao menos
uma vez;
• Teste baseado na cobertura de desvios: testa cada decisão e segue todos os desvios da
decisão;
• Teste da cobertura dos caminhos DD: um caminho DD é a seqüência de comandos que se
inicia no resultado de uma decisão e termina na próxima decisão;
• Teste baseado na complexidade: procura orientar o esforço do teste para as partes mais
complexas do código, onde é mais provável a existência de erros. Para métrica da
complexidade utiliza-se uma das diversas técnicas existentes como a métrica de Halstead,
número ciclomático de complexidade de McCabe e a complexidade da variável de
controle de McClure.
Diferentes aspectos da funcionalidade do programa devem ser testados nesta fase e para
cada um deles existe uma metodologia para a produção de dados de teste (primeiro passo,
acima). Por isso os testes funcionais se dividem nas seguintes etapas:
1 Teste de Via Normal (ou Caminho Normal)
2 Teste de Via de Erro (ou Caminho de Exceção)
3 Teste de Estado Transiente
4 Teste de Desempenho (ou Performance)
5 Testes Especiais
Símbolo Significado
= É composto de
+ E
<min>{ }<max> Iteração (mínimo, tipo de dado, máximo)
<valor1> – <valor2> Intervalo de valores
[<valor1>|<valor2>|<valorN>] Escolha Múltipla
Dicionário Exemplo:
Cod_quarto = 1 – 1000
Status = [ “vago” | “ocupado” ]
Cod_quarto Status
1 “vago”
500 “vago”
1000 “vago”
1 “ocupado”
500 “ocupado”
1000 “ocupado”
Semelhante ao de via normal, porém entra com dados inválidos no sistema para avaliar
seus tratamentos de erros, que deve ser recusá-los, evitando a produção de saídas inválidas ou
até mesmo o travamento do sistema.
Esses dados inválidos são geralmente de dois tipos:
1 Casos que infrinjam os limites de entrada (citados nos testes de via normal) como por
exemplo, para uma entrada de valor numérico que deve ser um valor de 1 a 10, um conjunto
de dados inválidos para teste poderia ser –1,0,11,15.
2 Valores incompatíveis com o tipo de dado esperado, como por exemplo, para a
mesma entrada numérica acima o conjunto de dados poderia ser 1A, w, #?, (vazio).
Cada conjunto de dados inválidos substituirá o seu respectivo conjunto de valores
normais de cada vez, que foram usados no teste anterior (via normal). Efetua-se a combinação
(produto cartesiano) nesse novo arranjo de conjuntos obtendo-se um conjunto de entradas
inválidas, que contém um único erro (que está no item que teve seu conjunto normal
substituído pelo inválido). Somente um conjunto de dados inválidos será combinado com o de
vias normais de cada vez, produzindo um único erro por entrada. Não se deve produzir
entradas com combinações de erros ou entradas com um dado com múltiplos erros.
Seguindo o mesmo dicionário do exemplo anterior, podemos estabelecer os seguintes
conjuntos de dados inválidos:
Cod_quarto Status
0 “vago”
1001 “vago”
“M#” “vago”
0 “ocupado”
1001 “ocupado”
“M#” “ocupado”
Os testes derivados até agora seriam suficientes para testar um sistema que não tivesse
nenhuma memória, que tratasse cada entrada de modo independente do que tivesse acontecido
antes. Porém para sistemas com vários estados transientes será necessário agrupar os testes
em seqüências. A seqüência de testes pode ser organizada para forçar o sistema em cada um
dos estados possíveis e testar o seu desempenho nesse estado. Para derivar um conjunto
completo de seqüências de teste deve-se listar os estados em memória para cada fluxo de
dados de entrada e realizar uma seqüência de teste para cada estado.
3 Fases do teste
A abordagem estruturada teve grande influência na etapa de teste, assim como nas
outras fases de desenvolvimento de software. O teste tem sido formalizado como um
procedimento de quatro fases como descrito abaixo.
3.2.1 Bottom-up
O nome desta estratégia significa do fundo para cima e segue este princípio na
integração dos módulos, iniciando pelos módulos de nível mais baixo de forma ascendente até
chegar aos níveis mais alto.
3.2.2 Top-down
Na estratégia top-down (do topo para baixo) os módulos de alto nível são integrados e
testados em primeiro lugar. Desse modo o teste segue de modo descendente na estrutura
hierárquica. O teste top-down requer a criação de módulos temporários chamados stubs. O
módulo stub representa o módulo de nível logo abaixo do módulo que está sendo testado. A
medida que o teste continua e se desce na estrutura, cada stub é substituído pelo módulo real e
novos stubs para esse módulo são criados.
Os módulos stubs podem ser de diversos tipos, cada tipo pode auxiliar de modo
diferente no teste do sistema:
• Não executar nada. Não é muito útil mas fácil de implementar;
• Exibir uma mensagem indicando que foi chamado. Útil para verificação do fluxo de
controle do sistema;
• Exibir um terminal, permitindo que o responsável pelo teste passe dados e tempo de
execução para o módulo superior;
• Retornar um valor constante, um número aleatório ou um número de uma tabela de teste.
• Ser uma versão simplificada do módulo real;
• Testar ou exibir os dados com os quais foi chamado;
• Aguardar certo tempo. Esse tipo de stub é útil em sistemas de tempo real ou sistemas
operacionais nos quais é preciso assegurar-se de que o sistema funcionará corretamente
com um módulo que consumirá, por exemplo, 19 milésimos de segundo. Também pode
ser utilizado para simular o acesso a um hardware que demorou tantos milésimos de
segundo para estar pronto.
3.2.3 Middle-out
A fases anteriores de teste serviam para detectar erros afim de corrigi-los. Mas no teste
de aceitação não é mais uma etapa de correção. O teste de aceitação é a mais pura forma de
teste funcional, determinando se o projeto atingiu seu alvo ou não, pois o teste de aceitação é
o que foi exigido na especificação (requisitos do usuário) estruturada produzida pela atividade
de análise .
É o passo mais importante, pois uma vez desenvolvido é usado por todas as atividades
subseqüentes. O plano de teste deve cobrir o estabelecimento do pessoal para testar o sistema,
um esboço das normas de teste e um relatório de tempo estimado e recursos necessários a
atividade de teste.
O objetivo inicial do plano deve ser a definição de uma pessoa ou grupo de pessoas
responsável por testar o sistema. Esta pessoa (ou grupo) deve ser alguém diferente das pessoas
que desenvolveram os sistema. Na verdade quanto mais afastada do projeto a pessoa
responsável, mais objetivo e profundo será o procedimento do teste. Pode-se até mesmo
contratar uma organização externa (como uma firma de consultoria de software) para realizar
o teste. De qualquer forma, o teste deve ser feito por alguém que entenda que o processo
possui a finalidade expressa de encontrar erros e revelar falhas do sistema.
Precisam ser desenvolvidos procedimentos e padrões para a construção de casos de
teste, documentação de resultados, convenção de nomeação, armazenamento e recuperação
para grupos (ou arquivos) de dados de teste.
O teste funcional é aquele visto na parte de Tipos de Teste, que agora deve ser aplicado
de modo global no programa de modo a validá-lo, resultando na sua aprovação ou reprovação.
Conclusão
Durante a realização deste trabalho concluímos que a análise estruturada possibilita o
desenvolvimento de software de qualidade, mas a etapa de teste é a que fornece maior retorno