14
Teste de Software – Uma introdução ao uso do Junit em testes unitários Gabriel Bittencourt, Pablo Venzke Tessmann, Thyérri Schirmer Departamento de Informática – Universidade de Santa Cruz do Sul (UNISC) Avenida Independência 2293 – 96815-900 – Santa Cruz do Sul – RS - Brasil {gedson, pablovtessmann, schirmer}@mx2.unisc.br Abstract. To perform a software test, it is necessary to think of the system in parts and test it in the same way, that is, we need to determine the features to be tested. To test certain part of the system before it must be ensured if it is possible that component can be tested independently. There are several types (s) of tests as: integration, functional (black box), installation, integrity, security, volume testing, performance, usability, maintenance and regression and unit test. In this article, we will also talk about some problems arising in the development of an application, as well as some concepts of software testing for the study of unit testing and its derivations, and thus applying some techniques with JUnit. Resumo.  Para realizar um teste de software, é necessário pensar no sistema em partes e testá-lo da mesma maneira, ou seja, é preciso determinar as funcionalidades a serem testadas. Para testar determinada parte do sistema, antes deve-se garantir se é possível que aquele componente possa ser testado de maneira independente. Existem vários tipos (níveis) de testes como: Integração, funcional (caixa preta), de instalação, de integridade, segurança, teste de volume, de performance, usabilidade, regressão e manutenção e teste de unidade. Neste artigo, falaremos também sobre alguns problemas gerados no desenvolvimento de uma aplicação, assim como alguns conceitos de testes de software visando o estudo de testes unitários bem como as suas derivações, e com isso aplicando algumas técnicas com o JUnit. 1. Defeitos no desenvolvimento de um software No processo de desenvolvimento de software, todos os defeitos são humanos e, apesar do uso dos melhores métodos de desenvolvimento, ferramentas, tecnologias ou profissionais, permanecem presentes nos produtos, o que torna a atividade de teste fundamental durante o desenvolvimento de um software. Esta atividade corresponde ao último recurso para avaliação do produto antes da sua entrega ao usuário final. O tamanho do projeto a ser desenvolvido e a quantidade de pessoas envolvidas no processo são dois possíveis fatores que aumentam a complexidade dessa tarefa, e consequentemente aumentam a probabilidade de defeitos. Assim, a ocorrência de falhas é inevitável. Mas o que significa dizer que um programa falhou? Basicamente significa que o funcionamento do programa não está de acordo com o esperado pelo usuário. Por 1

Teste de Software – Uma introdução ao uso do Junit em testes unitários

  • Upload
    unisc

  • View
    1

  • Download
    0

Embed Size (px)

Citation preview

Teste de Software – Uma introdução ao uso do Junit em testes unitários

Gabriel Bittencourt, Pablo Venzke Tessmann, Thyérri Schirmer

Departamento de Informática – Universidade de Santa Cruz do Sul (UNISC) Avenida Independência 2293 – 96815-900 – Santa Cruz do Sul – RS - Brasil

{gedson, pablovtessmann, schirmer}@mx2.unisc.br

Abstract. To perform a software test, it is necessary to think of the system in parts and test it in the same way, that is, we need to determine the features to be tested. To test certain part of the system before it must be ensured if it is possible that component can be tested independently. There are several types (s) of tests as: integration, functional (black box), installation, integrity, security, volume testing, performance, usability, maintenance and regression and unit test. In this article, we will also talk about some problems arising in the development of an application, as well as some concepts of software testing for the study of unit testing and its derivations, and thus applying some techniques with JUnit.

Resumo.  Para realizar um teste de software, é necessário pensar no sistema em partes e testá-lo da mesma maneira, ou seja, é preciso determinar as funcionalidades a serem testadas. Para testar determinada parte do sistema, antes deve-se garantir se é possível que aquele componente possa ser testado de maneira independente. Existem vários tipos (níveis) de testes como: Integração, funcional (caixa preta), de instalação, de integridade, segurança, teste de volume, de performance, usabilidade, regressão e manutenção e teste de unidade. Neste artigo, falaremos também sobre alguns problemas gerados no desenvolvimento de uma aplicação, assim como alguns conceitos de testes de software visando o estudo de testes unitários bem como as suas derivações, e com isso aplicando algumas técnicas com o JUnit.

