SlideShare une entreprise Scribd logo
1  sur  37
Télécharger pour lire hors ligne
Escrevendo
testes unitários
para código legado:
técnicas de isolamento
André Ricardo Barreto de Oliveira (“Arbo")

Core Software Engineer @ Liferay
discover.liferay.com/tdc2014
Banco
de Dados +
Objeto
Relacional
Teste
automatizado
Orientação
a Objetos
Ambientes de
Desenvolvimento
Servidores
de Aplicação
+ REST
+ SOAP
Distribuição
+ Nuvem
Bibliotecas +
Frameworks
Refactoring +
Análise EstáticaProfiling
Comunidade++
2015:
20 anos
Integração
Contínua Programação
Funcional +
Scala
Em várias empresas perto de você:
"O Gigantesco Projeto
Escrito em Java"
10+ anos em produção
milhares de classes
milhões de linhas
de código desktop / web / mobile
centenas de jars, wars, ears
dúzias de frameworks
… e crescendo!
Mas e os testes?
“Veja bem…"
Projetos Java
Gigantescos
QA
Testes
Manuais
Selenium
Desenvolvedores
Banco de Dados
Spring
Runner
customizado
SEM TESTES?
SEM PROBLEMAS :)
Manual Prático
de Paraquedismo
"In the industry, legacy code
is slang for difficult-to-change
code that we don't understand.
!
To me, legacy code
is simply code without tests."
!
- Michael C. Feathers
Testes de Caracterização
Classe não tem testes?
Escreva um teste que apenas
documenta o comportamento atual.
Testes de Caracterização
Feliz com a cobertura?
Implemente a nova funcionalidade.
public class MassMailingServiceTest	
{	
!
@Test	
public void whatcangowrong()	
{	
new MassMailingService();	
}	
!
}
new MassMailingService();
DatabaseException:	
!
Você precisa estar conectado ao banco
de dados para realizar esta operação!
public MassMailingService()	
{	
this.limit =	
SettingsFromDatabaseService	
.getLimit();	
}	
#FAIL
Que fazer?
Alternativa 1
1. Estudar a documentação do framework
2. Instalar / importar / emprestar uma base de dados
3. Popular a base com os dados de teste
4. Logar na base
5. Rodar o teste
Alternativa 2
public MassMailingService(	
Settings settings) // interface	
{	
this.limit = settings.getLimit();	
}
Quando você pode alterar
a classe de negócio...
@Test	
public void whatcangowrong()	
{	
Settings s =	
Mockito.mock(Settings.class);	
	
Mockito.when(s.getLimit())	
.thenReturn(42);	
	
new MassMailingService(s);	
}
@Test	
public void whatcangowrong()	
{	
PowerMockito.mockStatic(	
SettingsFromDatabaseService.class);	
!
PowerMockito.stub(method(	
SettingsFromDatabaseService.class,
"getLimit"))	
.toReturn(42);	
!
new MassMailingService();	
}
Quando você não pode
alterar a classe de negócio...
public class MassMailingServiceTest	
{	
!
@Test	
public void send()	
{	
new MassMailingService().send(	
new Message("Hello"), 	
"andre.oliveira@liferay.com",	
"andre@arbo.com.br");	
}	
!
}
new MassMailingService().send(	
new Message("Hello"), 	
"andre.oliveira@liferay.com",	
"andre@arbo.com.br");
30 segundos depois…
Você possui 1 (uma) nova
mensagem
em
sua caixa postal
Você possui 1 (um
a) nova
m
ensagem
em
sua caixa postal
public void send(	
Message message, String... targets)	
{	
for (Address address : targets)	
{	
RealSMTPSender	
.send(message, address);	
}	
}	
#FAIL
@Test	
public void send()	
{	
Sender s = Mockito.mock(Sender.class);	
Message message = new Message("Hello");	
	
new MassMailingService(s).send(message, 	
"andre.oliveira@liferay.com",	
"andre@arbo.com.br");	
	
Mockito.verify(s).send(message,	
"andre.oliveira@liferay.com");	
	
Mockito.verify(s).send(message,	
"andre@arbo.com.br");	
}
@Test	
public void send()	
{	
PowerMockito.mockStatic(	
RealSMTPSender.class);	
Message message = new Message("Hello");	
new MassMailingService().send(message, 	
"andre.oliveira@liferay.com",	
"andre@arbo.com.br");	
PowerMockito.verifyStatic();	
RealSMTPSender.send(message,	
"andre.oliveira@liferay.com");	
PowerMockito.verifyStatic();	
RealSMTPSender.send(message,
		 	 	 "andre@arbo.com.br");	
}
Testes unitários
com isolamento
http://martinfowler.com/bliki/UnitTest.html
Martin Fowler
Isolamento e legado
Testes de Caracterização?
Código legado, sem testes?
Isolamento vai te ajudar
Isolamento e legado
Código novo,
testes novos?
Use o bom senso, ou…
"TDD is dead. Long live testing"
http://david.heinemeierhansson.com/2014/tdd-is-dead-long-live-testing.html
!
"Is TDD dead?"
http://martinfowler.com/articles/is-tdd-dead/
100% de cobertura?
Sim, é possível!
if (service.result() > 5) { /* caso especial */ }	
	
