Upload
internet
View
110
Download
0
Embed Size (px)
Citation preview
Verificação e Validação
Profa. M.Sc. Yáskara Menescal
UNIVERSIDADE FEDERAL RURAL DO SEMI-ÁRIDO – UFERSADEPERTAMENTO DE CIÊNCIAS EXATAS E NATURAIS - DCEN
Verificação e Validação(V & V) É o nome dado aos processos de
verificação e análise que asseguram que o software cumpra com as suas especificações e atenda às necessidades dos clientes que estão pagando por ele.
É um processo do ciclo de vida. Inclui:• Revisões dos requisitos• Revisões de projeto• Inspeções de código• Testes do produto
Verificação e Validação Não é a mesma coisa:
– Validação: estamos construindo o produto certo?• Supõe falhas na especificação!!!
– Verificação: estamos construindo certo o produto?• Admite que a especificação esteja correta e supõe falhas no
desenvolvimento!
A validação deve ocorrer com antecedência, o que nem sempre é possível.
É provável que a validação dos requisitos não descubra todos os defeitos ou as deficiências.
V&V Existem duas técnicas:
• Inspeção de Software
• Testes de Software
Inspeções de software • analisam e verificam as representações do sistema, tais
como:– Documento de requisitos
– Diagramas de projeto
– Código-fonte do programa
• São aplicadas em todos os estágios do processo.
• Podem ser complementadas por alguma análise automática de texto dos documentos do sistema.
V&V Testes de software. Envolve:
Executar uma implementação do software com os dados de teste.
Examinar as saídas do teste e seu comportamento operacional.
Enquanto as inspeções são empregadas em todos os estágios do processo de software, os testes são utilizados somente quando um protótipo ou um programa estiver disponível.
Inspeções de
software
EspecificaçãoDe requisitos
Projeto deAlto nível
Especificaçãoformal
Projetodetalhado
Programa
ProtótipoTestes
doprograma
Tipos de Testes Testes de defeitos
– Encontram inconsistências entre o programa e a sua especificação.
– São devidos a defeitos do programa.
Testes estatísticos– Testam o desempenho e a confiabilidade do programa.
• O desempenho é medido pelo tempo que leva para executar o teste.
• A confiabilidade é medida pela contagens do número de falhas observadas.
Nível de confiança O objetivo da V&V é estabelecer a confiança de
que o sistema é “adequado a seu propósito”. O nível de confiança depende:
– Da função do software o quanto o software é importante para a organização.
– Das expectativas do usuário a tolerância do usuário às falhas hoje é menor do que a 20 anos atrás.
– Ambiente de mercado deve levar em conta os programas dos concorrentes, o preço e os prazos de entrega.
V&V x Depuração A V&V são um processo que estabelece a
existência de defeitos. A depuração é um processo que localiza e
corrige estes defeitos. Localizar defeitos em um programa nem
sempre é um processo simples. O defeito pode estar longe do ponto em que
o programa falhou!
Localizar um defeito Rastreamento manual. Programas de testes adicionais. Ferramentas de depuração (watch). Testes de regressão checam se as
mudanças feitas em um programa não introduziram novos erros no programa. Isto pode se tornar dispendioso!
Modelo de Desenvolvimento com Testes
Especificaçãode requisitos
Especificaçãode sistema
Projetode sistema
Projetodetalhado
Plano de testede aceitação
Plano de testede integração
de sistema
Plano de testede integraçãode subsistema
Teste deUnidade e de módulo
Operação Teste deaceitação
Teste de inte-gração desistema
Teste de inte-gração de
subsistema
Plano de teste de software Processo de teste
– Descrição das fases do processo de teste. Rastreamento dos requisitos
– Todos os requisitos devem ser individualmente testados. Itens a serem testados
– Especificar quais produtos do processo de software que devem ser testados.
Cronograma– Deve estar vinculado ao cronograma do desenvolvimento.
Registros de testes– Como os testes devem ser registrados?
Requisitos de hardware e software. Restrições.
Quanto à eficácia... Em 1987, Basili e Selby provaram empiricamente a
eficácia das inspeções e dos testes. Constataram que a revisão estática de código era mais
eficaz e menos dispendiosa do que os testes dinâmicos de defeitos!
Em 1992, Gilb e Graham constataram que isto é verdadeiro.
Fagan relata que mais de 60% dos erros podem ser detectados por inspeções informais do programa.
Porém, segundo Mills, através de uma inspeção formal (cleanroom), pode-se detectar mais de 90% dos erros!!!
A inspeção não descarta os testes. A inspeção deve preceder os testes.
Continuação... É muito complicado inspecionar um sistema
inteiro, composto por vários subsistemas. Os testes são a única técnica viável no nível
de sistema. Os testes, além de localizar erros, também
são necessários para determinar a confiabilidade, o desempenho e para validar a interface com o usuário.
Continuação... Engenheiros de software experientes
relutam em aceitar inspeções. Acham que os testes são suficientes. As inspeções implicam em custos
adicionais iniciais.
Inspeção de programa Desenvolvida por Fagan (IBM) uma equipe com
membros de diferentes graus de experiência deve revisar todo o código, linha por linha.
A equipe de inspeção deve ter em mãos uma especificação detalhada.
Todos os membros devem estar familiarizados com os padrões adotados na empresa.
O código a ser inspecionado deve estar completo. A inspeção resulta num documento com a lista dos erros. A equipe de revisão não deve sugerir como os erros
encontrados deverão ser corrigidos.
A Equipe de Inspeção Autor – desenvolvedor do artefato que será
inspecionado Inspetor – examina o produto na tentativa de
encontrar defeitos Leitor – apresenta o artefato aos demais
participantes Escritor – registra as informações sobre cada
defeito encontrado Moderador – possui o papel mais crítico de todo o
processo, liderando toda a equipe
O Processo de Inspeção
O Processo de Inspeção Planejamento
– O moderador é responsável por:• Selecionar a equipe de inspeção• Checar se o produto está pronto para inspeção• Organizar a reunião• Delegar as atividades de cada membro• Garantir a completude dos materiais a serem
inspecionados
– O autor e o moderador decidem quantas reuniões de inspeção serão requeridas
O Processo de Inspeção Visão Geral
– O autor apresenta as principais características do produto a ser inspecionado
– É uma etapa opcional e depende da necessidade identificada pelo moderador
O Processo de Inspeção Preparação
– Os inspetores analisam o produto de trabalho em busca de não-conformidades
– Fazem as anotações necessárias– O moderador analisa os logs antes da reunião
para determinar se a equipe está preparada para suas tarefas
O Processo de Inspeção Reunião
– O leitor realiza a leitura e interpretação do produto
– O autor tira quaisquer dúvidas que surgirem– A equipe de inspetores identifica os possíveis
defeitos– A reunião não deve passar de duas horas– Não devem ser discutidas formas de corrigir os
defeitos
O Processo de Inspeção Re-Trabalho
– O autor corrige os defeitos identificados na reunião
• Defeitos considerados mais relevantes devem ser corrigidos primeiro
O Processo de Inspeção Acompanhamento
– O moderador:• Analisa o material corrigido pelos autores
• Verifica se os defeitos foram corrigidos com sucesso
• Decide se uma nova inspeção é necessária
Testes e Inspeção No teste
– Você começa com um problema– Em seguida tem que encontrar o bug– Depois, deve imaginar a correção– Por fim, implementa e testa a correção
Nas Inspeções– Você vê o defeito– Então imagina a correção– Finalmente, implementa e revisa a correção
Testes e Inspeção Nos Testes
– Se o programa produziu um resultado não usual, você precisa
• Detectar que aquilo não foi usual
• Descobrir o que o sistema estava fazendo
• Encontrar em que ponto estava no programa
• Descobrir que defeito poderia causar este comportamento estranho
Continuação... Durante uma inspeção uma checklist pode ser útil. Uma checklist contem um roteiro de possíveis erros:
– Defeitos nos dados:• Todas as variáveis foram inicializadas?• As constantes foram nomeadas?• Tamanho máximo de um vetor?• Pode haver overflow de buffer?
– Defeitos de controle• As condições estão corretas?• Todos os loops estão certos de terminar?• Os parênteses estão corretos nas condições compostas?• Num case todas as alternativas estão declaradas?
Continuação...(Checklist)
– Defeitos de Entrada/saída• Todas as variáveis de entrada são utilizadas?
• Todas as variáveis de saída têm um valor designado antes de saírem?
• Entradas inesperadas podem corromper os dados?
– Defeitos de interface• Todas as chamadas de funções e métodos têm o número
correto de parâmetros?
• Os tipos de parâmetros combinam?
• Os parâmetros estão na ordem certa?
• Se componentes acessam memória compartilhada, eles têm a mesma estrutura de memória compartilhada?
Continuação...(Checklist)
– Defeitos de gerenciamento de armazenamento• Se uma estrutura linkada é modificada, todos os
links foram corretamente redesignados?• Se o armazenamento dinâmico é utilizado, o espaço
foi alocado corretamente?• O espaço é explicitamente liberado, depois que não
é mais necessário?
– Defeitos de gerenciamento de exceções• Todas as possíveis condições de erro foram levadas
em conta?
Análise automatizada Utiliza um programa que percorre o código fonte e
detecta possíveis anomalias.(Não é necessário executar o código!)
Pode analisar:– Fluxo de controle
– Utilização dos dados
– As interfaces (se o compilador não realizar esta tarefa)
– Fluxo de informações (entrada saída)
– Caminho (todos os caminhos possíveis no programa)
Análise automatizada O Linux tem o Lint para a linguagem C. A análise com ferramentas não substitui as
inspeções. Existem tipos de erros que a ferramenta não detecta.
As linguagens modernas são menos sujeitas a erro:– Todas as variáveis precisam ser inicializadas– Não existe goto.
Testes Apresentam duas fases:
– Testes de componentes cada componente é testado individualmente.
– Testes de integração é testada a interação entre os componentes e a funcionalidade e o desempenho do sistema como um todo.
– Inevitavelmente são descobertos defeitos em componentes, durante os testes de integração.
Sistemas orientados a objetos Sob perspectiva de testes, os sistemas baseados em objetos
diferem dos sistemas baseados em funções. Em sistemas baseados em funções existe distinção nítida
entre programas (funções) e módulos. Na orientação a objeto não há esta distinção: os objetos
podem ser simples entidades ou entidades complexas. Não há uma hierarquia de objetos bem definida. As estratégias de integração top-down e bottom-up são
inadequadas. O limite entre teste de componente e teste de integração
não é exato.
Detecção de defeitos O teste de validação se destina a demonstrar que o sistema
cumpre com suas especificações. O teste de detecção de defeitos tem por objetivo fazer com
que o sistema opere incorretamente, expondo um defeito existente.
Casos de teste são especificações das entradas para o teste e da saída esperada.
Casos de teste não podem ser gerados automatica-mente, porque não tem como prever a saída.
Já os dados de teste podem ser gerados automaticamente.
Testes É impraticável fazer todos os testes. Devem ser projetados casos de testes. A empresa pode ter política de casos de teste. Por exemplo:
– Testar todas as funções acessadas por meio de menus.
– Testar todas as combinações de funções acessadas pelo mesmo menu.
– Todas a funções devem ser testadas com dados corretos e incorretos.
Processo de teste
Projetar casos de testes
Preparar casos de testes
Executar programa com os dados de teste
Comparar resultados com os casos de teste
Casos de testes
Dados de testes
Resultados de testes
Relatórios de testes
Teste de caixas preta(Testes funcionais) Cada componente é considerado uma caixa
preta. O testador está preocupado somente com a
funcionalidade do componente. Também pode ser utilizado na orientação a
objeto. Principal dificuldade: selecionar os dados
de entrada que tenham grande probabilidade de detectar uma anomalia.
Dados de entrada Se dividem em classes:
– Números positivos– Números negativos– Strings sem “brancos” ou com “brancos”– Datas, etc
Os programas normalmente se comportam de maneira comparável para todos os membros de uma classe.
Essas classes são chamadas de “partições de equivalência”.
Casos de teste O testador deve identificador todas as partições de
equivalência. Os casos de teste são escolhidos a partir de cada
uma destas partições. Valores que não pertencem a nenhuma partição ou
que se encontram nos extremos de uma partição, são valores atípicos.
Os erros normalmente ocorrem, quando se processam valores atípicos.
Outras diretrizes de testes Utilizar seqüências com somente um único
valor. Utilizar seqüências diferentes, de tamanhos
diferentes, em diferentes testes. Utilizar o primeiro, o médio e o último
elemento de uma seqüência.
Teste de estrutura Também chamados de testes de “caixa
branca” ou “caixa de vidro” ou “caixa clara”
Neste caso, os dados de teste são derivados do código.
Dados de teste
Saídas do testeCódigo de componente
derivaTesta
Testes de Caminho É um caso de teste de estrutura, onde cada
caminho de execução independente é testado.
Nas declarações condicionais são testados os casos verdadeiros e os falsos.
Quando os módulos são integrados, torna-se inviável o teste de estrutura então usa-se o teste de caminho.
Teste de caminho É impossível testar todos os caminhos, pois
a combinação de caminhos tende a infinito! O ponto de partido é um grafo de fluxo de
programa. Cada caminho de programa deve ser testado
pelo menos uma vez.
1
2
3
4
5 6
7
8
9
Se vetor[medio]=chave
nãosim
Enquanto inicio<=fimInicio>fim
Se vetor[medio]<chave
sim não
Grafo de fluxo
para uma rotina
de pesquisa binária
Teste de caminho A rotina de pesquisa binária é simples e o
projeto do caso de teste é direto. Porém, se o programa tem uma estrutura
complexa de ramificações, pode ser difícil prever qualquer caso de teste.
Neste caso, pode ser utilizado um analisador de programa dinâmico.
Este conta o número de vezes que cada declaração do programa foi executada.
Testes de integração Quando todos os componentes já foram
testados, deve ser testada a integração destes.
Estes testes devem começar a partir da especificação do sistema.
Tão logo alguns componentes estejam concluídos, deve ser testada a integração dos mesmos.
Testes de integração Maior problema:
– como localizar um erro que foi detectado nesta etapa?
– Em qual componente ele está?
Solução: testes incrementais!
A
B
T1
T2
T3
A
B
C
T1
T2
T3
T4
T1
T2
T3
T4
T5
T6
A
B
C
D
Testes de integração incremental
Na prática, pode ser necessário integrar diversos componentes simultaneamente!
O erro detectado pode não estar no componente incrementado!
Testes top-down e bottom-up São abordagens diferentes da integração do
sistema. Top-down os componentes de alto nível são
integrados e testados antes que seus projetos e implementação tenham sido completados.
Bottom-up os componentes de nível inferior são integrados e testados antes que os componentes de nível superior tenham sido desenvolvidos.
Testes de integração top-down
Nível 1
Nível 2 Nível 2 Nível 2 Nível 2
Nível 1Seqüência de testes
Stubs nível 2
Stubs nível 3
Testes de integração bottom-up
Nível N Nível N Nível N Nível N Nível N
Nível N-1 Nível N-1 Nível N-1
Seq
üência de testes
Driver de teste
Driver de teste
Driver de teste
Driver de teste
Driver de teste
Driver de teste
Driver de teste
Driver de teste
Top-Down X Bottom-Up Validação da arquitetura:
– Top-down: tende a encontrar erros na arquitetura no inicio do desenvolvimento.
– Bottom-up: o projeto de alto nível só é validado num estágio avançado do processo.
Demonstração do sistema:– Top-down: um sistema de trabalho limitado está disponível na fase inicial.– Bottom-up: somente se reutilizar componentes.
Implementação de teste:– Top-down : os testes são difíceis de implementar, pois há necessidade de
simular os stubs.– Bottom-up : é necessário escrever drivers de teste.
Observação de teste:– Ambos têm problemas de observação do teste. Os componentes de alto
nível tendem a não ter saídas e os de baixo nível necessitam de um ambiente artificial (drivers) para que o teste possa ser observado.
Testes de Interface Ocorrem quando módulos ou subsistemas
são integrados para formar sistema maiores. É particularmente importante na orientação
a objeto. Os erros de interface não são detectados,
testando-se os objetos individuais.
Tipos de Interfaces De parâmetros
– Quando dados ou referências de funções são passados de um componente para outro.
De memória compartilhada– Quando um bloco de memória é compartilhado entre subsistemas.
De procedimento– Quando um subsistema encapsula um conjunto de procedimento
que podem ser chamados por outros subsistemas. De passagem de mensagem
– Quando um subsistema pede um serviço de outro subsistema, passando-lhe uma mensagem.
Tipos de erros de interface Mau uso
– Tipos errados, incompletos, invertidos, etc. Mau entendimento
– Exemplo: uma chamada a uma busca binária em um vetor não ordenado. Ou estouro de fila, etc.
Erros de timing– Ocorrem em sistema de tempo real com memória
compartilhada, quando o produtor de dados e o consumidor de dados trabalham com velocidades diferentes.
– É possível que o consumidor de dados acesse dados desatualizados!
Diretrizes para testes de interface Testar os valores dos parâmetros em seus extremos. Testar parâmetros com ponteiros nulos. Projetar testes que devam provocar a falha do componente. Em passagem de mensagem, projete testes que geram
muito mais mensagens do que é provável que ocorra na prática.
Projetar testes que variam a ordem de uso da memória compartilhada, quando existe mais de um produtor e/ou consumidor.
Quando a linguagem é bem tipificada (Pascal, Java) então o compilador se encarrega de encontrar a maioria dos erros de interface.
Testes de stress São testes em que a carga do sistema é aumentada
constantemente, até que o desempenho do sistema se torne inaceitável.
Funções:– Testar a falha do sistema. A falha corrompe os dados ou provoca a
perda de algum serviço?– Causar stress no sistema e assim acarretar a detecção de defeitos
que normalmente não se manifestariam. Os testes de stress são relevantes em sistemas distribuídos,
com base em rede de computadores. A rede se torna inundada de dados de coordenação, que os
diferentes processos devem trocar e, assim, os processos cada vez mais lentos.
Objetos Os objetos:
– São maiores do que funções isoladas.– Não são integrados em subsistemas. – São mal acoplados.– Não há um nível superior óbvio.– Na reutilização de objetos, o testador pode não
ter acesso ao código fonte.
Testes orientados a objetos Testar as operações (ou métodos)
individuais de cada objeto. Pode-se utilizar a técnica da caixa preta.
Testar classes de objetos. Idem. Testar grupos de objetos. Testar o sistema orientado a objeto.
Testes de classes de objeto Testar isoladamente todas as operações
associadas ao objeto. Estabelecer e testar os valores de todos os
atributos associados com o objeto. Testar todos os estados possíveis em
eventos que provoquem a mudança de estado no objeto.
Testar todas as subclasses com a operações herdadas da superclasse.
Integração de objetos Testes de cluster (bottom-up e top-down não são
indicados). Testes de use-case (ou cenários) Testes de threads. Pode-se provocar um evento e verificar
como o processamento de eventos faz o seu caminho. Testes de interação identificar os caminhos de MM
(Message Methods) e identificar o ASF (Atomic System Function).
Um ASF é um evento de entrada, seguido de uma seqüência de rotas de MM e que termina com um evento de saída.
Testes baseados em Use-case
Controlador de comunicações Estação meteorológica Dados meteorológicos
Requisitar (relatório)
Ok()
Responder (relatório)
Ok()
Relatar()
Enviar (relatório)
Resumir()
Use-Case O diagrama de seqüência explicita um Use-
case e permite identificar caminhos de operações a serem testados.
Permite identificar entradas e saídas. É claro que devemos também levar em
conta as exceções que foram suprimidas no diagrama anterior.
Ferramentas de teste Gerenciador de testes
• gerencia os testes e acompanha os dados de teste e os resultados esperados. Gerador de dados
• Gera os dados de teste a partir de padrões ou a partir da seleção em um banco de dados de teste.
Oráculo• Gera previsões dos resultados esperados.
Comparador de arquivos• Compara e relata as diferenças entre resultados de 2 ou mais testes.
Gerador de relatórios• Gera um relatório dos resultados de teste.
Analisador dinâmico• Adiciona código a um programa para contar o número de execuções de cada
declaração do programa. Simulador
• De máquina, de interface e de entrada e saída (timing)