Capítulo 6: Automatização de Teste de Software Com Ênfase em Teste de Unidade
Capítulo 6: Automatização de Teste de Software Com Ênfase em Teste de Unidade
Capítulo 6: Automatização de Teste de Software Com Ênfase em Teste de Unidade
6
Automatização de teste de software com ênfase em
teste de unidade
Abstract
Software testing is the activity of run a software product in order to check whether
this product conforms to it’s specifications. In software testing scenarios, automation con-
tributes significantly to reducing costs during the development process. Thus, increasing
the quality of the final product, high levels of coverage, reducing test time, increased reli-
ability, reduced human effort are some of the benefits of the automated test. This chapter
aims to present and discuss the main automated software testing concepts with emphasis
on unit testing. In this scenario, concepts will be presented related to the main technical
and criteria and, in parallel, tools that support the testing activity.
Resumo
6.1. Introdução
O teste de software é um conjunto de atividades dinâmicas que consistem na execução
de um programa com algumas entradas específicas, visando a verificar se o comporta-
mento do programa é condizente com sua especificação [Bertolino, 2007, Delamaro et al.,
2007b]. De acordo com Myers et al. [2004], as atividades de teste de software configu-
ram o processo, ou série de processos, que têm a função de executar um sistema com
a intenção de revelar a presença de possíveis defeitos. Para a maioria dos sistemas em
desenvolvimento, o processo de teste é o meio mais importante pelo qual tais sistemas
são submetidos para terem sua conformidade com especificações verificadas [Ammann
and Offutt, 2008, Hunter and Strooper, 2001]. Negligenciar as atividades de teste, muitas
vezes, pode remeter à produção de software de má qualidade e prejuízos econômicos.
É senso comum entre engenheiros de software e projetistas que duas questões bá-
sicas de projeto são intimamente associadas à aplicação do teste de software: (1) custo;
e (2) tempo. Em relação ao custo, pode-se afirmar que o emprego do teste traz a ne-
cessidade de contratação de equipes especializadas (testadores e projetistas de teste) e
aquisição de licenças de ferramentas específicas, elevando significativamente custos de
desenvolvimento, dependendo da complexidade do sistema em desenvolvimento [Myers
et al., 2004]. Tal acréscimo do tempo de projeto é consequência do não uso de técnicas
e critérios de testes adequados, da reexecução dos dados de teste após cada correção de
inconsistências detectadas e, principalmente, a falta de automatização [Bertolino, 2007].
Nesse cenário, o emprego de testes automatizados contribue significativamente
para a redução de custos e tempo de projeto durante o processo de desenvolvimento
[Myers et al., 2004]. Segundo Rafi et al. [2012], aumento da qualidade do produto final,
alto índice de cobertura, redução do tempo de teste, aumento da confiança, diminuição
de esforços humanos e redução de custos são alguns dos benefícios do teste automati-
zado relatados na literatura. Por isso, e pela aceitação entre pesquisadores e engenheiros
de software, da ideia de que qualidade é um fator essencial no desenvolvimento de soft-
ware, muito se tem investido em pesquisas na área de teste de software [Delamaro et al.,
2007b]. Pesquisadores procuram definir técnicas, critérios e ferramentas que possibilitem
a aplicação de tais atividades de maneira sistemática, com alta qualidade e custo reduzido.
Portanto, julga-se necessário difundir princípios e conceitos relacionados à apli-
cação de técnicas e critérios de teste a fim de possibilitar o desenvolvimento de softwares
de qualidade. Nessa seção foram apresentados o contexto, motivação para o desenvolvi-
mento deste capítulo. As demais Seções abordam técnicas e critérios de software, além
de ferramentas para o seu suporte e aplicação. Assim, o restante deste capítulo está orga-
nizado da seguinte forma:
• Teste de unidade: tem como objetivo testar as menores unidades que compõem
o sistema (métodos, funções, procedimentos, classes, etc.). Espera-se encontrar
com maior facilidade defeitos de programação, algoritmos incorretos ou mal im-
plementados, estruturas de dados incorretas, limitando-se a lógica interna dentro
dos limites da unidade;
• Teste de integração: o foco principal é verificar as estruturas de comunicação
entre as unidades que compõem o sistema. As técnicas de projeto de casos de teste
que exploram entradas e saídas são as mais utilizadas durante a fase de integração
[Pressman, 2010]; e
• Teste de sistema: o objetivo é verificar se os requisitos satisfazem a especificação
e se as funcionalidades do sistema foram implementadas corretamente, isto é, o
sistema é testado como um todo procurando simular um ambiente de execução real.
Classe Descrição
Assert Um conjunto de métodos contendo assertivas.
TestCase Define um conjunto de acessórios para execução dos casos de teste.
TestResult Usados para coletar informações sobre a execução dos casos de teste.
TestSuite Rotinas para executar um conjunto de casos de teste.
Tabela 6.1. JUnit core.
Com base na Figura 6.2, a classe Assert provê um conjunto de métodos contendo
assertivas úteis para escrever casos de teste. Somente assertivas que falharem são grava-
das. A classe TestCase provê acessórios para a execução de múltiplos casos de teste. Por
outro lado, a classe TestResult coleta informações sobre a execução de um dado caso de
teste. O framework faz distinção entre falhas e erros. Uma falha é antecipada e checada
por meio de assertivas, enquanto erros são problemas que não são antecipados, como por
exemplo o lançamento de exceções (Exceptions).
Além disso, a Figura 6.2 apresenta a classe TestSuite que oferece apoio à execução
de conjuntos de casos de teste. Por fim, a classe Annotations no framework JUnit são
meta-tags que possibilitam identificar e aplicar rotinas para métodos e classes. Essas
Annotations oferecem informações sobre os casos de teste, como métodos que necessitam
ser executados antes da execução do caso de teste, ou após a execução, métodos que deve
ser ignorados, entre diversas outras funções.
6.3.2. Teste Estrutural
Na técnica estrutural os critérios e requisitos de teste são derivados exclusivamente a par-
tir das características do código-fonte do software em teste, permitindo que haja uma
verificação mais profunda do seu comportamento. Os casos de teste são essencialmente
derivados a partir dos detalhes da estrutura interna do código-fonte do programa. Esse
tipo de teste possibilita que uma maior atenção seja dada aos pontos mais importantes do
código [Koscianski and Soares, 2007]. A partir do código-fonte é definido um conjunto
de elementos do software que devem ser executados para que se atinja a cobertura mínima
para um determinado critério. A maioria dos critérios desta técnica utiliza uma represen-
tação do programa conhecida como grafo de fluxo de controle (GFC) [Maldonado, 1991].
O GFC é elaborado de acordo com um número que identifica cada vértice do grafo
e o identificador de vértice é apresentado à frente de cada comando. No GFC, cada vértice
representa uma execução indivisível do código que termina em uma instrução simples ou
condicional [Barbosa et al., 2007, Myers et al., 2004].
A técnica estrutural é aplicada a pequenas partes do código, como sub-rotinas, ou
operações relacionadas a um objeto. Assim, o testador pode analisar o código antes de
iniciar os testes e buscar dados que possivelmente possam ser tratados de forma inespe-
rada, além de poder garantir que o programa foi liberado tendo seus comandos executados
pelo menos uma vez por pelo menos um caso de teste.
Os critérios estruturais aplicados em programas sequenciais são, em geral, classi-
ficados em:
EclEmma é uma ferramenta para dar suporte à cobertura de código em projetos desenvol-
vidos na IDE Eclipse, está disponível sob a licença Eclipse Public License. O plugin traz
consigo a possibilidade de disponibilizar estatísticas de cobertura de código diretamente
dentro do Eclipse6 .
Consiste em um plugin da ferramenta Emma7 para a IDE Eclipse e pode ser ins-
talado pelo menu Help->Install New Software, na versão tradicional do Eclipse, ou pelo
Eclipse Market Place.
O plugin EclEmma pode ser executado de algumas formas distintas:
6 http://www.eclemma.org/
7 http://emma.sourceforge.net/
Figura 6.5. Resultado da execução dos casos de teste para verificação da cobertura.
• Contagem de Métodos;
• Contagem de Tipos; e
• Contagem de Complexidade.
Figura 6.8. Programa original P e Mutante gerado com uso do operador ORRN.
O processo se encerra quando todos os mutantes que foram gerados são mortos
pelos casos de teste, ou há a identificação de mutantes que não podem ser mortos, no caso
da existência de mutantes equivalentes.
Um fator importante no teste de mutação é o escore de mutação, que fornece uma
medida de confiança do nível de adequação do conjunto de casos de teste utilizado durante
a aplicação do critério. Para tal, é necessária a realização de um cálculo que relaciona o
número de mutantes gerados, com o número e mutantes mortos.
O cálculo do escore de mutação é dado da seguinte forma:
DM(P, T )
ms(P,T) =
M(P) − EM(P)
exige lidar com o problema da equivalência de mutantes, que muitas vezes se torna um
grande desafio devido ao grande número de mutantes gerados, mesmo para programas
relativamente simples.
Em suma, o teste de mutação é uma técnica altamente eficaz para evidenciar defei-
tos em um produto de software e é uma ótima alternativa para medir o nível de adequação
de um conjunto de casos de teste, contudo, possui grandes desafios que precisam ser
superados. Entre as principais dificuldades estão o problema na identificação de mutan-
tes equivalentes, que na maioria das vezes acaba sendo resolvida de maneira manual e o
grande número de mutantes gerados que acaba se tornando um empecilho para a aplicação
da técnica em ambientes reais.
A literatura da área dispõe de diversas ferramentas que dão suporte à aplicação do teste de
mutação, uma delas a Proteum11 . A Proteum (do inglês Program Testing Using Mutants),
desenvolvida pelo grupo de pesquisa de Engenharia de Software do ICMC-USP, apoia
o teste de mutação para programas em C. Basicamente, ela oferece ao testador recursos
para, por meio da aplicação do critério teste de mutação, criar e avaliar a adequação de
um conjunto de casos de teste para um determinado programa. Com base nas informações
fornecidas pela Proteum, o testador pode melhorar a qualidade até obter um conjunto de
testes adequado ao critério.
A atividade de teste na Proteum é conduzido por meio de sessões de teste. Uma
sessão de testes é caracterizada por uma base de dados composta por um conjunto de
casos de testes e um conjunto de mutantes [Delamaro et al., 2000].
11 http://ccsl.icmc.usp.br/pt-br/projects/proteum
A ferramenta Proteum é composta por uma serie de módulos que atuam sobre
uma base de dados. Cada módulo é responsável por realizar uma atividade ligada ao teste
de mutação e possibilita duas formas de interação com o usuário (GUI/Script). A forma
indicada para iniciantes é a utilização da interface gráfica que tem como objetivo auxiliar
o testados a conhecer os módulos da ferramenta e como utilizar a interface por linha de
comando. Cada módulo da ferramenta é responsável por realizar uma atividade ligada ao
teste de mutação.
As Figuras 6.10, 6.11 e 6.12 ilustram a interface gráfica da ferramenta e demons-
tram respectivamente como se dá a visualização dos mutantes gerados, a visualização de
relatórios e o acompanhamento do status da sessão de teste.
• Test-new: cria uma sessão de testes, ou seja, cria todos os arquivos necessarios para
a aplicação do teste de mutação para o programa alvo;
• Tcase: modulo utilizado para gerenciar o conjunto de casos de teste utilizados em
uma sessão de teste na ferramenta Proteum, possibilitando adição, deleção, seleção
dos casos de teste a serem executados durante a sessão;
• Muta-gen: modulo responsável pela geração dos mutantes a serem utilizados na
sessão de testes;
• Exemuta: constrói e executa os mutantes a partir de descritores de mutação; tam-
bém é utilizado para selecionar um determinado grupo de mutantes;
• Muta: utilizado para o gerenciamento do conjunto de mutantes existente na sessão
de teste. Permite a seleção de um sub-conjunto de mutantes, além de possibilitar a
alteração do status dos mutantes individualmente;
• Muta-view: permite a visualização e analise dos mutantes criados/executados na
sessão de testes; e
• Report: é utilizado para a produção de dois tipos de relatórios: relatórios sobre os
casos de teste utilizados e relatórios sobre os mutantes gerados/executados.
Em seguida, o SUT é executado a partir das entradas “ent”, produzindo uma saída
qualquer comumente chamada de “saída real”. É exatamente nessa etapa do teste que
agem os “Oráculos de teste” – responsáveis por avaliar as saídas do SUT diante de al-
guma referência.
A automatização de testes possibilita uma grande economia de custos e proces-
sos de analise, além de aumentar a produtividade e prevenir os sistemas de futuras falhas
inesperadas. Automatizar processos de teste é uma questão de destaque para a área de
ES pelo fato de promover abordagens mais sistemáticas, produtivas e confiáveis [Ivory
and Hearst, 2001]. As vantagens na execução de testes automatizados são claras em com-
paração a testes manuais. Reexecução, suporte à regressão, tempo de projeto reduzido,
maior produtividade e prevenção contra erros são algumas das vantagens de testes au-
tomatizados. Entretanto, dependendo do sistema, a figura humana é capaz de encontrar
comportamentos inesperados que os testes automatizados não são capazes de encontrar
[Oliveira et al., 2014].
Referências
H. Agrawal, R. DeMillo, R. Hathaway, W. Hsu, E. Krauser, R. J. Martin, and A. Mathur.
Design of mutant operators for the c programming language. Technical Report SERC-
TR-41-P, Software Eng. Research Center, Purdue University, 1989.
P. Ammann and J. Offutt. Introduction to software testing. Cambridge University Press,
2008.
E. F. Barbosa, J. C. Maldonado, A. M. R. Vincenzi, M. E. Delamaro, S. R. S. Souza, and
M. Jino. Introduçao ao teste de software. Minicurso apresentado no XIV Simpósio
Brasileiro de Engenharia de Software (SBES 2000), 2000.
E. F. Barbosa, M. L. Chaim, A. M. R. Vincenzi, M. E. Delamaro, M. JINO, and J. C.
Maldonado. Capítulo 4 - Teste Estrutural. In M. E. Delamaro, J. C. Maldonado, and
M. Jino, editors, Introdução ao Teste de Software, pages 47–76. Campus, Rio de Ja-
neiro, 1 edition, 2007.
A. Bertolino. Software testing research and practice. In Abstract State Machines 2003,
pages 1–21, 2003.
A. Bertolino. Software testing research: Achievements, challenges, dreams. In 2007
Future of Software Engineering, pages 85–103, 2007.
M. E. Delamaro, J. C. Maldonado, and A. M. R. Vincenzi. Proteum/im 2.0: An integrated
mutation testing environment. In Mutation 2000 - A Symposium on Mutation Testing
for the New Century, October 2000.
M. E. Delamaro, E. F. Barbosa, A. M. R Vicenzi, and J. C. Maldonado. Teste de Mutação.
In M. E. Delamaro, M. Jino, and J. C. Maldonado, editors, Introdução ao Teste de
Software, pages 77 – 117. Elsevier, 2007a.
R. A. DeMillo, R. J. Lipton, and F. G. Sayward. Hints on test data selection: Help for the
practicing programmer. Computer, 11(4):34–41, April 1978. ISSN 0018-9162. doi:
10.1109/C-M.1978.218136.
C. Hunter and P. Strooper. Systematically deriving partial oracles for testing concurrent
programs. In Australian Computer Science Communications, pages 83–91, 2001.
IEEE. Ieee standard glossary of software engineering terminology. IEEE Standard, Sep-
tember 1990.
M. Y. Ivory and M. A. Hearst. The state of the art in automating usability evaluation of
user interfaces. ACM Computing Surveys (CSUR), pages 470–516, 2001.
S. W. K. John, J. A. Clark, and J. A. Mcdermid. Assessing test set adequacy for object-
oriented programs using class mutation. In Class Mutation, 28 JAIIO: Symposium on
Software Technology SoST‘99, pages 72–83, 1999.
A. Koscianski and M. S. Soares. Qualidade de software: aprenda as metodologias e
técnicas mais modernas para o desenvolvimento de software. Novatec Editora, 2007.
ISBN 9788575221129.
T. J. McCabe. A complexity measure. IEEE Trans. Softw. Eng., 2(4):308–320, July 1976a.
ISSN 0098-5589. doi: 10.1109/TSE.1976.233837.
A. J. Offutt and R. H. Untch. Mutation testing for the new century, 2001.
M. Pezze and C. Zhang. Automated test oracles: A survey. Advances in Computers, pages
1–48, 2014.
S. Rapps and E. J. Weyuker. Selecting software test data using data flow information.
IEEE Trans. Softw. Eng., 11(4):367–375, April 1985. ISSN 0098-5589. doi: 10.1109/
TSE.1985.232226.