@Test public void happyDay() {	
when(service.result()).thenReturn(1);	
// do it + assert happy day	
}	
!
@Test public void casoEspecial() {	
when(service.result()).thenReturn(42);	
// do it + assert caso especial	
}
Condicionais e casos especiais
Cada if branch deriva um caso de teste
try { service.danger(); }	
catch (OpaException e) { /* caso especial */ }	
!
@Test public void sorryDay() {	
when(service.danger())	
.thenThrow(OpaException.class);	
// do it + assert caso especial	
}
Tratamento de exceções
Cada catch branch deriva um caso de teste
if (pessoa.idade() < 0) { 	
throw new IdadeNegativaException(); 	
}	
!
@Expected(IdadeNegativaException.class)	
@Test public void wtf() {	
when(pessoa.idade()).thenReturn(-99);	
// do it (vai lançar a exception)	
}
Validações
Simulando entradas impossíveis com mocks
Resultado: cobertura de todos
os branches de execução
!
Novas funcionalidades /Refactorings
Bugfixes:
cobertura
mínima
• Rastrear a linha de código do bug
• Escrever teste para o fragmento de lógica
• Mock mínimo que reproduz o problema
• Protip: Extrair método testável
Testes unitários com
isolamento: benefícios
2
3
4
5
6
Rodam em < 1 segundo
(como integração
chegavam a 30+)
Dispensam preparar
base de dados ou
serviços
Fácil conseguir 100%
de cobertura
Blindagem contra
colaboradores mal
comportados
Simular exceptions,
casos especiais e dados
ruins
Modularização de
Projetos Java
Gigantescos
1
Happy testing!
André Oliveira
andre.oliveira@liferay.com
twitter.com/arbocombr
github.com/arboliveira/unit-tests-with-isolation

Contenu connexe

Similaire à Escrevendo testes unitários para código legado: técnicas de isolamento

Extração de informação no StackOverflow Careers
Extração de informação no StackOverflow CareersExtração de informação no StackOverflow Careers
Extração de informação no StackOverflow Careersroberta arcoverde
 
One Language to Rule Them All: TypeScript
One Language to Rule Them All: TypeScriptOne Language to Rule Them All: TypeScript
One Language to Rule Them All: TypeScriptLoiane Groner
 
Introdução ao ASP.NET 3.5 - Campus Party Brasil 2009
Introdução ao ASP.NET 3.5 - Campus Party Brasil 2009Introdução ao ASP.NET 3.5 - Campus Party Brasil 2009
Introdução ao ASP.NET 3.5 - Campus Party Brasil 2009Ramon Durães
 
Ferramentas para Ambiente de Desenvolvimento Ágil
Ferramentas para Ambiente de Desenvolvimento ÁgilFerramentas para Ambiente de Desenvolvimento Ágil
Ferramentas para Ambiente de Desenvolvimento ÁgilInael Rodrigues
 
Latinoware 2012 - Desenvolvendo Interfaces com Holy
Latinoware 2012 - Desenvolvendo Interfaces com HolyLatinoware 2012 - Desenvolvendo Interfaces com Holy
Latinoware 2012 - Desenvolvendo Interfaces com HolyDextra
 
