Как выполнить модульное тестирование файла JSP?

12

Я занимаюсь разработкой приложения Java 6 EE и тестирую свой jsp-код с помощью другого с тестовой версией вызовов функций и кода, использованных в оригинальной версии, но она кажется свободной и непрактичной. Есть ли хороший способ выполнить такое тестирование?

zamancer
источник
2
Что нужно знать из тестов?

Ответы:

15

Если вы еще не читали о MVC (контроллере вида модели), сделайте это. Вы не должны иметь код в JSP, просто отображать. Помещение кода в JSP очень 1900-х годов.

Если серьезно, если в JSP нет кода, вы не тестируете JSP. Вы тестируете действие / поток. Тогда вы можете использовать HttpUnit или Selenium . Большая разница в том, что Selenium тестирует из реального браузера.

Жанна Боярская
источник
13

Я не думаю, что есть хороший способ тестирования JSP, в основном потому, что они были разработаны до того, как модульное тестирование стало центром разработки.

Несколько лет назад Роберт Мартин написал статью о взломе JSP-компилятора, чтобы вы могли направлять неконтейнерные модульные тесты. Его идея была хороша, но она была нарушена в следующем выпуске TomCat. Просто слишком много волшебства происходит.

Я не согласен с идеей «просто не добавляйте код, и вам не нужно будет его проверять». Ясно, что вы не должны помещать код в JSP. Но, тем не менее, сложный пользовательский интерфейс часто будет иметь логику отображения, которая может быть выгодно протестирована.

Рассмотрим этот пример:

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

Этот код уже хорошо продуман: логика принятия решения о том, показывать ли нам меню администратора, отсутствует в представлении. Тем не менее, если бы существовал простой способ для модульного тестирования JSP, то мы могли бы написать тест, чтобы показать, что поведение, которое мы хотим, действительно появляется, и это защитило бы нас от изменения страницы, которое случайно сделало меню администратора видимым, когда оно должно не быть.

Portabella
источник
4

Существует программа (используемая любым используемым сервером приложений), которая компилирует файл .jsp в файл .java. Например, версия Sun / Oracle JSPC .

Если у вас есть файл .java, который будет создан преобразованием .jsp (вы можете даже захотеть использовать его как часть процесса сборки - предварительной компиляции jsp для повышения производительности при первом попадании), вы можете запустить тесты для него высмеивая запрос и проверяя ответ - это то, что вы ожидаете.

(редактировать с примером :)

Ключевым методом для этого является _jspService(HttpServletRequest, HttpServletResponse)метод.

Тривиальный привет мир JSP:

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

(test.jsp находится в каталоге с именем «webapp», а также в каталоге «out»). При компиляции с командой jspc -v -d out -compile -uriroot webapp/ test.jspпомещает в каталог «out» файл с именем test_jsp.java. Этот файл имеет внутри него (наряду с некоторыми другими настройками конфигурации):

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

На данный момент, это проверка, чтобы убедиться, что JspWriter вызывается с записью или печатью, и содержимое вызова соответствует ожидаемому.

Все это говорит о том, что в идеальном мире в jsp не должно быть никакой логики - такая логика была бы либо в контроллере, либо в taglibs, которые тестируются другими методами.


источник
1
Что будет в JSP, которое будет протестировано / смоделировано? Задать данные в запросе / сеансе, а затем проверить дисплей? Или это если хорошая практика не соблюдается и в JSP присутствует реальная логика?
Жанна Боярская
@JeanneBoyarsky Обновлено с примером JSP и кода. Я не считаю хорошей практикой пытаться протестировать это с традиционным джунтом - это еще одна сфера тестирования. Глубина насмешек может быть неудобной в зависимости от набора инструментов (например, создание подкласса JspWriter, чтобы можно было легко проверить, что ему отправлено).
3

Вы также можете рассмотреть возможность использования механизма модульного тестирования HTTP, например HTTPUnit | http://httpunit.sourceforge.net/ .

Другим важным моментом является четкое разделение проблем вашего приложения.

Например, используя такие методы, как TDD (http://en.wikipedia.org/wiki/Test-driven_development), вы будете разрабатывать типы для тестируемости.

Типы, используемые в JSP, будут тестироваться в специальных модульных тестах. Если это невозможно, вам следует смоделировать взаимодействие пользователя с браузером (опять же, HTTPUnit или аналогичный инструмент).

gsscoder
источник
2
  • попытаться вывести функциональный код сервлета для тестирования его вне контекста сервлета с помощью реальных модульных тестов
  • проверить конечные точки сервлета с помощью таких инструментов, как:
    • HttpUnit
    • HtmlUnit
    • Селен
    • Кактус
    • JspTest
    • ...
haylem
источник