web-dev-qa-db-fra.com

Comment tester un fichier jsp à l'unité?

Je développe une Java 6 application EE et je teste mon code jsp avec une autre avec une version de test des appels de fonction et du code utilisé dans l'original mais cela semble lâche et peu pratique Existe-t-il un bon moyen de réaliser ce type de test?

12
zamancer

Si vous n'avez pas lu sur MVC (contrôleur de vue du modèle), faites-le. Vous ne devriez pas avoir de code dans une JSP, il suffit de l'afficher. Mettre du code dans JSP est très 1900.

Sérieusement, s'il n'y a pas de code dans la JSP, vous ne testez pas la JSP. Vous testez l'action/le flux. Ensuite, vous pouvez utiliser HttpUnit ou Selenium . La grande différence est que Selenium teste à partir d'un vrai navigateur.

15
Jeanne Boyarsky

Je ne pense pas qu'il existe un bon moyen de tester les JSP, principalement parce qu'ils ont été développés avant que les tests unitaires ne deviennent un axe de développement.

Il y a plusieurs années, Robert Martin a écrit un article sur le piratage du compilateur JSP afin que vous puissiez diriger des tests unitaires non basés sur des conteneurs. Son idée était bonne, mais elle a été brisée avec la toute prochaine version majeure de Tomcat. Il y a tout simplement trop de magie.

Je ne suis pas d'accord avec l'idée "ne pas ajouter de code et vous n'aurez pas besoin de le tester". Évidemment, vous ne devriez pas mettre de code dans le JSP. Mais néanmoins, une interface utilisateur complexe aura souvent une logique d'affichage qui pourrait être testée de manière rentable.

Considérez cet exemple:

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

Ce code est déjà bien pris en compte: la logique pour décider si nous affichons le menu admin n'est pas dans la vue. Néanmoins, s'il existait un moyen facile de tester les JSP unitaire, nous pourrions alors écrire un test pour montrer que le comportement que nous voulons réellement apparaît, et cela nous protégerait d'une modification de la page qui rendrait accidentellement le menu d'administration visible alors qu'il ne devrait pas ne sois pas.

13
portabella

Il existe un programme (utilisé par le serveur d'applications que vous utilisez) qui compile un fichier .jsp en un fichier .Java. Par exemple, la version Sun/Oracle jspc .

Une fois que vous avez le .Java qui serait produit par la traduction .jsp (vous pourriez même envisager de l'utiliser dans le cadre du processus de construction - précompiler le jsp pour améliorer les performances sur le premier hit), vous pouvez ensuite exécuter des tests sur celui-ci en vous moquant de la demande et en vérifiant la réponse, c'est ce que vous attendez.

(modifier avec exemple :)

La méthode clé pour cela est la méthode _jspService(HttpServletRequest, HttpServletResponse).

Un petit monde bonjour jsp:

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

(test.jsp situé dans un répertoire nommé 'webapp' et également un répertoire 'out') Lors de la compilation avec la commande jspc -v -d out -compile -uriroot webapp/ test.jsp place dans un répertoire de sortie un fichier appelé test_jsp.Java. Ce fichier contient (avec un bon nombre d'autres paramètres de configuration):

  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);
    }
  }
}

À ce stade, c'est une vérification pour vous assurer que le JspWriter est appelé avec write ou print et que le contenu de l'appel correspond à ce que vous attendez.

Cela dit, dans un monde idéal, il ne devrait y avoir aucune logique dans le jsp - une telle logique serait soit dans le contrôleur soit dans les balises qui sont testées avec d'autres techniques.

4
user40980

Vous pouvez également envisager d'utiliser un cadre de test unitaire HTTP comme HTTPUnit | http://httpunit.sourceforge.net/ .

Un autre point important est de bien séparer les préoccupations de votre candidature.

Par exemple. en utilisant des techniques comme [~ # ~] tdd [~ # ~] (http://en.wikipedia.org/wiki/Test-driven_development), vous concevrez des types pour la testabilité.

Les types consommés dans JSP seront testés dans des tests unitaires spécifiques. Si ce n'est pas possible, vous devez simuler l'interaction utilisateur -> navigateur (encore une fois, HTTPUnit ou un outil similaire).

3
gsscoder
  • essayez d'externaliser le code fonctionnel du servlet pour le tester extérieur d'un contexte de servlet avec de vrais tests unitaires
  • tester les points de terminaison de servlet avec des outils tels que:
    • HTTPUnit
    • HtmlUnit
    • Sélénium
    • Cactus
    • JspTest
    • ...
2
haylem