Novas Ferramentas de Teste na
plataforma Java
Just Java 2009
Quem sou eu ?
Jorge Alberto Diz
•Mestre em Eng. Elétrica (UNICAMP ´95)
•Bach. em Ciência da Computação (UNICAMP ´89) •Programando desde ´84, em Java desde ´99
•Automação de testes desde ´94
•Ensinando desde ´01, na Globalcode desde ´06 •Consultoria em testes e métodos ágeis
Apresentação da agenda
•Novos modelos de testes: pirâmides e quadrantes •Apoio ao desenvolvimento: unitários/dublês
•Apoio à comunicação: prosa/planilhas/convergência Teste de interface usuário
Testes difíceis •Futuro
Quadrantes de Marick
Q2: GUI, regras de negócio Q3: Exploratório, usabilidade, aceitação funcional Q1: Unitários, componentes Q4: Desempenho / segurança Testes voltados ao Negócio S sup orte ao t ime crít ica S crít ica ao pro du toPirâmide de testes: frágil
Interface Usuário
Regras de
Negócio
Unidades
Pirâmide de testes: ágil (Mike Cohn)
Interface
Usuário
Regras de
Negócio
Unidades
A pirâmide de testes (Huggins*)
(*) Jason Huggins, autor do Selenium
Consensos (poucos)
•Não é possível testar tudo
•Quem testa deve ter atitude crítica •Testes têm custo
•Testes informam sobre riscos
•Áreas concentram defeitos (bug clusters):
se uma técnica de teste encontra problemas, outra técnica encontrará problemas na mesma área.
Testes Unitários
(Q1) Voltados à tecnologia, apoiam a equipe O problema:
isolamento das partes sendo testadas A solução:
projetar para o teste (testabilidade) projetar através dos testes (TDD) dublés de teste
(teste unitário centrado no desenvolvedor)
•Resultado independente da ordem de execução •Independência entre métodos de teste
•A suite executa em alguns segundos
•Todo recurso está sob controle do programador •Não é testada a integração
•Testes na mesma linguagem que o código sob teste •Resultado não sujeito a interpretação
(Guru checks output)
Testar estado X testar interação
Modalidade Estado Interação (comporta mento) comportamento Ferramentas setup play verify setup (record) play (verify) Ciclo da lógica de teste Verifica o estado da classe-alvo depois de exercitar uma funcionalidade Verifica se as interações da classe-alvo com seus colaboradores seguem um roteiro JUnit JUnit + dublês de testeDublês de teste (s. Meszaros)
Papel Dummy (laranja) Fake (brinquedo) Stub (sec. eletrônica) Mock (impostor)Substitui O que ele faz
Define previamente o comportamento esperado das interações da
classe-alvo com o colaborador Está ai apenas para
cumprir tabela
Retorna uma resposta pré-definida
Objeto
Serviço, Objeto Método
Substitui um serviço por uma implementação mais
apropriada para o teste. Registra comportamento para verificação posterior
Método, Objeto Spy (grampo) Variantes Responder, Saboteur Objeto Nice, Strict, Partial
Dublês de teste
Colaboradores: objetos/classes/serviços dos quais o
código sendo testado depende.
Dublês de Teste
== Colaboradores substitutos para efeito de teste •Verificam o comportamento da classe-alvo: teste baseado em interação (mocks, spies)
•Amenizam efeitos da dependência no teste (fakes,
stubs, dummies)
•Injetam falhas a serem detectadas (saboteurs)
Dublês de teste
• Ferramentas genéricas: • Jmock • EasyMock • Mockito • PowerMock • JMockit • Específicas de APIs • Mockrunner • EJBMock • SpringUnit • Fakes• Web containers leves, BDs / ORMs em memória,
Teste de interação: Spy X Mock
Tipo de dublê Spy (grampo) Mock (impostor) Verificação do comportamento Vantagens Depois do teste Antes do teste Especificação do comportamento esperado Depois do teste Durante o teste Simplicidade de especificação / implementaçãoFalhas são detectadas antes (fail-fast) Pilha de execução é
Teste Contínuo
• Testes são executados automaticamente toda vez que o
fonte é alterado
• Infinitest
• JUnitMax (comercial) • Autotest (JRuby)
Testes de Interface Usuário
• Ferramentas: • Selenium • WebDriver Selenium 2 • Canoo WebTest Interaction Design: CubicTestFamília Selenium
****
Selenium Core JavaScript
Browser: IE, Firefox, Safari, ... DOM (X)HTML Selenium RC Client API (Ruby) Selenium RC Server Java Selenium IDE (só Firefox) StoryTest IQ Eclipse IDE CubicTest plugin Selenium RC Client API (Java) Selenium On Rails CubicTest
Teste de regras de negócio
Não passa pela interface usuário Mais rápido
Entendível por especialistas no domínio Ferramenta FitNesse (planilha)
> ferramenta Wiki que pode ser utilizada por analistas de teste e
de negócios
> especificação de requisitos em planilhas
> codificação de fixtures pode ser feita por programadores
> Base para outros tipos de teste (GUI, unitários, banco de dados)
Outras Ferramentas:
FitNesse – fixture
package br.com.globalcode.aceitacao;
import fit.ColumnFixture;
import br.com.globalcode.impostos.RendaNaFonte;
public class ImpostoDeRendaNaFonteFixture extends ColumnFixture{
public double salarioBruto;
public int dependentes;
public double impostoRetido() {
return RendaNaFonte.desconto(salarioBruto); }
public double salarioLiquido() {
return RendaNaFonte.liquido(salarioBruto); }
FitNesse – classe de negócio
package br.com.globalcode.impostos;public class RendaNaFonte {
public static double desconto(double bruto) {
return bruto * 0.2; }
public static double liquido(double bruto) {
return bruto * 0.8; }
DSLs em planilhas FIT
DSL=“domain-specificlanguage”
Linguagens específicas para um determinado
domínio de aplicação. Ex: teste de GUI, seguro
de automóvel
Criadas caso-a-caso, aproveitam o motor do FIT
Podem ser implementadas utilizando fixtures
Behavior Driven Development
Especificação das funcionalidades em prosa.
Sendo um
<role> Eu Quero:
<funcionalidade> Para que:
<benefício>Behavior Driven Development
Detalhamento da funcionalidade:
Dado que:
<precondições> Quando:
<ação> Então:
<verificação>Behavior Driven Development
Ferramentas:
JBehave EasyB (Groovy) Cucumber + JRuby Fitnesse DoFixtureTeste de componentes JavaEE
Fora do container utilizando objetos que
simulam os componentes gerenciados (mock
objects)
Não é necessário executar o servidor de aplicações Não é testada a interação do componente com o
servidor no qual ele será instalado
Dentro do container
são necessárias ferramentas específicas configuração mais complexa
os ambientes são testados num ambiente mais próximo
Cactus - arquitetura
setUp testXYZ tearDown beginXYZ setUp* testXYZ* tearDown* endXYZ (*) no servidorA classe de caso de teste é instanciada duas vezes pelo test runner Os métodos setUp, testX e tearDown executam dentro do container
Container JEE
(Ex: Jetty Web Container)
MeuTestCase <<Servlet>> Proxy MeuTestCase 1b <<new> > 1:beginX 5: endX 2: setUp() 3: testX() 4: tearDown()
Testes difíceis
Banco de dados
Bungee-jump
Pequenas massas de dados com DB Fit
Especificar dados esperados interceptando chamadas
ao banco com Mockrunner JDBC
Geração de massa com Benerator
Web Services
Novas Ferramentas
Build, gestão de dependências
Maven, Ant+Ivy
Integração Contínua
Hudson, Continuum, Twist
Dashboard
Sonar, XRadar Sensores + Mineração
Hackystat Diagnóstico
TestabilityExplorer, Yslow!Novas ferramentas
Análise estática de código
PMD, FindBugs, Checkstyle
Cobertura de testes
Cobertura, JMockit Coverage
Mutantes
Jester
Geração de massa de dados:
Benerator
Desempenho / Carga
Futuro ?
• > comunicação, feedback, aviso rápido • > nuvem como desafio e oportunidade
• serviços especializados para teste de configuração/volume/ desempenho
• profissional de testes como embaixador da qualidade • > uso de linguagens dinâmicas
• ciclos de implantação + curtos / contínuos (Agile operations) • framework XYZ ==> XYZ test. Frameworks sem um ambiente