<?xml version="1.0" encoding="Shift_JIS"?>

<!DOCTYPE document SYSTEM "./dtd/document-v10.dtd">

<document>
  <header>
    <title>Cactus TestCase の作成/Writing Cactus TestCase</title>
    <authors>
      <person name="Vincent Massol" email="vmassol@apache.org"/>
    </authors>
  </header>

  <body>

    <s1 title="はじめに/Introduction">

      <p>
        This tutorial explains how to write a test case, using Cactus. There
        are several types of test cases : test cases for writing servlet
        unit tests, test cases for writing taglib unit tests and test cases
        for writing filter unit tests. We will first cover the principles
        which are generic to all test cases and then we will dive into
        the details specific to each test case.
      </p>
      <p>
	本チュートリアルでは、Cactus を使ったテストケースの作成法について説明します。
	テストケースには様々なタイプがあります :
	サーブレット単体テストを記述するためのテストケース、
	タグライブラリ単体テストを記述するためのテストケース、
	フィルター単体テストを記述するためのテストケースなどです。
	まず最初に、全てのテストケースにおいて一般的である原理について述べます。
	そして次に、個々のテストケースに特有なことについて詳しく掘り下げていきます。
      </p>
      <ul>
        <li>
          <jump anchor="general_principles">一般的な原則/General principles</jump>
        </li>
        <li>
          <jump anchor="specific_details">個別のTestCaseの詳細/TestCase specific details</jump>
        </li>
      </ul>

      <note>
        In order to help writing test case we highly suggest to have a look
        at the examples provided as part of the Cactus distribution. Also,
        all the best practices for JUnit also applies to Cactus test cases
        as they are in essence JUnit test cases.
      </note>
      <note>
	テストケースの書き方について理解しやすくするために、
	Cactus ディストリビューションの一部として配布されるサンプルに目を通しておく事を強くお勧めします。
	また、最適な JUnit の練習は全て、JUnit テストケースの本質として、
	そのまま Cactus テストケースに適用できます。
      </note>

    </s1>

    <anchor id="general_principles"/>
    <s1 title="一般的な原則/General principles">

      <p>
        To write a test case, please follow the steps defined below.
      </p>
      <p>
	テストケースを記述するには、下に定義した手順に従ってください。
      </p>

      <s2 title="ステップ 1 : インポート/Step 1 : Imports">

        <p>
          You need to include the following imports in your test class (
          <code>junit.framework.*</code> is needed because Cactus uses JUnit
          as the client side application for calling the tests) :
        </p>
        <p>
	  自分のテストクラスに次の import 文を含めなければいけません。
	  (Cactusは、呼び出しテストのためのクライアント側アプリケーションとして
	  JUnit を使っているので、<code>junit.framework.*</code> が必要となります。) : 
        </p>

<source><![CDATA[
import org.apache.cactus.*;
import junit.framework.*;
]]></source>

      </s2>

      <s2 title="ステップ 2 : Cactus TestCase クラスの拡張/Step 2 : Extend a Cactus TestCase class">

        <p>
          Now, we need to create a class (our test class) that extends one of
          Cactus test cases, depending on what we are testing :
        </p>
        <p>
	  さて次に、自分がテストしたい事に応じて、
	  Cactus テストケースの一つを拡張したクラス(自分のテストクラス)を作成しなければなりません。: 
        </p>
        <ul>
          <li>
            <strong><code>ServletTestCase</code></strong> : extend this class
            for writing tests for unit testing code that uses Servlet API
            objects (<code>HttpServletRequest</code>,
            <code>HttpServletResponse</code>, <code>HttpSession</code>,
            <code>ServletConfig</code>, <code>ServletContext</code>, ...),
            like Servlets or any java classes which have methods that
            manipulates Servlet API objects. For example :<br/><br/>