1. Defeitos no desenvolvimento de um softwareNo processo de desenvolvimento de software, todos os defeitos são humanos e, apesar do uso dos melhores métodos de desenvolvimento, ferramentas, tecnologias ou profissionais, permanecem presentes nos produtos, o que torna a atividade de teste fundamental durante o desenvolvimento de um software. Esta atividade corresponde ao último recurso para avaliação do produto antes da sua entrega ao usuário final.

O tamanho do projeto a ser desenvolvido e a quantidade de pessoas envolvidas no processo são dois possíveis fatores que aumentam a complexidade dessa tarefa, e consequentemente aumentam a probabilidade de defeitos. Assim, a ocorrência de falhas é inevitável. Mas o que significa dizer que um programa falhou? Basicamente significa que o funcionamento do programa não está de acordo com o esperado pelo usuário. Por

1

exemplo, quando um usuário da linha de produção efetua consultas no sistema das quais só a gerência deveria ter acesso. Esse tipo de falha pode ser originado por diversos motivos:

• A especificação pode estar errada ou incompleta;• A especificação pode conter requisitos impossíveis de serem implementados

devido a limitações de hardware ou software;• A base de dados pode estar organizada de forma que não seja permitido

distinguir os tipos de usuário;• Pode ser que haja um defeito no algoritmo de controle dos usuários.

Os defeitos normalmente são introduzidos na transformação de informações entre as diferentes fases do ciclo de desenvolvimento de um software. Vamos seguir um exemplo simples de ciclo de vida de desenvolvimento de software: os requisitos expressos pelo cliente são relatados textualmente em um documento de especificação de requisitos. Esse documento é então transformado em casos de uso, que por sua vez foi o artefato de entrada para o projeto do software e definição de sua arquitetura utilizando diagramas de classes da UML. Em seguida, esses modelos de projetos foram usados para a construção do software em uma linguagem que não segue o paradigma orientado a objetos. Observe que durante esse período uma série de transformações foi realizada até chegarmos ao produto final. Nesse meio tempo, defeitos podem ter sido inseridos. A imagem abaixo expressa exatamente a metáfora discutida nesse parágrafo.

Figura 1.

2. Definição de teste e o seu papel

Testar é verificar se o software está fazendo o que deveria fazer, de acordo com os seus requisitos, e não está fazendo o que não deveria fazer. [RIOS E MOREIRA, 2002].

2

Testar é qualquer atividade que a partir da avaliação de um atributo ou capacidade de um programa ou sistema, seja possível determinar se ele alcança os resultados desejados. [BILL HETZEL, 1998].

Com base nessas informações, o objetivo de um teste é avaliar o comportamento do software, baseado no que foi especificado. Ou seja, pelos esforços dos testes, é possível perceber que é mais fácil provar que algo funciona ao invés de provar que algo não funciona.

Resumindo: Testes servem para diminuir os riscos de ocorrer um erro.

3. Conceitos teóricos sobre o teste de software

O conceito de teste de software pode ser compreendido através de uma visão intuitiva ou mesmo de uma maneira formal. Existem inúmeras definições e modelos para esse conceito. De uma maneira simples, testar um software significa verificar através de uma execução controlada se o seu comportamento corre de acordo com o especificado. O objetivo principal desta tarefa é revelar o número máximo de falhas dispondo do mínimo de esforço, ou seja, mostrar aos que desenvolvem se os resultados estão ou não de acordo com os padrões estabelecidos.

Inicialmente é necessário entender e conhecer a diferença entre: defeito, erro e falha. As definições a seguir seguem a terminologia padrão de engenharia de software do IEEE:

