J820 Testes de interface Web com HttpUnit Helder da Rocha ([email protected]) argonavis.com.br O que é HttpUnit API Java para comunicação com servidores HTTP Permite que programas construam e enviem requisições, e depois recebam e processem respostas Cria parâmetros de formulários, cria cookies, segue links, interpreta HTML (tabelas, links, etc.) e realiza outras tarefas normalmente feitas por browsers Não é uma ferramenta de testes argonavis.com.br É só um cliente HTTP. Pode ser usado com JUnit para realizar testes em aplicações Web Testes HttpUnit não são testes de unidade São testes de interface (funcionais) ou testes de integração (dependem do servidor) Não testa JavaScript (use JsUnit: jsunit.sourceforge.net) 2 Como instalar e usar Onde encontrar http://httpunit.sourceforge.net Acrescente Tidy.jar e httpunit.jar no classpath da aplicação testada Tidy.jar: monta uma árvore DOM do HTML recebido na resposta (permite também interpretar página como XML) httpunit.jar: classes que implementam o cliente HTTP argonavis.com.br Importe com.meterware.httpunit.* no TestCase Operação básica WebConversation wc = new WebConversation(); WebRequest request = new GetMethodWebRequest("http://xyz.com/t.html"); WebResponse response = wc.getResponse(request); String html = response.getText(); 3 Principais classes da API do HttpUnit argonavis.com.br com.meterware.httpunit.WebConversation Representa uma sessão de cliente Web (usa cookies e permite lidar com requisições e respostas HTTP) com.meterware.httpunit.WebRequest Representa uma requisição. Permite setar parâmetros com.meterware.httpunit.WebResponse Representa uma resposta. A partir deste objeto pode-se obter objetos WebLink, WebTable e WebForm com.meterware.httpunit.WebLink Possui métodos para extrair dados de links de hipertexto com.meterware.httpunit.WebTable Possui métodos para navegar na estrutura de tabelas com.meterware.httpunit.WebForm Possui métodos para analisar a estrutura de formulários 4 WebConversation, WebRequest, WebResponse WebRequest pode ser criado de várias formas. Primeiro é preciso obter uma página. Para isto a melhor solução é usar GetMethodWebRequest WebConversation wc = new WebConversation(); WebRequest request = new GetMethodWebRequest("http://xyz.com/t.html"); WebResponse response = wc.getResponse(request); argonavis.com.br Se não for preciso usar o objeto request (para, por exemplo, acrescentar parâmetros), pode-se utilizar forma mais compacta WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse("http://xyz.com/t.html"); Tendo-se uma página pode-se iniciar novas requisições através de métodos de WebLink e WebForm 5 Testes com HttpUnit Para usar HttpUnit, importe o pacote com.meterware.httpunit no TestCase e use asserções normalmente no código Vários métodos que permitem navegar no HTML retornado apóes uma requisição podem ser usados para extrair dados testáveis da resposta para uso nas asserções. getText() de WebResponse retorna a página inteira. Pode-se fazer asserções verificando a presença de determinados substrings com String.indexOf(): argonavis.com.br assertTrue(resp.getText().indexOf("texto esperado")); getColumnCount(), getRowCount(), getTableCell() e outros métodos de WebTable permitem testar tabelas Métodos de WebForm permitem verificar a existência de objetos de formulário como botões, conteúdo de caixas de texto, etc. WebRequest permite ler cookies criados WebLink permite descobrir a presença de links na página 6 Simulação de cliques em links Uma vez obtida uma página, pode-se selecionar os links que ela contém e clicá-los para obter uma segunda resposta a ser testada argonavis.com.br Links podem ser selecionados através do seu conteúdo através de response.getLinkWith() Se webConversation.getResponse() receber código 404 uma exceção HttpNotFoundException será provocada WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse("http://xyz.com/t.html"); WebLink link = response.getLinkWith("resumo"); WebRequest clickResumo = link.getRequest(); try { WebResponse respResumo = wc.getResponse(clickResumo); } catch (HttpNotFoundException e) { fail("Link quebrado! " + e); } 7 Parâmetros de uma requisição HTTP Parâmetros são pares nome=valor gerados pelo cliente em links e formulários. São concatenados em strings separados por &: nome=Jo%E3o+Grand%E3o&id=agente007&acesso=3 Parâmetros podem ser passados na requisição de duas formas Se o método HTTP for GET, os parâmetros são passados em uma única linha no query string, que estende a URL após um "?" GET /servlet/Teste?id=agente007&acesso=3 HTTP/1.0 argonavis.com.br Se o método HTTP for POST, os parâmetros são passados como um stream no corpo na mensagem (o cabeçalho Content-length, presente em requisições POST informa o tamanho POST /servlet/Teste HTTP/1.0 Content-length: 21 Content-type: x-www-form-urlencoded id=agente007&acesso=3 8 Envio de requisições com parâmetros Parâmetros HTTP podem ser acrescentados em qualquer requisição através do HTTPUnit Podem ser incluídos em um acesso via HttpUnit usando o método setParameter() de WebRequest argonavis.com.br Para testar o resultado de uma requisição que recebeu parâmetro, pode-se usar getText() de WebResponse para obter o HTML WebConversation wc = new WebConversation(); WebRequest request = new GetMethodWebRequest("http://xyz.com/t.html"); request.setParameter("nome", "fulano"); request.setParametro("senha", "F932*xw"); WebResponse response = wc.getResponse(request); String html = response.getText(); assertFalse(html.indexOf("Acesso Negado")); 9 Formulários Há vários métodos para manipular formulários. Pode-se Detectar a presença de objetos de formulários e seu conteúdo Verificar métodos usados, nome do formulários e outros atributos Simular o envio clicando no botão submit e obter a resposta No exemplo abaixo, a página retornada após o envio do formulário deve conter um campo de texto preenchido com o valor do parâmetro definido na requisição argonavis.com.br WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse("http://xyz.com/t.html"); WebForm form = response.getFormWithID("cadastro"); assertEquals("POST", form.getMethod().toUpperCase()); String campoNome = form.getParameterValue("nome"); assertNotNull(campoNome); // se for null, campo não existe form.setParameter("nome", "Fulano"); WebRequest request = form.getRequest("botaoEnviar"); WebResponse response = wc.getResponse(request); assertEquals("Fulano", form.getParameterValue("nome"); 10 Testes de tabelas Há vários métodos para navegar nas células de tabelas argonavis.com.br Use métodos das classes WebTable e TableCell WebConversation wc = new WebConversation(); WebResponse response = wc.getResponse("http://xyz.com/t.html"); WebTable[] tables = response.getTables(); assertNotNull(tables); assertEquals(tables.length, 1); // só há uma tabela WebTable table = tables[0]; int rows = table.getRowCount(); boolean keyDefined = false; for (int i = 0; i < rows; i++) { String key = table.getCellAsText(i, 0); // col 1 String value = table.getCellAsText(i, 1); // col 2 if (key.equals("USER")) { keyDefined = true; assertEquals("JABBERWOCK", value); } } if (!keyDefined) { fail("No key named USER was found!"); } 11 Configuração de proxy Para realizar testes em um Web site remoto quando as máquinas de desenvolvimento estiverem atrás de uma firewall é preciso seter algumas propriedades proxySet=true proxyHost=nomeDoHostOuIP proxyPort=portaDoProxy Podem ser passadas em linha de comando (usando "-D"), através do Ant (<jvmargs>) ou pelo código: argonavis.com.br System.getProperties().put("proxySet", "true"); System.getProperties().put("proxyHost","200.9.2.1"); System.getProperties().put("proxyPort", "3831"); 12 Exercícios 1. Escreva testes para testar a aplicação Web fornecida argonavis.com.br A aplicação recebe parâmetros e grava os dados no contexto. No final retorna uma página HTML Rode a aplicação passando parâmetros diferentes e analise os resultados. Escreva testes com o HttpUnit que capturem todas as situações possíveis (tabelas, links e objetos de formulário esperados) 13 Exercícios com aplicações Web Para compilar aplicações Web é preciso importar os arquivos da Servlet API Pode-se usar o JBoss ou o Tomcat Para usar o JBoss altere os arquivos build.properties argonavis.com.br server.home=c:/jboss-3.2.1/server/default servlet.jar=${server.home}/lib/javax.servlet.jar deploy.dir=${server.home}/deploy No build.xml, é preciso carregar build.properties Use Arquivo necessário apenas na fase de compilação <property file="build.properties" /> 14 Fontes [1] Richard Hightower e Nicholas Lesiecki. Java Tools for eXtreme Programming. Wiley, 2002. Burke & Brian Coyner. Java eXtreme Programming Cookbook. O'Reilly, 2003 argonavis.com.br [2] Eric 15 Curso J820 Produtividade e Qualidade em Java: Ferramentas e Metodologias Revisão 1.1 © 2002, 2003, Helder da Rocha ([email protected]) argonavis.com.br