<source><![CDATA[
public class TestSampleServlet extends ServletTestCase
{
]]></source>
            <br/>
          </li>
          <li>
            <strong><code>ServletTestCase</code></strong> : 
	    サーブレットや Servlet API オブジェクトを操作するメソッドを持った
	    java クラスといった、
	    Servlet API オブジェクト
	    (<code>HttpServletRequest</code>,
            <code>HttpServletResponse</code>, <code>HttpSession</code>,
            <code>ServletConfig</code>, <code>ServletContext</code>, ...)
	    を使った単体テストコードを記述するために、このクラスを拡張します。
	    例は次のようになります :<br/><br/>

<source><![CDATA[
public class TestSampleServlet extends ServletTestCase
{
]]></source>
            <br/>
          </li>
          <li>
            <strong><code>JspTestCase</code></strong> : extend this class for
            writing tests for unit testing code that uses JSP API objects
            (<code>PageContext</code>, <code>JspWriter</code>, ...), like
            Taglibs or any java classes which have methods that manipulates
            JSP API objects. For example :<br/><br/>
<source><![CDATA[
public class TestSampleTag extends JspTestCase
{
]]></source>
            <br/>
          </li>
          <li>
            <strong><code>JspTestCase</code></strong> : 
	    タグライブラリや、JSP API オブエクとを操作するメソッドを持つ
	    java クラスのような JSP API オブジェクト
	    (<code>PageContext</code>, <code>JspWriter</code>, ...)
	    を使った単体テストコードを書くために、
	    このクラスを拡張します。
	    例は次の通りです :<br/><br/>
<source><![CDATA[
public class TestSampleTag extends JspTestCase
{
]]></source>
            <br/>
          </li>
          <li>
            <strong><code>FilterTestCase</code></strong> : extend this class
            for writing tests for unit testing code that uses Filter API
            objects (<code>FilterChain</code>, <code>FilterConfig</code>,
            <code>HttpServletRequest</code>, <code>HttpServletResponse</code>,
            ...), like Filters or any java classes which have methods that
            manipulates Filter API objects. For example :<br/><br/>
<source><![CDATA[
public class TestSampleFilter extends FilterTestCase
{
]]></source>
            <br/>
          </li>
          <li>
            <strong><code>FilterTestCase</code></strong> : 
	    フィルターや、Filter API オブジェクトを操作するメソッドを持つ
	    java クラスのような
	    Filter API オブジェクト
	    (<code>FilterChain</code>, <code>FilterConfig</code>,
            <code>HttpServletRequest</code>, <code>HttpServletResponse</code>,
            ...) を使った単体テストコードを書くためには、
	    このクラスを拡張します。例は次の通りです :<br/><br/>
<source><![CDATA[
public class TestSampleFilter extends FilterTestCase
{
]]></source>
            <br/>
          </li>
        </ul>

      </s2>

      <s2 title="ステップ 3 : 標準 JUnit メソッド/Step 3 : Standard JUnit methods">

        <p>
          As in a normal JUnit test case, define the following standard JUnit
          methods :
        </p>
        <p>
	  標準 JUnit テスト−ケースのように、
	  次の標準 JUnit メソッドを定義します : 
        </p>

        <ul>
          <li>
            A constructor with a single parameter (it is the test name),
          </li>
          <li>
	    引数を 1 つ(これはテスト名です)持つコンストラクタ
          </li>
          <li>
            A <code>main()</code> method in which you start a JUnit test
            runner if you want your test to be executable,
          </li>
          <li>
	    自分のテストを実行形式にしたい場合、
	    JUnit test runner を起動する <code>main()</code> メソッド
          </li>
          <li>
            A <code>suite()</code> method to list the tests that should
            be executed by your test class
          </li>
          <li>
	    テストクラスで実行されるべきテストの一覧を得るための
	    <code>suite()</code> メソッド
          </li>
        </ul>
        <p>
          For example :
        </p>
        <p>
          例 :
        </p>

<source><![CDATA[
public TestSampleServlet(String theName)
{
    super(theName);
}

public static void main(String[] theArgs)
{
    junit.swingui.TestRunner.main(new String[] {TestSampleServlet.class.getName()});
}

public static Test suite()
{
    return new TestSuite(TestSampleServlet.class);
}
]]></source>

      </s2>

      <s2 title="ステップ 4 (オプション) : setUp() および tearDown() メソッド/Step 4 (optional) : setUp() and tearDown() methods">

        <p>
          As in JUnit, you can define a <code>setUp()</code> and a
          <code>tearDown()</code> methods. They are executed respectively
          before and after each test case. However, whereas in JUnit they are
          executed on the client side, in Cactus they are executed on the
          server side. It means that you will be able to access the Cactus
          implicit object (these are the objects from the API as described
          in Step 2) within them. In other words, you'll be able to do
          things such as putting a value in the HTTP Session prior to calling
          the test cases, etc.
        </p>
        <p>
	  JUnit のように、<code>setUp()</code> および
	  <code>tearDown()</code> メソッドを定義できます。
	  それらは各々、テストケースの前と後で実行されます。
	  しかしながら、JUnit においては、これらはクライアント側で実行されますが、
	  それに対し、Cactus では、これらはサーバー側で実行されます。
	  暗黙的な Cactus オブジェクト
	  (これらはステップ 2 で述べられている API からのオブジェクトです)
	  の内部へアクセスできることを意味します。
	  言い換えれば、テストケースを呼び出す前に、
	  HTTP セッションにおいて値を設定する、などといった事ができるわけです。
        </p>
        <p>
          As in JUnit, the <code>setUp()</code> and <code>tearDown()</code>
          methods are optional.
        </p>
        <p>
	  JUnit のように、
	  the <code>setUp()</code> および <code>tearDown()</code>
	  メソッドはオプションです。
        </p>

      </s2>

      <s2 title="ステップ 5 : testXXX() メソッド/Step 5 : testXXX() methods">

        <p>
          As in JUnit, the main method for a test is the
          <code>testXXX()</code> method. The difference being that these
          methods are executed in the container with Cactus. Each XXX test
          case must have a <code>testXXX()</code> method defined.
        </p>
        <p>
	  JUnit のように、テストの主要なメソッドは、
	  <code>testXXX()</code> メソッドです。
	  違いは、これらのメソッドはコンテナ上で、
	  Cactus と共に実行されるということです。
	  個々の XXX テストケースに対して、
          <code>testXXX()</code> メソッドが定義されている必要があります。
        </p>
        <p>
          In your <code>testXXX()</code> methods you will :
        </p>
        <p>
          自分の<code>testXXX()</code> メソッドにおいてやらなければいけない事は次の通りです :
        </p>
        <ul>
          <li>
            instantiate the class to test (you can also factor this instance
            out and define is as a class instance variable),
          </li>
          <li>
	    テストするためにクラスをインスタンス化します。
	    (このインスタンスを要素に分け、クラスインスタンス変数として定義できます。)
          </li>
          <li>
            setup any server-side domain object (like putting a variable in
            the Http session, ...). Indeed, the Cactus test case class that
            you have extended in Step 2 has several instance variables (they
            are the different API objects mentioned in Step 2) that it has
            initialised with valid objects. Depending on the test case class
            that you have extended these variables are <code>request</code>
            (of type <code>HttpServletRequest</code>),
            <code>config</code> (of type <code>ServletConfig</code> for
            <code>ServletTestCase</code> or of type <code>FilterConfig</code>
            for <code>FilterTestCase</code>), ... (see Step 8 below),
          </li>
          <li>
	    サーバー側ドメインオブジェクトを設定します。
	    (HTTP セッションで変数を設定するなど、、、)
	    実際に、ステップ 2 で拡張した Cactus テストケースクラスは、
	    有効なオブジェクトで初期化された幾つかのインスタンス変数を持っています。
	    (これらはステップ 2 で述べる異なる API オブジェクトです。)
	    拡張したテストケースクラスに依存して、
	    これらの変数は、
	    (<code>HttpServletRequest</code>型の)
	    <code>request</code>、
	　  (<code>ServletTestCase</code>のための
	    <code>ServletTestCase</code>型、あるいは、
	    <code>FilterTestCase</code>のための
	    <code>FilterConfig</code>型の)
	    <code>config</code> という変数です。
	    (下のステップ 8 を参照してください)
          </li>
          <li>
            call the method to test,
          </li>
          <li>
            テスト実行のために、メソッドを呼びだします
          </li>
          <li>
            perform JUnit standard asserts (<code>asserts(..)</code>,
            <code>assertEquals(...)</code>, <code>fail(...)</code>, ...) to
            verify that the test was successful
          </li>
          <li>
	    テストが成功したか確認するために、
	    JUnit の標準のアサーション
	    (<code>asserts(..)</code>,
            <code>assertEquals(...)</code>, <code>fail(...)</code>, ...)
	    を実行します。
          </li>
        </ul>
        <p>
          For Example :
        </p>
        <p>
          例 :
        </p>

<source><![CDATA[
public void testXXX()
{
    // Initialize class to test
    SampleServlet servlet = new SampleServlet();

    // Set a variable in session as the doSomething() method that we are testing need
    // this variable to be present in the session (for example)
    session.setAttribute("name", "value");

    // Call the method to test, passing an HttpServletRequest object (for example)
    String result = servlet.doSomething(request);

    // Perform verification that test was successful
    assertEquals("something", result);
    assertEquals("otherValue", session.getAttribute("otherName"));
}
]]></source>

<source><![CDATA[
public void testXXX()
{
    // テスト実行のためのクラスの初期化
    SampleServlet servlet = new SampleServlet();

    // (例えば)テストしようとしている doSomething() メソッドが
    // この変数がセッション中に存在する必要があるので、
    // セッション中で、変数を設定します。
    session.setAttribute("name", "value");

    // (例えば)HttpServletRequest オブジェクトを渡して、
    // テスト実行のためにメソッドを呼び出します
    String result = servlet.doSomething(request);

    // テストが成功したか検証します
    assertEquals("something", result);
    assertEquals("otherValue", session.getAttribute("otherName"));
}
]]></source>

      </s2>

      <s2 title="ステップ 6 (オプション) : beginXXX() メソッド/Step 6 (optional) : beginXXX() methods">

        <p>
          For each XXX test case, you can define a corresponding
          <code>beginXXX()</code> method (optional). You will use it to
          initialize HTTP related parameters (HTTP parameters, cookies,
          HTTP headers, URL to simulate, ...). You will be able to retrieve
          these values in your <code>testXXX()</code> by calling the different
          API of <code>HttpServletRequest</code> (like
          <code>getQueryString()</code>, <code>getCookies()</code>,
          <code>getHeader()</code>, ...).
        </p>
        <p>
	  XXX テストケースの各々について、
	  それに相当する<code>beginXXX()</code>メソッドを定義できます。
	  (オプション)
	  これは HTTP に関するパラメータを初期化するのに使われます。
	  (HTTP パラメータ、クッキー、HTTPヘッダ、シミュレーションするURL、など)
	  これらの値は、<code>testXXX()</code> において、
	  <code>HttpServletRequest</code> の異なる API
	  (<code>getQueryString()</code>、<code>getCookies()</code>、
          <code>getHeader()</code>、など)
          を呼び出すことにより、取り出すことができます。
        </p>
        <p>
          The signature of the begin method is :
        </p>
        <p>
          この begin  メソッドの記述は次の通りです :
        </p>

<source><![CDATA[
public void beginXXX(WebRequest theRequest)
{
  [...]
}
]]></source>

        <p>
          where <code>theRequest</code> is the object (provided by Cactus)
          that you use to set all the HTTP related parameters.
        </p>
        <p>
          ここで、
	  <code>theRequest</code> は、
	  HTTPに関連する全てのパラメーターを設定するのに使われる
	  (Cactusにより提供される)オブジェクトです。
        </p>
        <p>
          The full description of all the HTTP related parameters that you can
          set can be found in the javadoc for the <code>WebRequest</code>
          class. You should also check the examples provided as part of the
          Cactus distribution.
        </p>
        <p>
	  開発者が設定できる全てのHTTP関連のパラメータの完全な記述は、
	  <code>WebRequest</code> クラスの javadoc にあります。
	  Cactus ディストリビューションの一部として配布されている例も見てください。
        </p>
        <p>
          The <code>beginXXX()</code> methods are executed on the client
          side, prior to executing <code>testXXX()</code> on the server side
          and thus, do not have access to any of the class variables that
          represent API objects (their values are <code>null</code>)
        </p>
        <p>
	  <code>beginXXX()</code> メソッドは、
	  <code>testXXX()</code> をサーバー側で実行するより前に、
	  クライアント側で実行されます。
	  ですから、API オブジェクトをあらわすどのクラス変数へのアクセスもできません。
	  (それらの値は<code>null</code>です。)
        </p>

      </s2>

      <s2 title="ステップ 7 (オプション) : endXXX() メソッド/Step 7 (optional) : endXXX() methods">

        <p>
          For each XXX test case, you can define a corresponding
          <code>endXXX()</code> method. You will use this method to
          verify the returned HTTP related parameters from your test case
          (like the returned content of the HTTP response, any returned
          cookies, returned HTTP headers, ...).
        </p>
        <p>
	  XXX テストケースの各々について、
	  それに相当する<code>endXXX()</code>メソッドを定義できます。
	  テストケースより返されたHTTPに関連するパラメータ
	  (HTTPレスポンスにより返された内容や、
	  返されたクッキー、返された HTTP ヘッダー、などです)
	  を検証するために、このメソッドを使えます。  
        </p>
        <p>
          For versions of Cactus up to v1.1, the signature of the end
          method is :
        </p>
        <p>
          1.1 までのバージョンの Cactus では、
	  end メソッドは次のように記述されます : 
        </p>

<source><![CDATA[
public void endXXX(HttpURLConnection theConnection)
{
  [...]
}
]]></source>

        <p>
          ... and some helper methods to extract the response content and
          cookies were provided in the <code>AssertUtils</code> class
          (see javadoc).
        </p>
        <p>
	  ... そして、レスポンスの内容やクッキーを取り出すための、
	  ユーティリティーメソッドが、
	  <code>AssertUtils</code> クラスの中で提供されています。
	  (javadoc をご覧ください)
        </p>
        <p>
          However, beginning with Cactus 1.2, this signature has been
          deprecated. There are now 2 possible signatures for the end
          method, depending on whether you need to perform sophisticated
          checks on the content of what is returned or not. For complex
          checking, we have integrated with the
          <link href="http://httpunit.sourceforge.net">HttpUnit</link>
          framework. See the
          <link href="howto_httpunit.html">HttpUnit tutorial</link> for the
          end method signatures and a full description.
        </p>
        <p>
	  しかしながら、Cactus 1.2 から、
	  この記述法は使えなくなりました。
	  返された内容について洗練されたチェックが必要かどうかにより、
	  end メソッドについて 2 つの記述法が可能になりました。
	  複雑なチェックのためには、
	  <link href="http://httpunit.sourceforge.net">HttpUnit</link>
          フレームワークと統合をしました。
	  end メソッドの記述法と完全な説明については、
          <link href="howto_httpunit.html">HttpUnit チュートリアル</link>をご覧ください。
        </p>
        <p>
          The <code>endXXX()</code> methods are executed on the client
          side, after executing <code>testXXX()</code> on the server side
          and thus, do not have access to any of the class variables that
          represent API objects (their values are <code>null</code>)
        </p>
        <p>
 	  <code>endXXX()</code> メソッドは、
	  <code>testXXX()</code> がサーバー側で実行された後で、
	  クライアント側で実行されるので、
	  API オブジェクトを表す全てのクラス変数へのアクセスはできません。
	  (それらの値は<code>null</code>です。)
        </p>

      </s2>

    </s1>

    <anchor id="specific_details"/>
    <s1 title="TestCase に個別の事項の詳細/TestCase specific details">

      <p>
        <strong>Before reading any of the following detailed tutorials,
        make sure you have read the previous general principles.</strong>
      </p>
      <p>
        <strong>次の詳しいチュートリアルを読む前に、
	前述の一般的な原則について読んだことを確認してください。</strong>
      </p>
      <ul>
        <li>
          <link href="howto_testcase_servlet.html">ServletTestCase
          principles</link>,
        </li>
        <li>
          <link href="howto_testcase_servlet.html">ServletTestCase
          の原則</link>
        </li>
        <li>
          <link href="howto_testcase_jsp.html">JspTestCase
          principles</link>,
        </li>
        <li>
          <link href="howto_testcase_jsp.html">JspTestCase
          の原則</link>
        </li>
        <li>
          <link href="howto_testcase_filter.html">FilterTestCase
          principles</link>
        </li>
        <li>
          <link href="howto_testcase_filter.html">FilterTestCase
          の原則</link>
        </li>
      </ul>

    </s1>

  </body>
</document>