Defeito: Ato inconsistente cometido por um indivíduo ao tentar entender uma determinada informação, resolver um problema ou utilizar um método ou uma ferramenta. Por exemplo, uma instrução ou comando incorreto.

Erro: Manifestação concreta de um defeito num artefato de software. Diferença entre o valor obtido e o valor esperado, ou seja, qualquer estado intermediário incorreto ou resultado inesperado na execução de um programa constitui um erro.

Falha: Comportamento operacional do software diferente do esperado pelo usuário. Uma falha pode ter sido causada por diversos erros e alguns erros podem nunca causar uma falha.

A Figura abaixo apresenta a diferença entre esses conceitos. Defeitos fazem parte do universo físico (a aplicação propriamente dita) e são causados por pessoas, por exemplo, através do mal uso de uma tecnologia. Defeitos podem ocasionar a manifestação de erros em um produto, ou seja, a construção de um software de forma diferente do que foi especificado (universo de informação). Por fim, os erros geram falhas, que são comportamentos inesperados em um software que afetam diretamente o usuário final da aplicação (universo do usuário) e pode inviabilizar a utilização de um software.

3

Figura 2. Defeito x erro x falha

Com essas informações, verificamos que o processo de teste de software demonstra as falhas de um produto. Após a identificação e execução dos testes é preciso fazer a depuração como objetivo de realizar a correção dos defeitos que originaram a falha. Ressaltando que depurar não é efetivamente testar.

É importante estimar o tempo que um teste leva para ser executado, os recursos que serão utilizados, pessoas envolvidas, tecnologias necessárias, mas o principal para o teste de software é que o analista responsável pelo teste tenha conhecimento do sistema, para que possa pensar em todas as formas possíveis de se executar determinado passo. Entretanto, para se testar um sistema, leva-se em conta dois fatores, "probabilidade e risco".

3. Ciclo de vida dos testes de software

Existem 5 fases dentro do ciclo de vida dos testes de software. O primeiro deles chamamos de planejamento, ou seja, é elaborada a estratégia de teste e o plano de teste (como será executado). A fase seguinte é a preparação, cujo objetivo é preparar o ambiente de teste (equipamentos, pessoal, ferramentas de automação, massa de testes) de modo que os testes sejam executados de acordo com o que foi planejado. A terceira fase é a especificação, nela temos as atividades de elaborar (ou revisar) casos de testes e elaborar (ou revisar) roteiros de testes. A quarta fase é a execução, os testes são executados e registrado os resultados obtidos. E por fim, a entrega, na qual toda a documentação é arquivada.

4. Conceitos de teste unitário

Vamos partir através de uma analogia: Se um avião só fosse testado após a conclusão de sua construção, com certeza isso seria um verdadeiro desastre, é nesse ponto que a engenharia aeronáutica é uma boa referência em processos de construções de projetos de software, principalmente em sistemas de missão crítica, pois durante a construção e montagem de um avião todos os seus componentes são testados isoladamente até a

4

exaustão, e depois cada etapa de integração também é devidamente testada e homologada.

O teste unitário, de certa forma se baseia nessa ideia, pois é uma modalidade de testes que se concentra na verificação da menor unidade do projeto de software. Testes de unidade podem garantir que o aplicativo esteja em teste desde o início do desenvolvimento. É realizado o teste de uma unidade lógica, com uso de dados suficientes para se testar apenas a lógica da unidade em questão.

Em sistemas construídos com uso de linguagens orientadas a objetos, essa unidade pode ser identificada como um método, uma classe ou mesmo um objeto.

Grande parte dos aplicativos estão divididos em subsistemas. Como desenvolvedor, você quer garantir cada um destes subsistemas funcionem corretamente. À medida que o código é escrito, os primeiros testes serão provavelmente testes de unidade lógica. Conforme são escritos mais testes e mais códigos, serão inseridos os testes de unidade de integração e testes funcionais. Abaixo, seguem as três modalidades de teste de unidade:

Teste de unidade lógico: Testes de unidade que focam no exercício da lógica do código. São testes criados para execução exclusivamente de um método. O controle dos limites de um determinado método usando objetos mock ou stubs.

