Comment tester un fichier jsp à l'unité?

12

Je développe une application Java 6 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?

zamancer
la source
2
Que devez-vous savoir des tests?

Réponses:

15

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.

Jeanne Boyarsky
la source
13

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é rompue 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 d'administration n'est pas dans la vue. Néanmoins, s'il existait un moyen simple de tester les JSP unitaire, alors nous pourrions é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 admin alors qu'il ne devrait pas ne sois pas.

portabella
la source
4

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 soleil / 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 _jspService(HttpServletRequest, HttpServletResponse)méthode.

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 aussi un répertoire 'out') Une fois compilé avec la commande jspc -v -d out -compile -uriroot webapp/ test.jspplace dans un répertoire out un fichier appelé test_jsp.java. Ce fichier contient (ainsi qu'une bonne partie de la 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.


la source
1
Quels éléments du JSP seraient testés / simulés? Définition des données dans la demande / session puis vérification de l'affichage? Ou est-ce le cas si les bonnes pratiques ne sont pas suivies et qu'il existe une logique réelle dans le JSP?
Jeanne Boyarsky
@JeanneBoyarsky Mis à jour avec un exemple de jsp et de code. Je ne considère pas que ce soit une bonne pratique d'essayer de tester cela avec un junit traditionnel - c'est un autre domaine de test. La profondeur de la moquerie peut être gênante en fonction de l'ensemble d'outils (par exemple sous-classer JspWriter afin que l'on puisse facilement tester ce qui lui est envoyé).
3

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 cela n'est pas possible, vous devez simuler l' interaction utilisateur -> navigateur (encore une fois, HTTPUnit ou un outil similaire).

gsscoder
la source
2
  • essayer d'externaliser le code fonctionnel du servlet pour le tester en dehors d'un contexte de servlet avec de vrais tests unitaires
  • testez les points de terminaison du servlet avec des outils tels que:
    • HTTPUnit
    • HtmlUnit
    • Sélénium
    • Cactus
    • JspTest
    • ...
haylem
la source