StrutsTest と Cactus


StrutsTest と Cactus

Struts をテストするためのテスティングフレームワークです。わたしは Cactus とともに Cactus アプローチでテストをおこなっています。

インストール

Cactus

Servlet や JSP、Struts のテストを行うためのテスティングフレームワーク です。WebLogic 8.1 は J2EE 1.3 に対応したアプリケーションサーバです ので 1.3 用の Cactus を用意します。

なお、Tomcat 4.1 も J2EE 1.3 の中で Servlet 2.3/JSP 1.2 に対応した WebContainar なので同じライブラリを使用して問題ありません。

c:\java に展開します。 C:\java\jakarta-cactus-13-1.6.1 に置かれます。

StrutsTestCase

Tomcat 4.1 と WebLogic 8.1 のいずれも Servlet 2.3/JSP 1.2 に対応した WebContainar なので strutstest213-1.2_2.3 を使用できます。 これは strutstest(strutstest のバージョン)-(Struts のバージョン)_(Servlet のバージョン) です。

c:\java に展開します。 C:\java\strutstest に置かれます。このままだとバージョンが分からなくなってしまう ので strutstest213-1.2_2.3 に名前を変更します。

設定

cactus.properties の作成

cactus.properties を WEB-INF/classes におきます。

# Configuration file for Cactus.

# Each project using Cactus need to have such a file put in the client side
# CLASSPATH (Meaning the directory containgin this file should be in the client
# side CLASSPATH, not the file itself of course ... :) )

# Defines the URLs that will be used by Cactus to call it's redirectors
# (Servlet and JSP). You need to specify in these URLs the webapp context
# that you use for your application. In the example below, the context is
# "test".

cactus.contextURL = http://localhost:8080/lab
cactus.servletRedirectorName = ServletRedirector
cactus.enableLogging=true

web.xml への追加

cactus の設定を web.xml に追加します。順番を変えるとちゃんと読まれませんので それぞれのタグを見つけてその後ろに追加してください。

servlet

 <servlet>
   <servlet-name>ServletRedirector</servlet-name>
   <servlet-class>org.apache.cactus.server.ServletTestRedirector</servlet-class>
 </servlet>

servlet-mapping

 <servlet-mapping>
   <servlet-name>ServletRedirector</servlet-name>
   <url-pattern>/ServletRedirector</url-pattern>
 </servlet-mapping>

テストケースの作成

テスト項目の考え方

テスト用クラスはアプリケーションとは別パッケージにしました。 この方がテストクラスを取り除いてデプロイするのが楽だと考えたからです。 ただ、別パッケージだと private のメソットをテストできません。 結局パラメータに入力項目をセットしてエラーが返ってこないことをテストするだけになってしまいました。 これだとテストが甘めですね。

テストメソットの例)

/**
 * 名前の文字数がオーバーしたときのテスト
 */
public void testEntryUpdateOverName() {
    // リクエストに値をセットする
    normalRequest();
    addRequestParameter("name", "123456789012345678901234567890123456789012345678901234567890");

    // アクションを呼び出す
    actionPerform();

    // アクションの戻り値をチェックする
    verifyForward("fail");
       
    // セッションに値が正しく設定されているかチェックする

    // Action エラーチェック
    verifyActionErrors(new String[] {"errors.maxbytes"});
}

DBアクセスについて

さて、DBへの登録がちゃんと行われていることはどうやったらチェックしたらいいので しょうか。いろいろと迷いましたがテスト用の汎用DBアクセスクラスを作成しました。 DBへの登録メソットを呼んだ後で汎用DBアクセスクラスを使用して select した結果と 入力項目を照合しています。汎用DBアクセスクラスがテストが必要になるほど複雑に してどうする!とかいろいろと矛盾はあるのですが。もっとスマートな方法があると おもうのですが思いつかなかったのでしかたありません。いい方法をご存知の方は ご連絡ください。

JavaMail について

JavaMail でメールを送信する処理でメールがちゃんと送れたことをどうやってテスト ケースを書いたらいいのか今もって分かっていません。返り値がエラーなしである ことはともかく、実際にメールは送信してしまうのでテストケースを引き渡して やってもらうと自分宛にメールが大量に届いてしまいます。結局、ダミーのアドレス を用意してそこのメールは定期的に削除するようにしましたがもうすこしスマート にしたいテストケースです。

テストの実行

Eclipse から JUnit のテストケースを実行すると自動的に Cactus が使われます。

AllTests

まとめてテストするために AllTests というクラスを作成しました。このクラスを Eclipse から JUnit のテストケースとして実行するとまとめてテストできて便利 です。まとめてテストするクラスは JUnit の基礎なのでいろいろなサイトに書い てありとおもいますが念のため。

package test;

import junit.framework.Test;
import junit.framework.TestSuite;

/**
 *
 */
public class AllTests {

   public static void main(String[] args) {
       junit.textui.TestRunner.run(AllTests.class);
   }

   public static Test suite() {
       TestSuite suite = new TestSuite("Test for test");
       //$JUnit-BEGIN$
       suite.addTest(new TestSuite(AdminBusinessTest.class));
       suite.addTest(new TestSuite(AdminConfirmActionTest.class));
       suite.addTest(new TestSuite(AdminFindActionTest.class));
       suite.addTest(new TestSuite(AdminInitialActionTest.class));
       suite.addTest(new TestSuite(AdminListActionTest.class));
       suite.addTest(new TestSuite(CourseListTest.class));
       suite.addTest(new TestSuite(DivisionListTest.class));
       suite.addTest(new TestSuite(EntryBusinessTest.class));
       suite.addTest(new TestSuite(EntryConfirmActionTest.class));
       suite.addTest(new TestSuite(EntryFindActionTest.class));
       suite.addTest(new TestSuite(EntryInitialActionTest.class));
       suite.addTest(new TestSuite(EntryUpdateActionTest.class));
       //$JUnit-END$
       return suite;
   }
}

関連リンク



Return to TOP