Como testar a unidade um arquivo jsp?

12

Estou desenvolvendo um aplicativo Java 6 EE e testando meu código jsp com outro com uma versão de teste das chamadas de função e código usado no original, mas parece pouco flexível e impraticável. Existe uma boa maneira de realizar esse tipo de teste?

zamancer
fonte
2
O que você precisa saber dos testes?

Respostas:

15

Se você não leu sobre o MVC (controlador de visualização de modelo), faça isso. Você não deve ter código em um JSP, apenas exiba. A inserção de código no JSP é muito antiga.

Sério, se não houver código no JSP, você não está testando o JSP. Você está testando a ação / fluxo. Então você pode usar HttpUnit ou Selenium . A grande diferença é que o Selenium é testado em um navegador real.

Jeanne Boyarsky
fonte
13

Não acho que exista uma boa maneira de testar JSPs, principalmente porque eles foram desenvolvidos antes do teste de unidade se tornar um foco de desenvolvimento.

Robert Martin escreveu um artigo há vários anos sobre hackear o compilador JSP para que você possa direcionar testes de unidade não baseados em contêiner. Sua idéia foi boa, mas foi interrompida com o próximo grande lançamento do TomCat. Há muita mágica acontecendo.

Não concordo com a idéia "apenas não adicione código e você não precisará testá-lo". Obviamente, você não deve colocar código no JSP. Mas, no entanto, uma interface do usuário complexa geralmente possui lógica de exibição que pode ser testada de maneira lucrativa.

Considere este exemplo:

<c:choose>
  <c:when test="${mydto.showAdminMenu}">
   The admin menu....
  </c:when>
  <c:otherwise>
    Something completely different
  </c:otherwise>
</c:choose>

Esse código já está bem fatorado: a lógica para decidir se mostramos o menu de administração não está na visualização. No entanto, se houvesse uma maneira fácil de realizar JSPs de teste de unidade, poderíamos escrever um teste para mostrar que o comportamento que queremos realmente aparece e nos protegeria de uma alteração na página que acidentalmente tornava visível o menu de administrador quando deveria ser.

portabella
fonte
4

Existe um programa (usado por qualquer servidor de aplicativos que você esteja usando) que compila um arquivo .jsp em um arquivo .java. Por exemplo, a versão sun / oracle jspc .

Depois de ter o .java que seria produzido pela tradução .jsp (você pode considerar usá-lo como parte do processo de compilação - pré-compilando o jsp para obter melhorias de desempenho no primeiro hit), você poderá executar testes nele. zombando da solicitação e verificando a resposta é o que você está esperando.

(edite com exemplo :)

O método principal para isso é o _jspService(HttpServletRequest, HttpServletResponse)método

Um trivial olá mundo jsp:

<html>
    <head>
        <title>Hello world</title>
    </head>
    <body>
        <h1>Hello world</h1>
        Today is: <%= new java.util.Date().toString() %>
    </body>
</html>

(test.jsp localizado em um diretório chamado 'webapp' e também em um diretório 'out'). Quando compilado com o comando, jspc -v -d out -compile -uriroot webapp/ test.jspcoloca em um diretório out um arquivo chamado test_jsp.java. Este arquivo contém (junto com algumas outras configurações):

  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;

    try {
      response.setContentType("text/html");
      pageContext = _jspxFactory.getPageContext(this, request, response,
                null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("<html>\n\t<head>\n\t\t<title>Hello world</title>\n\t</head>\n\t<body>\n\t
\t<h1>Hello world</h1>\n\t\tToday is: ");
      out.print( new java.util.Date().toString() );
      out.write("\n\t</body>\n</html>\n\n");
    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

Nesse momento, é uma verificação para garantir que o JspWriter seja chamado com gravação ou impressão e o conteúdo da chamada seja o que você espera que seja.

Tudo o que disse, em um mundo ideal, não se deve ter lógica dentro do jsp - essa lógica estaria no controlador ou no taglibs que são testados com outras técnicas.


fonte
1
O que haveria no JSP que seria testado / ridicularizado? Definir dados na solicitação / sessão e depois verificar a exibição? Ou será isso se as boas práticas não forem seguidas e houver lógica real no JSP?
Jeanne Boyarsky
@JeanneBoyarsky Atualizado com exemplo jsp e código. Eu não consideraria uma boa prática tentar testar isso com uma junção tradicional - é outro domínio de teste. A profundidade da zombaria pode ser incômoda, dependendo do conjunto de ferramentas (por exemplo, subclassificando o JspWriter, para que se possa testar facilmente o que é enviado a ele).
3

Você também pode considerar o uso de uma estrutura de teste de unidade HTTP como HTTPUnit | http://httpunit.sourceforge.net/ .

Outro ponto importante é separar bem as preocupações do seu aplicativo.

Por exemplo, usando técnicas como TDD (http://en.wikipedia.org/wiki/Test-driven_development), você criará tipos para testabilidade.

Os tipos consumidos no JSP serão testados em testes de unidade específicos. Se isso não for possível, você deve simular a interação usuário -> navegador (novamente, HTTPUnit ou ferramenta similar).

gsscoder
fonte
2
  • tente externalizar o código funcional do servlet para testá-lo fora de um contexto de servlet com testes reais de unidade
  • teste os terminais do servlet com ferramentas como:
    • HTTPUnit
    • HtmlUnit
    • Selênio
    • Cacto
    • JspTest
    • ...
haylem
fonte