Latinoware2012 - Desenvolvendo interfaces WEB com HOLY de forma prática e efi...
Latinoware2012 - Desenvolvendo interfaces WEB com HOLY de forma prática e efi...Latinoware2012 - Desenvolvendo interfaces WEB com HOLY de forma prática e efi...
Latinoware2012 - Desenvolvendo interfaces WEB com HOLY de forma prática e efi...Leandro Guimarães
 
Domain Driven Design (DDD) - DevIsland, BH
Domain Driven Design (DDD) - DevIsland, BHDomain Driven Design (DDD) - DevIsland, BH
Domain Driven Design (DDD) - DevIsland, BHGiovanni Bassi
 
Minicurso sobre AndroidAnnotations, GreenDAO, EventBus e Crouton
Minicurso sobre AndroidAnnotations, GreenDAO, EventBus e CroutonMinicurso sobre AndroidAnnotations, GreenDAO, EventBus e Crouton
Minicurso sobre AndroidAnnotations, GreenDAO, EventBus e CroutonRicardo Longa
 
Introducao a Linguagem Kotlin
Introducao a Linguagem KotlinIntroducao a Linguagem Kotlin
Introducao a Linguagem KotlinCalebeMiquissene
 
Precisamos falar sobre MERN stack
Precisamos falar sobre MERN stackPrecisamos falar sobre MERN stack
Precisamos falar sobre MERN stackSidney Roberto
 
Workshop Elasticsearch - Android Dev Conference 2016
Workshop Elasticsearch - Android Dev Conference 2016Workshop Elasticsearch - Android Dev Conference 2016
Workshop Elasticsearch - Android Dev Conference 2016Thiago Barradas
 
Rails - EXATEC2009
Rails - EXATEC2009Rails - EXATEC2009
Rails - EXATEC2009Caue Guerra
 
Monitoramento em tempo real (DEVDAY2015)
Monitoramento em tempo real (DEVDAY2015)Monitoramento em tempo real (DEVDAY2015)
Monitoramento em tempo real (DEVDAY2015)Marcus Lacerda
 
Design de APIs RESTful Seguras e Escaláveis
Design de APIs RESTful Seguras e EscaláveisDesign de APIs RESTful Seguras e Escaláveis
Design de APIs RESTful Seguras e EscaláveisKleber Bacili
 
Design de APIs RESTful – Seguras, Escaláveis e Interoperáveis, por Kleber Bacili
Design de APIs RESTful – Seguras, Escaláveis e Interoperáveis, por Kleber BaciliDesign de APIs RESTful – Seguras, Escaláveis e Interoperáveis, por Kleber Bacili
Design de APIs RESTful – Seguras, Escaláveis e Interoperáveis, por Kleber BaciliiMasters
 
Melhores práticas de CI/CD na construção de aplicações modernas
Melhores práticas de CI/CD na construção de aplicações modernasMelhores práticas de CI/CD na construção de aplicações modernas
Melhores práticas de CI/CD na construção de aplicações modernasAmazon Web Services LATAM
 
JavaOne LATAM 2016 - Combinando AngularJS com Java EE
JavaOne LATAM 2016 - Combinando AngularJS com Java EEJavaOne LATAM 2016 - Combinando AngularJS com Java EE
JavaOne LATAM 2016 - Combinando AngularJS com Java EERodrigo Cândido da Silva
 

Similaire à Escrevendo testes unitários para código legado: técnicas de isolamento (20)

Scala no Android
Scala no AndroidScala no Android
Scala no Android
 
Extração de informação no StackOverflow Careers
Extração de informação no StackOverflow CareersExtração de informação no StackOverflow Careers
Extração de informação no StackOverflow Careers
 
One Language to Rule Them All: TypeScript
One Language to Rule Them All: TypeScriptOne Language to Rule Them All: TypeScript
One Language to Rule Them All: TypeScript
 