Teste de unidade de integração: Realiza testes entre componentes no ambiente real (ou em parte dele). Um exemplo deste contexto é um código que acessa uma base de dados com testes efetivos com banco de dados, provando dessa forma, que a interação com a camada de dados efetivamente funciona.

Testes de unidade funcionais: Testes de unidade estendem os limites de unidade de integração para confirmar uma resposta estímulo. Por exemplo: o acesso a uma página na WEB é protegido e que o acesso é realizado após o login de uma conta. De forma resumida, testes funcionais não são testes de unidades puros, porém não são testes funcionais puros devido ao fato de dependerem de um ambiente externo do que realmente são os testes de unidade puros. Mas eles não testam um fluxo de trabalho completo, ou regra de negócio, como esperado pelos testes funcionais puros.

5. Introdução do JUnit

Durante o desenvolvimento, a primeira coisa que devemos fazer é executar o nosso próprio “teste de aceitação” do programador. Nós codificamos, compilamos e rodamos. E quando rodamos, testamos. O “teste” pode ser efetuado simplesmente, clicando num botão para confirmar se ele traz à tona o menu esperado. Porém, todos os dias, nós criamos códigos, compilamos, executamos e testamos. Quando o software é testado, frequentemente são encontrados problemas, normalmente já na primeira execução. Portanto, codificamos, compilamos, executamos e testamos novamente. Com isso, rapidamente será desenvolvida uma padronização para os testes informais: adicionamos, visualizamos, editamos e apagamos registros. Executar um pequeno conjunto de testes

5

como este à mão, é muito fácil de fazer, tantas vezes quantas forem necessárias. Mas alguns programadores não apreciam este tipo de trabalho repetitivo. Ao invés de executar à mão, eles preferem criar um pequeno programa que roda o teste automaticamente. O código para testes é uma coisa, teste que que rodam automaticamente é outra [MASSOL, 2005].

Alguns desenvolvedores perceberam que testes automatizados são uma parte essencial do processo de desenvolvimento. Um componente não pode ser provado que ele funciona até que passe por uma compreensível bateria de testes. De fato, dois desenvolvedores perceberam que este tipo de “testes de unidade” mereciam o seu próprio framework. Em 1997, Erich Gamma e Kent Beck criaram um framework em Java, simples, mas muito eficiente, para testes de unidade chamado JUnit (JUnit.org). É um software de fonte aberta, ou seja, é possível distribuir o framework para aplicações comerciais sem a menor restrição (MASSOL, 2005).

Teste de unidade examina o comportamento de uma unidade de trabalho distinta. Dentro de um aplicativo Java, a “unidade de trabalho distinta” é frequentemente um método único. Por contraste, testes de integração e testes de aceitação examinam como os vários componentes estão interligados. Uma unidade de trabalho é uma tarefa que não é diretamente dependente da finalização de qualquer outra tarefa.

Motivos para utilizar o JUnit:

Permite a criação rápida de código de teste possibilitando um aumento na qualidade do desenvolvimento e teste;

Amplamente utilizado pelos desenvolvedores da comunidade código-aberto, possuindo um grande número de exemplos;

Uma vez escritos, os testes são executados rapidamente sem que, para isso, seja interrompido o processo de desenvolvimento;

JUnit verifica os resultados dos testes e fornece uma resposta imediata; JUnit é livre e orientado a objetos.

5.1. Implementando testes unitários em Java

Para iniciarmos os testes com o JUnit, é importante conhecer alguns métodos ágeis para a execução destes testes, como por exemplo, o “Extreme Programming” (ou XP) cujo o foco está voltado para a agilidade de equipes e qualidade de projetos, agregado em valores como: simplicidade, comunicação e feedback. XP é uma metodologia comportamental, em que preza por mudanças de atitudes e práticas. Sua principal mudança está na máxima integração entre pessoas e estimulando a participação do cliente, ou seja, o desenvolvimento é realizado juntamente com ele.

