Testes em aplicações JEE: Montando sua infra de testes automatizados
Upcoming SlideShare
Loading in...5
×
 

Testes em aplicações JEE: Montando sua infra de testes automatizados

on

  • 2,058 views

A 4Linux foi uma das patrocinadoras do Just Java 2012 que ocorreu nos dias 18 e 19/05/2012. Além do patrocínio, a equipe 4Linux foi responsável pela apresentação da palestra: Testes em ...

A 4Linux foi uma das patrocinadoras do Just Java 2012 que ocorreu nos dias 18 e 19/05/2012. Além do patrocínio, a equipe 4Linux foi responsável pela apresentação da palestra: Testes em aplicações Java EE: Montando sua infra de testes automatizados.

Statistics

Views

Total Views
2,058
Views on SlideShare
1,900
Embed Views
158

Actions

Likes
2
Downloads
50
Comments
0

2 Embeds 158

http://www.4linux.com.br 157
http://ns2.lpibrasil.com.br 1

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Testes em aplicações JEE: Montando sua infra de testes automatizados Testes em aplicações JEE: Montando sua infra de testes automatizados Presentation Transcript

  •  Experiência em missão crítica de missão crítica Pioneira no ensino de Linux à distância Parceira de treinamento IBM Primeira com LPI no Brasil + de 30.000 alunos satisfeitos Reconhecimento internacional Inovação com Hackerteen e Boteconet www.4linux.com.br 2 / 44
  • Testes em aplicações JEE:Montando sua infra de testes automatizados
  • Agenda● Porque testar?● Escrevendo testes com mais valor● Problemas testando componentes JEE● Como integrar containers aos testes. www.4linux.com.br 4 / 44
  • Porque automatizar testes?● Modinha...● Eficiência dos testes de regressão ● Você pode melhorar/refatorar o sistema com tranquilidade, se estragar você sabe instantaneamente que estragou● Integração contínua pode te tirar do apuro ● Você tem uma espécie de auditoria “vigiando” o funcionamento do seu código, se falhar você saberá exatamente onde e porque falhou www.4linux.com.br 5 / 44
  • Problemas na hora de testar?● Mas te ensinaram como usar em situações do cotidiano?● Até que ponto testar com objetos fake e mocks? Segundo Bill Burke, mocks te dão uma falsa sensação de segurança, pois permitem distorcer os testes para que seu código passe.● Difícil montar ambientes onde os testes podem ser executados● O quanto de esforço é necessário para executar testes em ferramentas de build e IDEs ao mesmo tempo. www.4linux.com.br 6 / 44
  • Problemas em testes decomponentes JEE● Ciclo chato de desenvolvimentoImplementação Deploy Test Implementação● Isolar o que deve ser testado ● Para um componente ser testado, ele dependente de um outro componente ou um serviço oferecidos pelo container. ● Exemplos: – Filas de mensageria – Transacionalidade – Segurança – Data Sources www.4linux.com.br 7 / 44
  • Ciclo chato de desenvolvimentoMas eu utilizo Ant e o Maven para executaros testes pra mim, moleza! www.4linux.com.br 8 / 44
  • Utilizando ferramentas de build● Ant, Maven: ● Vantagem: – Fácil de executar testes: mvn test (unitários) / mvn verify (unitários e integração) – Fácil integração com servidor de integração contínua como Jenkins. ● Desvantagem: – Executa todos os testes de um vez. – (Maven) Os erros são somente mostrados nos relátorios gerados – (Maven) não integra as suas fases de teste com a IDE www.4linux.com.br 9 / 44
  • Vei, na boa! Minha aplicação nem usa EJB www.4linux.com.br 10 / 44
  • Para recursos simples da Web● Sua aplicação não usa EJB, JTA, JMS?● Você não precisa testar em um servidor de aplicações FULL.● Utilize só um container web, mais leve e mais fácil de configurar.● Opções como o Jetty, Tomcat. Ambos possuem versão embutidas, que pode ser adicionada aos testes.● Jetty é dividido em módulos e permite especificar quais deles seram iniciaram com os testes.● Possuem plugins para Maven.● Possuem APIs que podem ser usadas dentro dos testes. www.4linux.com.br 11 / 44
  • Embedded Jetty● Container de servlets leve● Possui uma API para configurar e iniciar uma instância do container. Server server = new Server(8080); Context root = new Context(server,"/agenda",Context.SESSIONS); root.addServlet(new ServletHolder(new ContatoServlet()), "contatos"); server.start(); www.4linux.com.br 12 / 44
  • API do Jetty A API do Jetty permite que você especifique os módulos que são importantes para você, no caso, em seus testes. private static WebAppContext gerandoContextoAplicacao() throws Exception { WebAppContext context = new WebAppContext(); context.setWar(new File(URI_DO_WAR).getAbsolutePath()); context.setContextPath(“/aplicacao-do-jjustjava/”); context.setConfigurations(new Configuration[] { new AnnotationConfiguration(), new JettyWebXmlConfiguration(), new WebInfConfiguration(), new WebXmlConfiguration(), new TagLibConfiguration(), new MetaInfConfiguration(), new PlusConfiguration(), new FragmentConfiguration(), new EnvConfiguration() }); return context; } @BeforeClass public static void inicializar() throws Exception {Mais dependências para utilizar JSPs: server = new Server(SERVER_PORT); ● ant-1.6.5.jar WebAppContext contexto = gerandoContextoAplicacao(); ● core-3.1.1.jar ● jsp-2.1.jar server.setHandler(contexto); ● jsp-api-2.1.jar server.start(); } www.4linux.com.br 13 / 44
  • Tomcat Embedded● Mais fácil de iniciar que o Jetty por todos os módulos já virem configurados para iniciar.// Configura container de servlet embutidoTomcat servidor = new Tomcat();// Aponta o diretorio temporario para que o container necessitaservidor.setBaseDir("target/temp");// Especifica a porta onde irá funcionar <dependency>servidor.setPort(8081); <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId>// Inicia servidor <version>7.0.27</version> <scope>test</scope>servidor.start(); </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <version>7.0.27</version> <scope>test</scope> </dependency> www.4linux.com.br 14 / 44
  • API do Tomcat : Adicionando ConteúdoVocê pode associar um WAR do file system a um contextoutilizando o método addWebappservidor.addWebapp("/carrinho", enderecoDoWar); Adiciona o WAR ao contexto /carrinhoTambém é possível tornar um diretório, o contexto da aplicação, adicionando servlets aoContainer e mapeando-os no contexto.File diretorioWebapp = new File("src/main/webapp");Context contexto = servidor.addWebapp("/", diretorioWebapp.getAbsolutePath());servidor.addServlet("/", "LeilaoServlet", new LeilaoServlet());contexto.addServletMapping("/leilao", "LeilaoServlet"); Mapeando o Servlet adicionado www.4linux.com.br 15 / 44
  • Mas os como eu forneço pacotes com as classes para os containers dentro dos meus testes?www.4linux.com.br 16 / 44
  • JBoss ShrinkWrap● Projeto que ajuda automatizar e personalizar a criação de pacotes Java ● EAR, WAR, JAR ou também qualquer outro Zip. ● A maioria dos container embutidos permitem especificar um pacote para registrado inserido em um contexto. WebArchive warAplicacao = ShrinkWrap.create(WebArchive.class, “livraria.war”) .addClasses(Cliente.class, CartaoCreditoInfo.class) .addPackage(“fourlinux.justjava.store.dao”); .setWebXML(“/src/test/resources/web.xml”); www.4linux.com.br 17 / 44
  • JBoss ShrinkWrap <repository><project> <id>jboss-public-repository-group</id> ... <name>JBoss Public Maven Repository Group</name> <dependencies> <url>https://repository.jboss.org/nexus/content/groups/public/</url> ... </repository> <dependency> <groupId>org.jboss.shrinkwrap</groupId> <artifactId>shrinkwrap-api</artifactId> </dependency> <dependency> <groupId>org.jboss.shrinkwrap</groupId> <artifactId>shrinkwrap-impl-base</artifactId> <scope>test</scope> </dependency>...</dependencies>...</project> www.4linux.com.br 18 / 44
  • Usando o ShrinkWrap // Exportando WAR: WebArchive war = ShrinkWrap.create(WebArchive.class); war.addPackages(true, "fourlinux.justjava"); Adiciona todas as classes do seguinte pacote recursivamente war.as(ZipExporter.class).exportTo(new File(“/target/shrinkwrap/aplicacao.war”)); Cria um arquivo zip para o conteúdo indicado // Embedded Jetty WebAppContext context = new WebAppContext(); context.setWar(new File(uriDoWar).getAbsolutePath());; www.4linux.com.br 19 / 44
  • Usando ShrinkWrap + Maven ● As vezes seu projeto está dividido em submódulos e um componente que está sendo testado depende de um módulo declarado no POM ● Ou você precisa adicionar um driver JDBC no pacote para testar ShrinkWrap ResolverMavenDependencyResolver resolver = DependencyResolvers.use( MavenDependencyResolver.class);MavenDependencyBuilder dominio = resolver.artifact("soujava.justjava:livraria-dominio:1.0");carrinho.addAsLibraries(dominio.resolveAs(GenericArchive.class)); www.4linux.com.br 20 / 44
  • MAS MEU PROJETO POSSUI EJBs,COMO TESTO?www.4linux.com.br 21 / 44
  • Apache OpenEJB● Container EJB● Desde 1999● Como pode ser utilizado nos testes? ● Diferencial: Leve e rápido ● Pode ser iniciado dentro dos testes. ● Suporta as versões 3.1, 3.0, 2.1, 2.0, 1.1 ● Simples configuração e inicialização. ● Simplicica os ciclos de desenvolvimento e teste. www.4linux.com.br 22 / 44
  • Configurando OpenEJB comMaven● É utilizado como uma simples dependência. <project> ... API <dependency> <groupId>org.apache.openejb</groupId> <artifactId>javaee-api</artifactId> <scope>provided</scope> <version>6.0-3-SNAPSHOT</version> </dependency> Container <dependency> <groupId>org.apache.openejb</groupId> <artifactId>openejb-core</artifactId> <scope>test</scope> <version>4.0.0-beta-1</version> </dependency> </project> Preciso de suporte a JPA, o que faço? <dependency> <groupId>org.apache.openejb</groupId> OpenEJB com Hibernate <artifactId>openejb-core-hibernate</artifactId> <version>4.0.0-beta-1</version> <type>pom</type> </dependency> www.4linux.com.br 23 / 44
  • Iniciando container ● O container pode ser iniciado dentro dos testes, seja a cada teste ou em um setup para todos os testes.@Before <= EJB 3.0public void inicializacao() { Properties props = new Properties(); props.put(Context.INITIAL_CONTEXT_FACTORY, "org.apache.openejb.client.LocalInitialContextFactory"); Context context = new InitialContext(props);} >= EJB 3.1@Beforepublic void inicializacao() { EjbContainer container = EjbContainer.createEjbContainer(); Context context = container.getContext();} www.4linux.com.br 24 / 44
  • Testando SessionBeans@Statelesspublic class ServicoPagamento { public void cobrar(double valor, CartaoCreditoInfo ccInfo) { ... }} Provê um JNDI padrão que você pode customizá-lo.@Testpublic class ServiceoPagamentoIT { @Test(expected=IllegalArgumentException.class) public void valorNegativoLancaExcecao() { Context contexto = EjbContainer.createEjbContainer().getContext(); ServicoPagamento sp = (ServicoPagamento) contexto.lookup(“java:global/projeto/ServicoPagamento”); sp.cobrar(-5, ccInfo); }} Utilizando o JNDI para recuperar componentes como session beansO OpenEJB caça sua aplicação por componentes JavaEE que podem ser de sua responsabilidade. www.4linux.com.br 25 / 44
  • Configurando Recursos @Stateless public class OrderProcessor { Configurando recursos como @Resource DataSource, filas, tópicos, DataSource dataSource; fábricas de conexões... ... } public class OrderProcessorIT { @Test public void processOrderAddItensToDatabase() { Properties props = new Properties(); props.put("shopDatabase", "new://Resource?type=DataSource"); props.put("shopDatabase.JdbcDriver", "org.hsqldb.jdbcDriver"); props.put("shopDatabase.JdbcUrl", "jdbc:hsqldb:mem:shopdb"); Context contexto = EjbContainer.createEjbContainer(props).getContext(); OrderProcessor orders = (OrderProcessor) contexto.lookup(“java:global/projeto/OrderProcessor”); } } www.4linux.com.br 26 / 44
  • Ligando o teste no container● Há momentos onde é mais pratico permitir que o teste tenha acesso aos recursos através de injeção de dependência. public class GameContextIT { @PersistenceContext(unitName=”gameunit”) private EntityManager em; @Resource private Queue filaJogadores; Acesso a todos os recursos do Container, como filas, @EJB datasources, ejbs e ao GameController controller; contexto cdi … public SetUp() throws Exception { EJBContainer container = EJBContainer.createEJBContainer(); container.getContext().bind(“inject”, this); } } www.4linux.com.br 27 / 44
  • Mais eu quero testar em um servidor de aplicação completo, inútil!www.4linux.com.br 28 / 44
  • Testando na real comJBoss Arquillian● Facilmente extensível.● Ajuda a diminui o esforço para fazer testes em qualquer tipo de container, seja remoto ou embutido.● Gerencia todo o ciclo de vida do container e da aplicação sendo executada nele.● Com ajuda do ShrinkWrap, permite montar pacotes personalizados para deploy.● Permite executar testes dentro e fora do container. www.4linux.com.br 29 / 44
  • Arquillian + Maven Novamente adicionar repositório Jboss: http://repository.jboss.org/nexus/content/groups/public<dependency> <groupId>org.jboss.arquillian</groupId> <artifactId>arquillian-bom</artifactId> <version>1.0.0.Final</version> Importando dependências <scope>import</scope> do Arquillian <type>pom</type></dependency> Integração com Junit ou TestNG <dependency> <groupId>org.jboss.arquillian.junit</groupId> <artifactId>arquillian-junit-container</artifactId> <version>1.0.0.Final</version> </dependency> Falta a extensão do container... www.4linux.com.br 30 / 44
  • Arquillian + MavenArquillian com Glassfish Extensões para<dependency> ● JBoss <groupId>org.jboss.arquillian.container</groupId> ● Tomcat <artifactId>arquillian-glassfish-embedded-3.1</artifactId> ● Glassfish <version>1.0.0.CR3</version> ● Resin <scope>test</scope></dependency> Extensão para glassfish ● Weld ● OSGI<dependency> <groupId>org.glassfish.main.extras</groupId> ● CloudBees <artifactId>glassfish-embedded-all</artifactId> ● OpenEJB <version>3.1.2</version> ● Jetty <scope>test</scope> ● Google AppEngine</dependency> ● Spring Glassfish Embutido www.4linux.com.br 31 / 44
  • JBoss Arquillian● Do que o Arquillian precisa? ● Os testes devem funcionar com @RunWith(Arquillian.class) ● Pelo menos um método anotado com @Test ● Um método estático que entregue um pacote Java montado pelo ShrinkWrap ● Um container onde ele irá instalar o pacote. www.4linux.com.br 32 / 44
  • Teste com CDI usandoArquillian@RunWith(Arquillian.class)public class GerenciadorReservasTest { @Inject private GerenciadorReservas reservas; @Deployment public static JavaArchive gerandoArquivoDeploy() { JavaArchive arquivo = ShrinkWrap.create(JavaArchive.class); arquivo.addPackages(true, “fourlinux.justjava”); arquivo.addAsManifestResource(EmptyAsset.INSTANCE, "beans.xml"); return arquivo; } @Test public void reservaDeveGerarCobranca() throws Exception { Cabine cabine = new Cabine(“Titanic”, “A12”, Tipo.LUXO, 340.00f); Usuario usuario = new Usuario("gabriel.ozeas1@gmail.com", "Gabriel Ozeas"); Cobranca cobranca = reservas.reservarCabine(new Cabine[]{cabine}, usuario); assertEquals(new Float(340), new Float(cobranca.getValor())); }} www.4linux.com.br 33 / 44
  • Testando em Containers Remotos<dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-arquillian-container-remote</artifactId> <version>7.1.1.Final</version> <scope>test</scope></dependency> Cliente JBoss Remoto<dependency> <groupId>org.jboss.as</groupId> <artifactId>jboss-as-controller-client</artifactId> <version>7.1.1.Final</version> <scope>test</scope></dependency> Utilizando containers remotos e gerenciados, faz com que eles iniciem em outra JVM, ou seja os logs e debug não estão disponiveis na JVM que iniciou os testes. www.4linux.com.br 34 / 44
  • Arquillian como Cliente Teste OUT Container@RunWith(Arquillian.class)public class GerenciadorReservasTest { Deploy no container, mas testa no cliente @Deployment(testable = false) public static JavaArchive gerandoArquivoDeploy() { JavaArchive arquivo = ShrinkWrap.create(JavaArchive.class); arquivo.addPackages(true, “fourlinux.justjava”); arquivo.setWebXML(“src/main/webapp/WEB-INF/web.xml”); return arquivo; } Testando UI com Selenium @Test public void verificandoTotalItensInicial() throws Exception { WebDriver navegador = new HtmlUnitDriver(); navegador.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); navegador.get("http://localhost:8081/leilao"); WebElement body = navegador.findElement(By.tagName("h1")); assertEquals("Histórico do item", body.getText()); }} www.4linux.com.br 35 / 44
  • Misturando In e Out Container@RunWith(Arquillian.class)public class GerenciadorReservasTest { @Inject private GerenciadorReservas reservas; @Deployment public static JavaArchive gerandoArquivoDeploy() { JavaArchive arquivo = ShrinkWrap.create(JavaArchive.class); arquivo.addClasses(...); ... } Teste será executado na JVM do container @Test public void reservaDeveGerarCobranca() throws Exception { …. Cobranca cobranca = reservas.reservarCabine(new Cabine[]{cabine}, usuario); assertEquals(new Float(340), new Float(cobranca.getValor())); } @Test Teste será executado na JVM que inicou os testes @RunAsClient public void verificandoTotalItensInicial() throws Exception { WebDriver navegador = new HtmlUnitDriver(); navegador.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); ... } www.4linux.com.br 36 / 44
  • PLUS: Infinitest● Customizando a IDE: ● Teste continuo com Infinitest – Ajuda a executar os testes dentro do Eclipse automaticamente – Verde, passou, Vermelho Falhou. – Permite criar filtros para escolher quais testes serão sempre executados. – Recomendado para executar em testes de unidade, pois são normalmente executados em millisegundos. Testes que falharam www.4linux.com.br 37 / 44
  • Filtrando testes no Infinitest● O Infinitest permite que você filtre os testes que serão executados continuamente.● Arquivo infinitest.filtersBloqueia todos os testes de integração:.*ITestBloqueia todos os testes de um pacote:org.soujava.justjava..*Bloqueia todos os teste do projeto:.* www.4linux.com.br 38 / 44
  • Emma www.4linux.com.br 39 / 44
  • Emma www.4linux.com.br 40 / 44
  • Cobertura dos Testes www.4linux.com.br 41 / 44
  • Cobertura dos Testes www.4linux.com.br 42 / 44
  • Chegaremos a 100% ???➢ Nem tudo será testado ➢ Ex: Gets e Setters! ➢ Classes sem lógica de negócio / domínio➢ O aumento do esforço para se chegar a 100% pode não valer a pena! www.4linux.com.br 43 / 44
  • O que acontece na realidade?➢ A maioria das empresas estabelece um patamar mínimo aceitável: ➢ Ex. 80% de cobertura (somente um exemplo)!➢ Os testes unitários e a verificação de cobertura são feitos automaticamente; ➢ A verificação de cobertura pode ser configurada para analisar apenas algumas classes ou pacotes ➢ Utilizar patamares diferentes para recusar o build em cada classe ou pacote. www.4linux.com.br 44 / 44