Jak przeprowadzić test jednostkowy pliku jsp?

12

Tworzę aplikację Java 6 EE i testuję mój kod jsp z innym za pomocą testowej wersji wywołań funkcji i kodu używanego w oryginalnym, ale wydaje się luźny i niepraktyczny. Czy istnieje dobry sposób na przeprowadzenie tego rodzaju testów?

zamancer
źródło
2
Co musisz wiedzieć z testów?

Odpowiedzi:

15

Jeśli nie czytałeś o MVC (kontroler widoku modelu), zrób to. Nie powinieneś mieć kodu w JSP, po prostu wyświetl. Umieszczenie kodu w JSP to bardzo wczesne lata 1900.

Poważnie, jeśli nie ma kodu w JSP, nie testujesz JSP. Testujesz działanie / przepływ. Następnie możesz użyć HttpUnit lub Selenium . Duża różnica polega na tym, że selen testuje z prawdziwej przeglądarki.

Jeanne Boyarsky
źródło
13

Nie sądzę, aby istniał dobry sposób testowania stron JSP, głównie dlatego, że zostały one opracowane, zanim testy jednostkowe stały się przedmiotem rozwoju.

Robert Martin napisał artykuł kilka lat temu o zhakowaniu kompilatora JSP, abyś mógł kierować testami jednostkowymi bez kontenerów. Jego pomysł był dobry, ale został złamany w następnej wersji głównej TomCat. Po prostu dzieje się za dużo magii.

Nie zgadzam się z pomysłem „po prostu nie dodawaj kodu, a nie musisz go testować”. OCZYWIŚCIE nie powinieneś umieszczać kodu w JSP. Niemniej jednak złożony interfejs użytkownika często ma logikę wyświetlania, która może być z zyskiem testowana jednostkowo.

Rozważ ten przykład:

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

Ten kod jest już dobrze przemyślany: logika decydowania, czy pokażemy menu administratora, nie jest widoczna. Niemniej jednak, gdyby istniał prosty sposób na jednostkowe testowanie stron JSP, moglibyśmy napisać test, aby pokazać, że pożądane zachowanie faktycznie się pojawia, i uchroniłoby nas przed zmianą strony, która przypadkowo spowodowała, że ​​menu administratora było widoczne, gdy nie powinno tak będzie.

portabella
źródło
4

Istnieje program (używany przez dowolny używany serwer aplikacji), który kompiluje plik .jsp w plik .java. Na przykład wersja sun / oracle jspc .

Po uzyskaniu pliku .java, który zostałby wygenerowany przez tłumaczenie .jsp (możesz nawet rozważyć użycie go jako części procesu kompilacji - wstępnej kompilacji pliku jsp w celu poprawy wydajności przy pierwszym trafieniu), możesz następnie uruchomić testy na nim kpiąc z żądania i weryfikując odpowiedź, czego oczekujesz.

(edytuj z przykładem :)

Kluczową metodą tego jest _jspService(HttpServletRequest, HttpServletResponse)metoda.

Trywialny hello world jsp:

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

(test.jsp znajduje się w katalogu o nazwie „webapp”, a także w katalogu „out”) Po kompilacji z poleceniem jspc -v -d out -compile -uriroot webapp/ test.jspumieszcza w katalogu out plik o nazwie test_jsp.java. Ten plik ma w sobie (wraz z nieco inną konfiguracją konfiguracji):

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

W tym momencie sprawdzamy, czy JspWriter jest wywoływany z zapisem lub drukiem, a zawartość wywołania jest zgodna z oczekiwaniami.

To powiedziawszy, w idealnym świecie nie powinno się mieć żadnej logiki w jsp - taka logika byłaby albo w kontrolerze, albo w taglibsach, które byłyby testowane innymi technikami.


źródło
1
Co będzie w JSP, które zostanie przetestowane / wyszydzone? Ustawianie danych w żądaniu / sesji, a następnie sprawdzanie wyświetlacza? A może dzieje się tak, jeśli nie stosuje się dobrych praktyk i istnieje rzeczywista logika w JSP?
Jeanne Boyarsky,
@JeanneBoyarsky Zaktualizowano o przykład jsp i kod. Nie uważałbym za dobrą praktykę testowania tego za pomocą tradycyjnego junita - to kolejna dziedzina testowania. Głębokość wyśmiewania może być niezręczna w zależności od zestawu narzędzi (np. Podklasowanie JspWriter, aby można było łatwo przetestować, co jest do niego wysyłane).
3

Możesz również rozważyć użycie struktury testów jednostkowych HTTP, takich jak HTTPUnit | http://httpunit.sourceforge.net/ .

Inną ważną kwestią jest dokładne oddzielenie problemów związanych z aplikacją.

Np. Używając technik takich jak TDD (http://en.wikipedia.org/wiki/Test-driven_development) zaprojektujesz typy dla testowalności.

Typy zużywane w JSP będą testowane w określonych testach jednostkowych. Jeśli nie jest to możliwe, należy zasymulować interakcję użytkownika -> przeglądarka (ponownie HTTPUnit lub podobne narzędzie).

gsscoder
źródło
2
  • spróbuj uzewnętrznić kod funkcjonalny serwletu, aby przetestować go poza kontekstem serwletu za pomocą rzeczywistych testów jednostkowych
  • przetestuj punkty końcowe serwletu za pomocą narzędzi takich jak:
    • HTTPUnit
    • HtmlUnit
    • Selen
    • Kaktus
    • JspTest
    • ...
Haylem
źródło