Práticas XP é um conjunto de boas práticas que melhoram o planejamento, execução e gerenciamento de seu projeto de software. De acordo com a imagem abaixo

6

é possível melhorar a eficiência e eficácia, cujo objetivo é diminuir o retrabalho, garantindo sobretudo a qualidade do software a ser desenvolvido.

Figura 3. Exemplo de práticas XP a nível organizacional, de equipes e de pares.

Na imagem abaixo temos um diagrama, mostrando de que maneira as classes de testes ficam organizadas em um projeto desenvolvido em Java e a correlação com as práticas XP.

Figura 4. Organização das classes de teste.

7

Para entender como a arquitetura do JUnit funciona, é importante entender de que modo as classes estão organizadas dentro da API do framework, de acordo com a figura abaixo:

Figura 5. Classe do JUnit.

Command: O padrão (pattern) permite encapsular um pedido (de teste) como objeto e fornece um método run().

Run(): Cria um contexto (método setUp); em seguida executa o código usando um contexto e verifica o resultado (método runTest); e por fim, limpa o contexto (método tearDown).

SetUp(): Método chamado antes de cada método, pode ser utilizado para abrir uma conexão de banco de dados.

TearDown(): Método chamado depois de cada método de teste, usado para desfazer o que setUp() fez, por exemplo fechar uma conexão de banco de dados.

RunTest(): Método responsável por controlar a execução de um teste particular.Classe TestSuite: Com esta classe, o desenvolvedor executa um único teste com

vários métodos de testes e registra os resultados num TestResult.

5.2. Implementando um teste

Asserções:Para testar nosso código, o JUnit fornece os métodos de “assert”. O conceito é muito simples, todo método de asserção recebe um valor que é o correto esperado pelo teste, e o outro valor que é o devolvido pelo seu código. A comparação é executada, e o teste falha caso sejam diferentes e passa caso sejam iguais. Apenas com esse conceito é

8

possível testar todo o código, basta saber quais são os valores que devem ser testados para garantir o funcionamento do código.

A chave para escrever um teste unitário que cobre muito bem o seu código, é colocar as asserções nos valores realmente relevantes ao funcionamento do sistema. Algumas vezes por exemplo, não é preciso testar um valor intermediário gerado pelo código, apenas o resultado final, outras vezes esse valor intermediário gerado é crucial para o resultado final e, portanto, deve ser verificado também.

Quando se adicionam valores, é necessário entender que um valor pode ser qualquer objeto Java, portanto é muito importante implementar o “equals” e “hashcode” de seus objetos de resposta que serão testados pelo JUnit.

Será demonstrado um exemplo de classe de testes com o JUnit 4 para vermos como funciona na prática a execução de testes unitários.

Na imagem abaixo, é mostrada a criação de uma classe de testes:

Figura 6. Criação de uma classe

Apesar do nome parecer que segue algum padrão, não é necessário que a classe tenha nenhuma dessas palavras em seu nome. Porém esta classe ainda não é uma classe de testes do JUnit. Para torná-la um teste, é preciso criar um método da seguinte forma:

Figura 7. Exemplo de implementação método teste

Na anotação “org.JUnit.Test”. Essa anotação diz que nosso método “metodoQualquer” é um teste do JUnit. Perceba também que seu retorno é “void” e ele não recebe nenhum argumento. Então neste momento a classe é um teste propriamente dito. O próximo passo é adicionar uma asserção para ver o funcionamento da mesma. Dentro do método criado, adicione a seguinte chamada:

Figura 8. Exemplo de asserção

9

Note que o primeiro argumento do método, é a mensagem que vai aparecer caso o método falhe. Mude o valor obtido (último argumento) para ver a mensagem de erro.

Esse é o básico de execução de testes. Agora existem outras funcionalidades que ajudam a escrever testes mais complexos, por exemplo, caso seja preciso criar um objeto mais complexo para testes, é feito o seguinte, adicione o seguinte código na classe de testes:

