Este documento discute estratégias de teste de software, com foco no teste ágil. Apresenta os principais tipos de teste como unidade, integração, validação e sistema. Destaca que no desenvolvimento ágil, os testes ocorrem em todas as fases e são responsabilidade de toda a equipe, com ênfase em automação e nos testes de unidade e integração. O método Test-Driven Development (TDD) é descrito como uma técnica que automatiza a especificação e execução de testes antes da implementação do código.
1. Verificação, Validação e Teste de Software Ágil
Gilberto Gampert1
1
Instituto de Ciências Exatas e Geociências – Universidade de Passo Fundo (UPF)
Campus Universitário – Bairro São José – Passo Fundo – RS – Brasil
gampert@upf.br
Abstract. This paper presents a brief introduction to the topic Verification,
Validation and Agile Software Testing and brings a case study where can be
seen that the use of software testing techniques, such as TDD, can dramatically
decrease the occurrence of software errors.
Resumo. Este trabalho apresenta uma breve introdução ao tema Verificação,
Validação e Teste de Software Ágil e traz um estudo de caso onde pode-se
verificar que a utilização de técnicas de teste de software, tais como o TDD,
podem diminuir drasticamente a ocorrência de erros no software.
1. Introdução
Conforme [Pressman 2011], a estratégia de teste de software descreve: os passos que
devem ser executados como parte do teste, quando estes passos devem ser planejados e
executados e quanto trabalho, tempo e recursos serão necessários. Desta forma, uma
estratégia de teste é composta por: planejamento dos testes, casos de testes, coleta e
avaliação dos dados obtidos.
A estratégia é normalmente desenvolvida pelos especialistas em testes. Ela é
importante pelo fato de que os testes muitas vezes requerem mais trabalho do que as
outras etapas da engenharia de software. Se for feito sem atenção, perde-se tempo e erros
passam desapercebidos.
Os testes iniciam por um pequeno componente ou grupo de componentes, que são
testados para verificar erros nos dados e na lógica. Após esta etapa, os componentes são
integrados e neste ponto testes são executados para descobrir erros ao atender os
requisitos do cliente. Conforme os erros são descobertos, devem ser diagnosticados e
corrigidos (depuração).
Um modelo de teste de software deve ter as seguintes características básicas:
Proceder revisões técnicas eficazes;
Iniciar no nível de componente e evoluir para a integração do sistema;
Ter uma técnica de teste definida. Diferentes técnicas de teste são apropriadas a
diferentes abordagens da engenharia de software;
O teste é executado pelo desenvolvedor e (em grandes projetos) por uma equipe
de testes;
A depuração é uma atividade distinta do teste, porém deve estar associada com a
estratégia de testes.
2. 2. Verificação e Validação
O teste de software faz parte de um tópico mais amplo, conhecido como verificação e
validação (V & V). A verificação diz respeito ao conjunto de tarefas que asseguram que
o software implementa uma funcionalidade específica. Já a validação por sua vez, diz
respeito ao conjunto de tarefas que asseguram que o software foi criado e atende aos
requisitos do cliente. Uma outra visão é abordada por [Pressman 2011]:
Verificação: “ Estamos criando o produto corretamente? ”
Validação: “ Estamos criando o produto certo? ”
A verificação e a validação abrangem diversas atividades de SQA (software
quality assurance, garantia da qualidade de software):
Revisões técnicas;
Auditorias de qualidade e configuração;
Monitoramento de desempenho;
Simulação;
Estudo de viabilidade;
Revisão de documentação;
Revisão de base de dados;
Análise de algoritmo;
Teste de desenvolvimento;
Teste de usabilidade;
Teste de qualificação;
Teste de aceitação;
Teste de instalação.
Ou seja, embora o teste tenha um papel muito importante em V&V, muitas outras
atividades são necessárias. Isto significa que o teste sozinho não garante a existência de
qualidade, e sim atesta a sua ausência.
3. Estratégia de Teste de Software
O desenvolvedor é responsável pelo teste dos componentes do programa, certificando-se
que cada um executa a função ou comportamento para qual foi projetado. Em alguns
casos, ele também faz o teste de integração, o que implica na construção e teste do
software completo. Somente após esta etapa é que a equipe de testes faz a sua parte.
A equipe de teste, ou ITG (independent test group, grupo independente de teste),
tem por função resolver o problema de deixar o criador testar aquilo que ele mesmo criou.
O desenvolvedor e o ITG trabalham juntos durante todo o projeto para garantir que testes
completos sejam realizados. O ITG se envolve durante a análise e o projeto e continua
envolvido durante o projeto inteiro.
3. Uma estratégia de teste de software pode ser vista na Figura 1, onde o teste de
unidade inicia no centro da espiral e trata de cada componente do software conforme for
implementado. O teste segue o sentido do exterior da espiral, abordando o projeto e a
arquitetura do software (teste de integração). Seguindo no mesmo sentido, há o teste de
validação, onde os requisitos são validados em relação ao software criado. Por fim, o teste
do sistema, onde o software é testado como um todo.
Figura 1. Estratégia de teste
3.1. Teste de unidade
O teste de unidade coloca os esforços na menor unidade do software, o componente ou
módulo de software. Utilizando a especificação do componente como guia, este teste
enfoca a lógica interna de processamento e as estruturas de dados, buscando descobrir
erros dentro dos limites do componente. Ele pode ser executado em paralelo para diversos
tipos de componentes. O teste de unidade é ilustrado na Figura 2.
Figura 2. Teste de unidade
Os seguintes aspectos são testados:
A interface do módulo, para assegurar a comunicação com os demais
componentes;
A estrutura de dados locais, para garantir a integridade dos dados;
4. Os caminhos independentes da estrutura de controle, para garantir que todas as
instruções tenham sido executadas pelo menos uma vez;
As condições de limite, para garantir que o componente opere adequadamente nas
fronteiras de processamento;
E por fim, são testados os caminhos de manipulação de erro.
Casos de testes deverão ser projetados para descobrir erros de computação,
comparações ou fluxo de controle incorretos.
3.2. Teste de integração
O teste de integração é uma técnica utilizada para conduzir testes para descobrir erros
associados com as interfaces. Normalmente é aplicada uma estratégia de integração
incremental, pois os erros são mais fáceis de isolar e corrigir. Uma estratégia oposta,
integrando todos os módulos ao mesmo tempo, poderá levar ao caos, pois muitos erros
são encontrados simultaneamente e o seu isolamento é dificultado.
Existem várias abordagens de teste de integração. Nos parágrafos a seguir
abordaremos as principais.
Integração descendente: ou top-down, os módulos são integrados de cima para baixo na
hierarquia de controle, começando com o programa principal e incorporando os módulos
subordinados a seguir. Na Figura 3 podemos ver os dois tipos de integração existentes:
integração primeiro-em-profundidade e primeiro-em-largura. No caso da integração
primeiro-em-profundidade, os componentes M1, M2 e M5 seriam integrados primeiro,
depois M8 e por fim M6. E depois continuaria para os outros ramos. No caso da integração
primeiro-em-largura, primeiro M1, depois M2, M3 e M4, e assim sucessivamente.
Figura 3. Integração descendente
O módulo principal se torna o controlador e os módulos diretamente subordinados
são substituídos por pseudocontroladores. Um a um estes pseudocontroladores vão sendo
substituídos pelos componentes reais, os testes são executados neste componente e assim
o processo se repete até atingir todos os componentes.
5. Integração ascendente: ou bottom-up, começa os testes com módulos atômicos, ou seja,
nos níveis mais baixos na estrutura do programa. Neste caso, somente um
pseudocontrolador é necessário.
Os componentes são agrupados em agregados (Figura 4) que executam uma
subfunção específica do software, então um pseudocontrolador coordena as entradas e
saídas do caso de teste. O agregado é testado, e então o pseudocontrolador é removido,
os agregados são combinados e move-se para cima na estrutura do programa.
Figura 4. Integração ascendente
Teste de regressão: Sempre que um novo módulo é adicionado no processo de integração
o software muda. Novos fluxos de dados são estabelecidos, novas entradas e saídas e nova
lógica de controle pode ser adicionada.
O teste de regressão nada mais é do que executar novamente um conjunto de testes
que foram executados anteriormente para garantir que as alterações não tenham inserido
efeitos indesejados ou erros adicionais. Pode ser executado através de ferramentas que
automatizam a captura/execução e permitem comparação subsequente.
3.3. Teste de validação
O teste de validação tem seu início quando o teste de integração chega ao fim, e os
componentes já estão devidamente testados. Neste ponto o software está completamente
integrado e os possíveis erros de interface corrigidos. Este teste concentra-se em ações e
saídas visíveis ao usuário.
Existem várias definições de validação, pode-se dizer que a validação teve sucesso
quando o software funciona de acordo com o esperado pelo cliente. Esta expectativa,
normalmente está descrita na especificação de requisitos de software.
A validação do software é obtida através de um conjunto de testes que
demonstram a conformidade com os requisitos. Um plano de teste descreve as classes de
teste e um procedimento de deste define os testes específicos necessários para garantir
que todos os requisitos funcionais sejam satisfeitos, que todos os requisitos de
desempenho sejam atendidos, que a documentação correta e outros requisitos sejam
cumpridos (compatibilidade, recuperação de erro, manutenibilidade, etc.). Outro
6. elemento importante é a revisão da configuração de software. Sua finalidade é garantir
que seus elementos tenham sido catalogados e tenham os detalhes necessários para apoiar
as atividades de suporte.
É praticamente impossível prever como cada cliente realmente usará um
programa, e, se o software for desenvolvido para muitos clientes, é impraticável executar
testes formais de aceitação para cada cliente. Neste caso utiliza-se um processo de teste
chamado teste alfa e beta, com o objetivo de descobrir erros que somente o usuário final
é capaz de encontrar.
Teste alfa: é conduzido na instalação do desenvolvedor por um grupo representativo de
usuários finais. O teste acontece com os desenvolvedores acompanhando e registrando os
erros e problemas de uso. É um ambiente controlado.
Teste beta: é conduzido nas instalações dos usuários finais. Normalmente o
desenvolvedor não está presente e o ambiente não é controlado. O cliente registra os erros
e problemas encontrados e relata para o desenvolvedor.
3.4. Teste de sistema
Ao término do desenvolvimento, o software é agregado a outros elementos do sistema,
por exemplo, hardware, pessoas e informações. Desta forma, é necessária a execução de
uma série de testes de integração de sistema e validação. Estes testes não fazem parte do
processo de software.
Teste de sistema é uma série de testes cuja finalidade é exercitar todo o sistema e
verificar de este se integra adequadamente e executa as funções a ele alocadas. A seguir
veremos os tipos de teste de sistema.
Teste de recuperação: é um teste que força o sistema a falhar de várias formas e verifica
se a recuperação é executada adequadamente. A recuperação pode ser automática, e neste
caso é avaliada a capacidade de recuperação de dados, ou, requerer a interação humana,
e o tempo médio de reparo será avaliado.
Teste de segurança: verifica se os mecanismos de segurança implementados no software
irão protege-lo de acesso indevido.
Teste por esforço: verifica até onde pode-se forçar o sistema até que ele falhe, ou seja,
busca-se quebrar o programa. Ele estressa o sistema de maneira que este demande recurso
em quantidade, frequência e volume anormais.
Teste de desempenho: é projetado para testar o desempenho em tempo de execução.
Apesar de poder ser feito em todas as etapas de teste, o verdadeiro teste de desempenho
somente poderá ser avaliado depois da integração total de todos os elementos.
Normalmente uma ferramenta é utilizada para automatizar este tipo de teste e coletar os
resultados obtidos.
Teste de disponibilização: ou teste de configuração, tem por objetivo validar o software
em cada ambiente no qual ele dever operar. Examina os procedimentos de instalação e
documentação para fornecer o software aos usuários finais.
7. 4. Teste de Software Ágil
O teste de software ágil é caracterizado por ocorrer em todas as etapas do ciclo de vida
de desenvolvimento de software e ser desempenhado por todos os membros do time. Ele
ocorre em ciclos contínuos e através de mecanismos automatizados.
Todo o time é responsável pelos testes, e cada membro contribui executando testes
sob a sua perspectiva. Assim, os testes são executados de forma colaborativa e
complementar. Os desenvolvedores atuam na perspectiva do código, enquanto que os
clientes avaliam a perspectiva da funcionalidade. Há também o papel do testador, que
complementa os testes dos dois anteriores e colabora com abordagens mais
especializadas.
Em teste ágil, a automação tem grande enfoque, pois viabiliza curtos ciclos de
entrega e faz parte de um ciclo de integração contínua, fornecendo resultados de forma
contínua. A automação libera o time para executar tarefas mais criativas ao invés de
executar testes entediantes, repetitivos e manuais.
A Figura 5 mostra que o foco principal do teste ágil são os testes unitários e de
integração. O uso desta abordagem diminui o custo e a manutenção, pois os erros são
encontrados mais cedo e aumenta a velocidade de entrega, pois não há o retorno para
correção.
Figura 5. Pirâmide do teste ágil
4.1. Test-Driven Development (TDD)
Este trabalho não se destina a descrever o método TDD, pois existe suficiente material
para o aprendizado e não faz parte do escopo.
Esta técnica busca automatizar a busca por resultados especificados antes da
construção do software. Cada teste é uma especificação que mapeia um resultado
esperado para uma parte específica do software. Isso ocorre dentro de um ambiente onde
os testes já produzidos podem ser facilmente executados (automação). Na Figura 6 pode-
se verificar o funcionamento do processo de teste do TDD.
8. Figura 6. TDD
O autor [Crispin 2006], nos descreve suas experiências com TDD: "Eu posso
afirmar por experiência pessoal que TDD produz código que tem ordens de magnitude
menos erros de unidade, muito menos erros funcionais, e uma probabilidade de
atendimento das expectativas do cliente exponencialmente mais alta, quando comparado
com técnicas de programação convencionais.".
5. Estudo de Caso
Os autores do estudo de caso abordado neste artigo [Silva et. al, 2010] escolheram o
projeto OOOD (OpenOffice.org Daemon). Este projeto foi desenvolvido inicialmente
pela Nexedi, uma empresa Francesa associada ao NSI (Núcleo de Pesquisa em Sistema
de Informação). O objetivo do OOOD é extrair/inserir metadados em um documento e
converter e exportar documentos para o OpenOffice.org. Ele foi escolhido por utilizar
TDD desde o início de seu desenvolvimento. Inicialmente o time não tinha experiência
no uso do TDD, então durante o processo aconteceu o aprendizado.
Um outro projeto desenvolvido pelo NSI, a Biblioteca Digital (BD), foi
selecionado como grupo de controle e portanto não apresentou o uso do TDD. O objetivo
do BD é manter dados sobre obras literárias, gráficas e vídeos.
5.1. Metodologia
O objetivo da metodologia proposta é demonstrar estabilidade durante o processo de
desenvolvimento e a diminuição gradativa dos erros causados pelo aumento da
complexidade e mudança de requisitos. Quer-se demonstrar a diminuição dos erros e
aumento das melhorias, durante o desenvolvimento, proporcionados pelo monitoramento
contínuo obtido através de testes automatizados.
Estima-se que quanto maior a cobertura dos testes oferecidos pelo TDD, mais
seguro o desenvolvedor estará para trabalhar no incremento, melhoria e correções
necessários.
Os autores optaram por utilizar o controle de versões como recurso de
monitoramento no desenvolvimento do software, para acompanhar a taxa de mudanças
submetidas pelo time. Cada incremento, alteração ou correção, passa primeiro por este
sistema e depois é incorporado ao software. A partir das mudanças submetidas ao controle
de versões, foi feita uma verificação nas descrições para detectar palavras que sugeriam
o tipo da modificação. Buscou-se identificar três situações: novas funcionalidades,
melhoria do código e correção de erros.
9. A expectativa é de que as adições de novas funcionalidades indiquem a
estabilidade do código e as operações de melhoria do código possam indicar evolução na
qualidade do mesmo. Já as operações de correções, indicam que a execução atingiu um
caminho não coberto pelos testes, denotando instabilidade no produto.
Após recuperar as informações do controle de versões, atribuiu-se um valor
positivo (1), para as novas funcionalidades denotando estabilidade. Para as situações de
melhoria de código, atribuiu-se um valor neutro (0), indicando a estabilidade. Para as
situações de erro atribuiu-se (-2), demonstrando instabilidade. Foi escolhido o valor (-2)
para intensificar o efeito visual dos erros nos gráficos.
5.2. Resultados
Na Figura 7, pode-se observar que o desenvolvimento do projeto OOOD foi dividido em
3 fases:
Fase A: criação da arquitetura da solução, os primeiros testes ainda não haviam
encontrado erros;
Fase B: os erros começam a aparecer, o que significou aprendizado para o time.
Foram encontrados 18 erros, representando 45% do total de erros;
Fase C: houve uma certa estabilidade, com poucas declividades (erros).
Figura 7. Evolução do projeto OOOD
É fácil concluir que a dispersão dos erros encontrados na terceira etapa (22) foi
menos densa do que os erros ocorridos na segunda etapa. Atribui-se esta distância entre
os erros ao TDD, pois com o uso desta técnica e o aperfeiçoamento do time, existe a
tendência de que ocorram cada vez menos erros.
Além da quantidade de erros ter diminuído, pode-se observar que as operações de
refatoração (melhoria de código) foram constantes (Figura 8). Isto somente poderia
acontecer em um ambiente estável, onde o time se sentisse confiante.
10. Figura 8. Avaliação das atividades do projeto OOOD
No projeto BD, onde não foi usada a técnica de TDD, podemos observar um
comportamento distinto. Como podemos ver na Figura 9, este projeto esteve
constantemente sujeito a propagação de erros, tornando o desenvolvimento menos estável
e diminuindo as chances de melhoria.
Figura 9. Evolução do projeto BD
Na Figura 10 é possível verificar um número menor de melhorias e maior de erros:
Acompanhe a evolução das fases:
Fase A: início do desenvolvimento, houveram incrementos de funcionalidades,
porém com muitos erros e correções (vários declives);
Fase B: ocorreu grande evolução e esteve um pouco mais estável, mas também
ocorreu grande número de erros;
Fase C: foi caracterizada por melhorias de código e correção de erros.
11. Figura 10. Avaliação das atividades do Projeto BD
6. Considerações Finais
O objetivo deste artigo foi fazer uma introdução ao assunto Verificação, Validação e
Teste de Software Ágil e apresentar um estudo de caso, tendo em vista a importância do
software e a necessidade de melhor gerenciar a sua produção.
O estudo de caso selecionado, a partir dos projetos escolhidos pelos autores e dos
dados que foram coletados, concluiu que a aplicação do TDD e de testes automatizados
refletem positivamente na qualidade de software, permitindo identificar os erros
rapidamente e trazendo controle ao processo de desenvolvimento.
Observou-se inicialmente que houve pouca estabilidade, e depois com o
aprendizado e a evolução do uso chegou-se a um momento de maior estabilidade no
desenvolvimento.
Deixamos como contribuição a constatação de que a técnica utilizada para
identificar novas funcionalidades, melhoria de código e correção de erros precisa ser
aprimorada e ancorada em informações mais consistentes do que aquelas obtidas do
sistema de controle de versões.
Referencias
Crispin, K. (2006). Driving Software Quality: How Test-Driven Development Impacts
Software Quality. IEEE Software. IEEE. P.70-71. 2006.
Pressman, R. S. (2011). Engenharia de Software: Uma Abordagem Profissional. Mc Graw
Hill. 7ª ed. 2011.
Silva, F. L. C., Monnerat, G. M., Carvalho, R. A. (2010). “Automação na Produção de
Software”,
http://www.abepro.org.br/biblioteca/enegep2010_TN_STO_113_745_16894.pdf,
Junho.