web-dev-qa-db-ja.com

jspファイルを単体テストする方法は?

私はJava 6 EEアプリケーションを開発しており、元のコードで使用されている関数呼び出しとコードのテストバージョンを使用して、別のコードでjspコードをテストしていますが、緩やかで実用的ではないようです。 。この種のテストを実行する良い方法はありますか?

12
zamancer

MVC(モデルビューコントローラー)についてまだ読んでいない場合は、読んでください。 JSPにコードを含めるのではなく、表示するだけです。 JSPにコードを配置するのは非常に1900年代です。

しかし真剣に、JSPにコードがない場合は、JSPをテストしていません。アクション/フローをテストしています。次に、 HttpUnit または Selenium を使用できます。大きな違いは、Seleniumが実際のブラウザーからテストすることです。

15
Jeanne Boyarsky

JSPをテストする良い方法はないと思います。JSPは、ユニットテストが開発の焦点になる前に開発されたためです。

Robert Martinが数年前に、コンテナベースではないユニットテストを指示できるようにJSPコンパイラをハッキングすることについての記事を書きました。彼のアイデアは良かったが、次のTomcatメジャーリリースでうまくいかなかった。あまりにも多くの魔法が起こっています。

「コードを追加しないで、テストする必要がない」という考えには同意しません。もちろん、JSPにコードを配置するべきではありません。しかし、それにもかかわらず、複雑なUIには、多くの場合、ユニットテストで有益な表示ロジックが含まれます。

この例を考えてみましょう:

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

このコードはすでに十分に因数分解されています。管理メニューを表示するかどうかを決定するロジックはビューにありません。それでも、JSPをユニットテストする簡単な方法がある場合は、目的の動作が実際に表示されることを示すテストを作成できます。これにより、管理メニューが誤って表示されたときにページが誤って変更されるのを防ぐことができます。ありません。

13
portabella

.jspファイルを.Javaファイルにコンパイルするプログラム(使用しているアプリケーションサーバーで使用される)が存在します。たとえば、Sun/Oracleバージョン jspc です。

.jsp変換によって生成される.Javaを取得したら(これをビルドプロセスの一部として使用することを検討することもできます-最初のヒットでのパフォーマンス向上のためにjspをプリコンパイルします)、それに対してテストを実行できます。リクエストをモックしてレスポンスを検証することで、期待どおりの結果が得られます。

(例で編集:)

このための重要なメソッドは、_jspService(HttpServletRequest, HttpServletResponse)メソッドです。

ささいなhello world jsp:

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

(「webapp」という名前のディレクトリと「out」ディレクトリ内にあるtest.jsp)コマンドjspc -v -d out -compile -uriroot webapp/ test.jspでコンパイルすると、test_jsp.Javaというファイルがoutディレクトリに配置されます。このファイルはその中にあります(他の構成設定もかなり含まれています)。

  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内にロジックはありません。そのようなロジックは、他の手法でテストされるコントローラーまたはtaglibにあります。

4
user40980

HTTPUnit|のようなHTTPユニットテストフレームワークの使用を検討することもできます。 http://httpunit.sourceforge.net/

もう1つの重要な点は、アプリケーションの懸念を十分に分離することです。

例えば。 [〜#〜] tdd [〜#〜](http://en.wikipedia.org/wiki/Test-driven_development)などの手法を使用し、テストしやすいようにタイプを設計します。

JSP内で使用されるタイプは、特定の単体テストでテストされます。これが不可能な場合は、user-> browserインタラクション(ここでも、HTTPUnitまたは同様のツール)をシミュレートする必要があります。

3
gsscoder
  • サーブレットの機能コードを外部化してテストしますoutside実際のユニットテストでサーブレットコンテキストの
  • 次のようなツールでサーブレットのエンドポイントをテストします。
    • HTTPUnit
    • HtmlUnit
    • セレン
    • カクタス
    • JspTest
    • ...
2
haylem