A String é inicializada e setada novamente pra “null” 3 vezes. Isso porque a classe possui três métodos de testes, e os métodos anotados com “@Before” rodam sempre antes de todos os métodos de teste. O mesmo vale para os métodos anotados com “@After”, apenas estes rodam depois de executar os métodos de teste.

Com essas duas anotações é possível criar cenários que estão sempre “zerados” e corretamente inicializados para cada teste que será executado em sua classe. Com isso é possível separar melhor as asserções em suas classes em mais métodos, deixando mais específico e focado cada método de teste.

Porém algumas vezes queremos inicializar algum objeto para o teste todo, sem precisar de algo específico para cada execução. Nesse caso existem duas outras anotações que podem ser úteis, como no exemplo abaixo:

10

Neste caso existe uma restrição neste contexto, pois o escopo das chamadas é estático. Os métodos necessitam ser estáticos e, portanto, as suas inicializações só serão uteis para propriedades que são estáticas em sua classe de teste.

Essa funcionalidade possui esse comportamento porque o JUnit instancia um novo objeto da sua classe de testes para cada método que será rodado, dessa forma ele garante um melhor isolamento dos testes, tornando-os mais unitários por assim dizer. Dessa forma somente métodos estáticos são garantia de execução antes de todos os outros métodos.

6. Conclusões

O teste de software é uma das atividades mais custosas do processo de desenvolvimento de software, pois pode envolver uma quantidade significativa dos recursos de um projeto. Lançar um software não basta simplesmente desenvolvê-lo, existe a necessidade inicial de testar o software utilizando-se de formas corretas de testes, sejam eles os testes de componentes, de independentemente do seu nível. Um ponto bastante importante para a viabilização da aplicação de teste de software é a utilização de uma infraestrutura adequada. Realizar testes não consiste simplesmente na geração e execução de casos de teste, mas envolvem também questões de planejamento, gerenciamento e análise de resultados. Sem esses testes, o sistema possui altas chances de apresentar falhas nas execuções de suas rotinas, o que poderá comprometer a credibilidade do analista de sistemas e reduzir o valor do produto no já tão competitivo mercado da informática. Evitar tais ocorrências é justamente o que faz dos testes de softwares uma parte vital do desenvolvimento deles, assim como evitar prejuízos financeiros, pessoais, de saúde, segurança e integridade. Além disso, é importante ressaltar que diferentes tipos de aplicações possuem diferentes técnicas de teste a serem aplicadas, ou seja, testar uma aplicação web envolve passos diferenciados em comparação aos testes de um sistema embarcado. Cada tipo de aplicação possui

11

características especificas que devem ser consideradas no momento da realização dos testes.

O segredo de um bom teste unitário é o quanto ele consegue cobrir do funcionamento do código, sem que seja necessário escrever um teste extremamente detalhado que deixe o código acoplado demais, e não permita muita mudança no código original. Se for investido tempo demais testando todos os valores possíveis das classes de maneira extremamente detalhada, quando o cliente pedir que um requisito mude, com certeza ocorrerá a sensação de trabalho jogado fora, e desânimo por ter que escrever tudo novamente. De forma resumida, testar o que é crítico, o que possui risco e também a análise de riscos do plano de testes. A ideia é utilizar padrões de design para testes unitários, de forma que se mantenha a cobertura de código e ainda deixe os testes bem flexíveis a mudanças. Tarefa difícil, mas não impossível, e concluímos que é muito mais difícil e trabalhosos escrever testes realmente bons, do que escrever o código que será testado.

7. Referências Bibliográficas[1] SOFTWARE SAPPERDisponível em: <http://www.davedevelopment.co.uk/2008/03/20/10-tools-for-modern-php- development.html>

[2] Domingues, André Luís dos Santos “Avaliação de critérios e ferramentas de teste para programas OO.”Disponível em: <http://www.teses.usp.br/teses/disponiveis/55/55134/tde-28112002-171043/en.php>

[3] Oliveira, Ricardo Zitelli de e Darce, Álvaro Ferraz “Como O Teste De Software Pode Ajudar O Desenvolvimento”Disponível em:<http://intertemas.unitoledo.br/revista/index.php/ETIC/article/view/ 3377/3128>