Introdução ao ASP.NET 3.5 - Campus Party Brasil 2009
Introdução ao ASP.NET 3.5 - Campus Party Brasil 2009Introdução ao ASP.NET 3.5 - Campus Party Brasil 2009
Introdução ao ASP.NET 3.5 - Campus Party Brasil 2009
 
Ferramentas para Ambiente de Desenvolvimento Ágil
Ferramentas para Ambiente de Desenvolvimento ÁgilFerramentas para Ambiente de Desenvolvimento Ágil
Ferramentas para Ambiente de Desenvolvimento Ágil
 
Latinoware 2012 - Desenvolvendo Interfaces com Holy
Latinoware 2012 - Desenvolvendo Interfaces com HolyLatinoware 2012 - Desenvolvendo Interfaces com Holy
Latinoware 2012 - Desenvolvendo Interfaces com Holy
 
Latinoware2012 - Desenvolvendo interfaces WEB com HOLY de forma prática e efi...
Latinoware2012 - Desenvolvendo interfaces WEB com HOLY de forma prática e efi...Latinoware2012 - Desenvolvendo interfaces WEB com HOLY de forma prática e efi...
Latinoware2012 - Desenvolvendo interfaces WEB com HOLY de forma prática e efi...
 
Domain Driven Design (DDD) - DevIsland, BH
Domain Driven Design (DDD) - DevIsland, BHDomain Driven Design (DDD) - DevIsland, BH
Domain Driven Design (DDD) - DevIsland, BH
 
Minicurso sobre AndroidAnnotations, GreenDAO, EventBus e Crouton
Minicurso sobre AndroidAnnotations, GreenDAO, EventBus e CroutonMinicurso sobre AndroidAnnotations, GreenDAO, EventBus e Crouton
Minicurso sobre AndroidAnnotations, GreenDAO, EventBus e Crouton
 
Introducao a Linguagem Kotlin
Introducao a Linguagem KotlinIntroducao a Linguagem Kotlin
Introducao a Linguagem Kotlin
 
Precisamos falar sobre MERN stack
Precisamos falar sobre MERN stackPrecisamos falar sobre MERN stack
Precisamos falar sobre MERN stack
 
Workshop Elasticsearch - Android Dev Conference 2016
Workshop Elasticsearch - Android Dev Conference 2016Workshop Elasticsearch - Android Dev Conference 2016
Workshop Elasticsearch - Android Dev Conference 2016
 
Rails - EXATEC2009
Rails - EXATEC2009Rails - EXATEC2009
Rails - EXATEC2009
 
Monitoramento em tempo real (DEVDAY2015)
Monitoramento em tempo real (DEVDAY2015)Monitoramento em tempo real (DEVDAY2015)
Monitoramento em tempo real (DEVDAY2015)
 
Design de APIs RESTful Seguras e Escaláveis
Design de APIs RESTful Seguras e EscaláveisDesign de APIs RESTful Seguras e Escaláveis
Design de APIs RESTful Seguras e Escaláveis
 
Design de APIs RESTful – Seguras, Escaláveis e Interoperáveis, por Kleber Bacili
Design de APIs RESTful – Seguras, Escaláveis e Interoperáveis, por Kleber BaciliDesign de APIs RESTful – Seguras, Escaláveis e Interoperáveis, por Kleber Bacili
Design de APIs RESTful – Seguras, Escaláveis e Interoperáveis, por Kleber Bacili
 
Melhores práticas de CI/CD na construção de aplicações modernas
Melhores práticas de CI/CD na construção de aplicações modernasMelhores práticas de CI/CD na construção de aplicações modernas
Melhores práticas de CI/CD na construção de aplicações modernas
 
04_Introducao_JavaScript.pdf
04_Introducao_JavaScript.pdf04_Introducao_JavaScript.pdf
04_Introducao_JavaScript.pdf
 
JavaOne LATAM 2016 - Combinando AngularJS com Java EE
JavaOne LATAM 2016 - Combinando AngularJS com Java EEJavaOne LATAM 2016 - Combinando AngularJS com Java EE
JavaOne LATAM 2016 - Combinando AngularJS com Java EE
 
DDD > Experiências
DDD > ExperiênciasDDD > Experiências
DDD > Experiências
 

Escrevendo testes unitários para código legado: técnicas de isolamento