É bem mais complicado testar interfaces web do que classes Java.
Aplicações WEB não permitem verificar facilmente se o conteúdo presente é o esperado. Informações importantes que precisam ser avaliadas encontram-se misturadas com tags HTML.
O layout das aplicações web mudam com frequência.
É preciso construir testes que não precisem ser reescritos toda vez que o layout das páginas mudem.
Alguns problemas que dificultam a criação de testes automáticos para aplicações web:
Resubmissão de um formulário (por exemplo, o usuário submete um pedido de compra, enquanto o servidor ainda está processando a primeira submissão)
Implicações do uso do botão "Voltar" (muitas vezes, objetos perdem seus valores quando mudam de escopo)
Segurança, ataques do tipo DoS (Denial of Service)
Implicações do browser (valores existentes na memória cache do browser sendo usados sem o conhecimento do usuário)
Tanto páginas JSP quanto Servlets são complicadas de testar, pois é necessário um container rodando para poder avaliar suas funcionalidades.
Além disso, páginas JSP são particularmente complicadas de testar, pois elas não existem até que o deployment seja feito dentro do container web.
Aplicações WEB são difíceis de testar pois dependem da comunicação com o container.
Para testar aplicações WEB precisamos fazer:
Veremos aqui três tecnologias:
Nós podemos testar as camadas das classes Java presentes de uma aplicação WEB fora do container utilizando a API JUnit, entretanto faz-se necessário criar mock objects para emular o container.
O projeto ServletUnit provê um mecanismo que permite invocar servlets e outras classes dependentes da API Servlet fora do container.
Permite invocar diretamente métodos e fazer asserções nas suas respostas. Dessa forma, podemos avaliar o valor dos atributos e parâmetros associados com cada requisição.
ServletUnit é parte do framework HttpUnit e pode ser utilizado para testar servlets fora do servlet container. Embora HttpUnit possa ser utilizado para testar servlets e JSPs, ele é mais utilizado para fazer testes de caixa-preta (ex.: testes funcionais) do ponto de vista do browser.
ServletUnit também permite testar métodos individuais.
ServletUnit simula servlet container que prover todas as funcionalidades de servlet container real. Os seguintes passos são necessários para testar um servlet:
Criar um instância da classe ServletRunner. Essa é a classe que simula o container e permite o acesso a objetos do servlet que estejam rodando.
Registrar o(s) servlet(s) que serão testados no contexto simulado pelo ServletRunner.
Criar um ServletUnitClient. Esse cliente permitirá acessar diferentes partes dos servlets registrados.
Criar uma WebRequest que é usado para chamar o servlet.
Recuperar o InvocationContext. O InvocationContext consiste em um objeto que permite acessar os objetos request e response.
Uma vez possuindo o InvocationContext, é possível acessar o servlet e executar seus métodos. Isso permite testar partes do servlets, e não apenas seu resultado como um todo.
Seja o seguinte servlet a ser testado:
public class SimpleServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String user = getUser(request, response);
response.getWriter().print("User that call this servlet is " + user);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
public String getUser(HttpServletRequest request, HttpServletResponse response) {
return((String)request.getAttribute("UserName"));
}
}Seja o teste para o servlet apresentado:
public void testServletGetUser(){
ServletRunner sr = new ServletRunner();
sr.registerServlet("SimpleServlet", SimpleServlet.class.getName());
ServletUnitClient sc = sr.newClient();
WebRequest request = new PostMethodWebRequest("http://localhost/SimpleServlet");
try {
InvocationContext ic = sc.newInvocation(request);
SimpleServlet simpleServlet = (SimpleServlet) ic.getServlet();
HttpServletRequest simpleServletRequest = ic.getRequest();
simpleServletRequest.setAttribute("UserName", "TimmyC");
String userName = simpleServlet.getUser(ic.getRequest(),ic.getResponse());
assertEquals("TimmyC", userName);
}
catch (Exception e){
fail("Error testing getUser exception is " + e);
e.printStackTrace();
}
}
public void testGetTimes() {
ServletRunner sr = new ServletRunner();
sr.registerServlet("TabelaCampeonatoServlet", TabelaCampeonatoServlet.class.getName());
ServletUnitClient sc = sr.newClient();
WebRequest request = new PostMethodWebRequest("http://localhost/TabelaCampeonatoServlet");
try {
InvocationContext ic = sc.newInvocation(request);
TabelaCampeonatoServlet tabelaServlet = (TabelaCampeonatoServlet)ic.getServlet();
Collection times = tabelaServlet.getTimes(ic.getRequest());
assertTrue( times.contains("Flamengo") );
assertTrue( times.contains("Vasco") );
assertEquals( times.size() , 2 );
}
catch (Exception e) {
fail("Error testing TabelaCampeonatoServlet Exception is " + e);
e.printStackTrace();
}
}
public Collection getTimes(HttpServletRequest request) {
Collection times = (Collection)request.getSession().getAttribute("times");
if ( times == null ) {
times = new LinkedList();
times.add("Flamengo");
times.add("Vasco");
request.getSession().setAttribute("times" , times);
}
return(times);
}
public void testGetTimes() {
ServletRunner sr = new ServletRunner();
sr.registerServlet("TabelaCampeonatoServlet", TabelaCampeonatoServlet.class.getName());
ServletUnitClient sc = sr.newClient();
WebRequest request = new PostMethodWebRequest("http://localhost/TabelaCampeonatoServlet");
request.setParameter("time1" , "São Paulo");
request.setParameter("time2" , "Treze");
try {
InvocationContext ic = sc.newInvocation(request);
TabelaCampeonatoServlet tabelaServlet = (TabelaCampeonatoServlet)ic.getServlet();
Collection times = tabelaServlet.getTimes(ic.getRequest());
assertTrue( times.contains("Flamengo") );
assertTrue( times.contains("Vasco") );
assertTrue( times.contains("São Paulo") );
assertTrue( times.contains("Treze") );
assertEquals( times.size() , 4 );
}
catch (Exception e) {
fail("Error testing TabelaCampeonatoServlet Exception is " + e);
e.printStackTrace();
}
}
public Collection getTimes(HttpServletRequest request) {
Collection times = (Collection)request.getSession().getAttribute("times");
if ( times == null ) {
times = new LinkedList();
times.add("Flamengo");
times.add("Vasco");
request.getSession().setAttribute("times" , times);
}
for (int cont = 1; request.getParameter("time" + cont) != null ; cont++) {
times.add( request.getParameter("time" + cont) );
}
return(times);
}
WebConversation wc = new WebConversation();
WebRequest req = new GetMethodWebRequest("http://www.portalwebmobile.com.br/index.asp");
WebResponse resposta = wc.getResponse(req)
WebConversation wc = new WebConversation();
WebResponse resposta = wc.getResponse("http://www.portalwebmobile.com.br/index.asp");
WebConversation wc = new WebConversation();
try {
WebResponse resposta = wc.getResponse("http://127.0.0.1:8080");
WebLink link = resposta.getLinkWith("JSP Examples"); // encontra o link para página Home
link.click(); // invoca o link
WebResponse home = wc.getCurrentPage(); // recupera o conteúdo da reposta após a invocação do link
assertEquals( home.getLinks().length , 133);
} catch (Exception e) {
fail("Error is " + e);
}
public void test() {
WebConversation wc = new WebConversation();
try {
WebResponse resp = wc.getResponse("http://127.0.0.1:8080");
WebTable table = resp.getTables()[0];
assertEquals("rows", 1, table.getRowCount());
assertEquals("columns", 3, table.getColumnCount());
assertEquals("links", 1, table.getTableCell(0, 2).getLinks().length);
} catch (Exception e) {
fail("Error is " + e);
}
Nome | Cor |
morango | vermelho |
pêssego | amarelo |
String[][] cores = resp.getTables()[1].asText();
assertEquals( "Nome", cores[0][0] );
assertEquals( "Cor", cores[0][1] );
assertEquals( "morango", cores[1][0] );
assertEquals( "vermelho", cores[1][1] );
assertEquals( "pêssego", cores[2][0] );
assertEquals( "amarelo", colors[2][1] );
WebForm form = resp.getForms()[0]; // seleciona o primeiro formulário da página
assertEquals("La Cerentolla", form.getParameterValue("Nome"));
assertEquals("Chinêa", form.getParameterValue("Comida"));
assertEquals("Manayunk", form.getParameterValue("Localizacao"));
assertEquals("on", form.getParameterValue("Cartao"));
form.setParameter("Comida", "Italiano"); // seleciona um dos restaurantes permitidos
form.removeParameter("Cartao"); // desmarca a caixa de seleção
form.submit(); // submete o formulário
public class SimpleServlet extends HttpServlet {
public void doGet(HttpServletRequest theRequest, HttpServletResponse theResponse)
throws IOException {
PrintWriter pw = theResponse.getWriter();
theResponse.setContentType("text/html");
pw.print("<html><title>Teste cactus!</title>" +
"<center><h3>Oi Turma!</h3></center>" +
"<body><table align=\"center\"><tr><td>Nome</td><td>" + registerUser(theRequest, theResponse) + "</td></tr></table></body></html>");
}
public String registerUser(HttpServletRequest theRequest, HttpServletResponse theResponse){
String name = theRequest.getParameter("USER_NAME");
theRequest.getSession().setAttribute("NAME", name);
Cookie cookie = new Cookie("ID", name);
theResponse.addCookie(cookie);
return name;
}
}
public class TestSimpleServlet extends ServletTestCase {
public void beginRegisterUser(WebRequest theRequest) {
theRequest.addParameter("USER_NAME", "Vincent");
}
public void testRegisterUser() throws ServletException {
SimpleServlet servlet = new SimpleServlet();
try {
servlet.doGet(request, response);
} catch (IOException e) {
fail("Exception not expected!");
}
String name = servlet.registerUser(request, response);
assertEquals("Vincent", name);
assertEquals("Vincent", (String) session.getAttribute("NAME"));
}
public void endRegisterUser(WebResponse theResponse) {
Cookie cookie = theResponse.getCookie("ID");
assertEquals("Vincent", cookie.getValue());
assertEquals("<html><body><h1>Your name is Vincent</h1></body></html>", theResponse.getText());
}
}
public void endRegisterUser(com.meterware.httpunit.WebResponse theResponse) throws SAXException {
assertEquals("Vincent", theResponse.getNewCookieValue("ID"));
WebTable table = theResponse.getTables()[0];
assertEquals("rows", 1, table.getRowCount());
assertEquals("columns", 2, table.getColumnCount());
assertEquals("value", "Vincent" , table.getTableCell(0, 1).getText());
assertEquals("title", "Teste cactus!" , theResponse.getTitle());
}
-Dcactus.config=c:/cactus.txt
))cactus.contextURL
: contexto no qual a aplicacao se encontra (ex.:
cactus.contextURL = http://localhost:8080/test
)cactus.servletRedirectorName
: default ServletRedirector
cactus.jspRedirectorName
: default JspRedirector
cactus.filterRedirectorName
: default FilterRedirector
Livro Test Driven Development: A J2EE Example; Russell Gold, Thomas Hammell and Tom Snyder ISBN:1590593278 Apress © 2005
Livro J2EE Design and Development
Site http://httpunit.sourceforge.net
Site http://jakarta.apache.org/cactus
Material de Helder Rocha - Testes de integração em J2EE com Jakarta Cactus
Material de Julio Cesar Fernander Correa - Conhecendo o Framework HttpUnit;
Como usar o HttpUnit com o JUnit para testar sua aplicação WEB.