[4] Neto, Arilo Claudio Dias “Artigo Engenharia de Software - Introdução a Teste de Software”Disponível em:< http://www.devmedia.com.br/artigo-engenharia-de-software-introducao-a-teste-de-software/8035>

[5] Massol, Vincent e Husted,Ted (2005) “JUnit em ação”, Editora Ciência Moderna Ltda., Rio de Janeiro

12

[6] Bastos, Aderson e Rios, Emerson e Cristalli, Ricardo e Moreira, Trayahú (2006) “Base de conhecimento em teste de software”, Editora Martins Fontes[7] Anais III Simpósio Brasileiro de qualidade de software, 2004

[8] Medeiros, Manoel Pimentel “JUnit-Implementando testes unitários em Java–Parte I”Disponível em:< http://www.devmedia.com.br/JUnit-implementando-testes-unitarios-em-java-parte-i/1432>

[9] OS 13 PRINCIPAIS TIPOS DE TESTES DE SOFTWAREDisponível em:< http://www.targettrust.com.br/blog/desenvolvimento/testes/os-13-principais-tipos-de-testes-de-software/>

[10] REGRA 10 DE MYERSDisponível em:< https://testedsoftware.wordpress.com/2012/04/02/regra-10-de-meyrs/>

[11] Medeiros, Manoel Pimentel JUnit-Implementando testes unitários em Java-Parte IIDisponível em:< http://www.devmedia.com.br/JUnit-implementando-testes-unitarios-em-java-parte-ii/1549>

[12] JUnitDisponível em:< http://pt.wikipedia.org/wiki/JUnit>

[13] Medeiros, Higor “Mocks: Introdução a Automatização de Testes com Mock Object”Disponível em:< http://www.devmedia.com.br/mocks-introducao-a-automatizacao-de-testes-com-mock-object/30641>

[14] STUBDisponível em:< http://pt.wikipedia.org/wiki/Stub>

[15] Medeiros, Manoel Pimentel “Extreme Programming – Conceitos e Práticas”Disponível em:< http://www.devmedia.com.br/extreme-programming-conceitos-e-praticas/1498>

[16] Neto, Aristides Vicente de Paula “Criando testes com JUnit”Disponível em:< http://javafree.uol.com.br/dependencias/tutoriais/testes_JUnit.pdf>

[17] Oliveira, Eric C M “Java: Testes Unitários e JUnit”Disponível em:< http://www.linhadecodigo.com.br/artigo/576/java-testes-unitarios-e-JUnit.aspx>

13

[18]Disponível em:< http://siep.ifpe.edu.br/anderson/blog/?page_id=976>

[19]Disponível em:< http://www.desenvolvimentoagil.com.br/xp/praticas/tdd/ mock_objects>

[20] TESTES UNITÁRIOS COM JUNIT – DE VOLTA AO BÁSICODisponível em:< http://www.dclick.com.br/2011/12/14/testes-unitarios-com-JUnit-de-volta-ao-basico/>

[21] Rocha, Helder da “JUnit”Disponível em:< http://pt.slideshare.net/denistuning/j820-04-JUnit?related=1>

[22] CICLO DE VIDA DOS TESTES E DO DESENVOLVIMENTODisponível em:< http://analistadetestes.blogspot.com.br/2013/05/ciclo-de-vida-dos-testes-e-do.html>

[23] VAGAS DE ANALISTA DE TESTESDisponível em:< http://www.catho.com.br/vagas/analista-de-testes/>

[24] CERTIFICAÇÕES DE TESTE DE SOFTWARE E ÁREAS AFINSDisponível em:< http://www.qualister.com.br/blog/certificacoes-de-teste-de-software-e-areas-afins>

[25] Tatham, Simon “Como Relatar Bugs De Maneira Eficaz”Disponível em:< http://www.chiark.greenend.org.uk/~sgtatham/bugs-br.html>

14