Introduction소개

이 문서는 테스트 케이스를 어떻게 작성하는 가와 캑터스를 사용하는 방법을 설명하고 있습니다. 테스트 케이스에는 몇가지의 종류가 있습니다 : 서블릿 단위 테스트 작성을 위한 테스트 케이스, 태크라이브러리 단위 테스트들을 작성하기 위한 테스트 케이스 및 필터 단위 테스트들을 작성하기 위한 테스트 케이스가 있습니다. 우리는 먼저 모든 테스트 케이스에 보편적인 원리들에 대해 알아 본 후 각 테스트 케이스만의 독특한 부분들을 상세히 알아보도록 하겠습니다. 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.

우리는 테스트 케이스 작성에 도움이 될만한 것으로 캑터스 배포판의 일부분으로 제공되는 예제들을 살펴보는 것을 강력 추천합니다. 또한, 본질적으로 JUnit 테스트 케이스인 캑터스 테스트 케이스들에도 적용될 수 있는 JUnit 추천 사례(best practices) 역시 참고하시기 바립니다. 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.

General principles일반적인 원리들

테스트 케이스를 작성하기 위해선, 아래에 정의한 단계들을 따라가시기 바랍니다. To write a test case, please follow the steps defined below.

Step 1: Imports첫 번째 단계 : 임포트(import)

여러분의 테스트 클래스에 다음의 임포트(import)들을 포함하셔야 합니다(캑터스가 JUnit 을 테스트를 호출하기위한 클라이언트측 어플리케이션(application) 처럼 사용하기 때문에 junit.framework.* 이 필요합니다). You need to include the following imports in your test class ( junit.framework.* is needed because Cactus uses JUnit as the client side application for calling the tests):

import org.apache.cactus.*;
import junit.framework.*;

Step 2: Extend a Cactus TestCase class or reuse a JUnit TestCase 두 번째 단계 : 캑터스 테스트케이스 클래스를 상속 받거나 JUnit 테스트케이스를 재사용하기

Option A: Extend a Cactus TestCase class 선택사항 A: 캑터스 테스트케이스 클래스 상속받기

우리가 무엇을 테스트 하려는지에 따라, 캑터스 테스트 케이스들을 상속받은 클래스(우리의 테스트 클래스) 를 만들어야 할 필요가 있습니다: We need to create a class (our test class) that extends one of Cactus test cases, depending on what we are testing:

  • ServletTestCase: 서블릿 API 객체들 ( HttpServletRequest, HttpServletResponse, HttpSession, ServletConfig, ServletContext, ...) 을 사용하거나, 서블릿 혹은 서블릿 API 객체 관리 메서드를 가지고 있는 클래스 단위 테스트 코드를 위해 테스트들을 작성할때 이 클래스를 상속 받으십시오. 예를들면, 다음과 같이 합니다 : ServletTestCase: extend this class for writing tests for unit testing code that uses Servlet API objects (HttpServletRequest, HttpServletResponse, HttpSession, ServletConfig, ServletContext, ...), like Servlets or any java classes which have methods that manipulates Servlet API objects. For example:

    public class TestSampleServlet extends ServletTestCase
    {
    

  • JspTestCase: JSP API 객체들 (PageContext, JspWriter, ...)을 사용하거나, 태크라이브러리 혹은 JSP API 객체들을 관리하는 메서드들을 가지고 있는 자바클래스 JspTestCase: extend this class for writing tests for unit testing code that uses JSP API objects (PageContext, JspWriter, ...), like Taglibs or any java classes which have methods that manipulates JSP API objects. For example:

    public class TestSampleTag extends JspTestCase
    {
    

  • FilterTestCase: extend this class for writing tests for unit testing code that uses Filter API objects (FilterChain, FilterConfig, HttpServletRequest, HttpServletResponse, ...), like Filters or any java classes which have methods that manipulates Filter API objects. For example:

    public class TestSampleFilter extends FilterTestCase
    {
    

Option B: reuse a JUnit TestCase

Cactus is able to run pure JUnit TestCase on the server side. This is done by using the ServletTestSuite Test Suite that wraps your existing Test Cases. For example:

public class TestJUnitTestCaseWrapper extends TestCase
{
    public static Test suite()
    {
        ServletTestSuite suite = new ServletTestSuite();
        suite.addTestSuite(TestJUnitTestCaseWrapper.class);
        return suite;
    }

    public void testXXX()
    {
    }
}

Step 3 (optional): setUp() and tearDown() methods

As in JUnit, you can define a setUp() and a tearDown() 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.

As in JUnit, the setUp() and tearDown() methods are optional.

Step 4 (optional): begin() and end() methods

begin(...) and end(...) methods are the client side equivalent of the setUp() and a tearDown() methods (see previous step). They are called on the client side, before and after every test.

The begin() and end() methods are optional.

Step 5: testXXX() methods

As in JUnit, the main method for a test is the testXXX() method. The difference being that these methods are executed in the container with Cactus. Each XXX test case must have a testXXX() method defined.

In your testXXX() methods you will:

  • instantiate the class to test (you can also factor this instance out and define is as a class instance variable),
  • 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 request (of type HttpServletRequest), config (of type ServletConfig for ServletTestCase or of type FilterConfig for FilterTestCase), ... (see the "Testcase Specific Details" Step below),
  • call the method to test,
  • perform JUnit standard asserts (asserts(..), assertEquals(...), fail(...), ...) to verify that the test was successful

For example:

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

Step 6 (optional): beginXXX() methods

For each XXX test case, you can define a corresponding beginXXX() 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 testXXX() by calling the different API of HttpServletRequest (like getQueryString(), getCookies(), getHeader(), ...).

The signature of the begin method is:

public void beginXXX(WebRequest theRequest)
{
  [...]
}

where theRequest is the object (provided by Cactus) that you use to set all the HTTP related parameters.

The full description of all the HTTP related parameters that you can set can be found in the javadoc for the WebRequest interface. You should also check the examples provided as part of the Cactus distribution.

The beginXXX() methods are executed on the client side, prior to executing testXXX() on the server side and thus, do not have access to any of the class variables that represent API objects (their values are null)

Step 7 (optional): endXXX() methods

For each XXX test case, you can define a corresponding endXXX() 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, ...).

For versions of Cactus up to v1.1, the signature of the end method is:

public void endXXX(HttpURLConnection theConnection)
{
  [...]
}

... and some helper methods to extract the response content and cookies were provided in the AssertUtils class (see javadoc).

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 HttpUnit framework. See the HttpUnit tutorial for the end method signatures and a full description.

The endXXX() methods are executed on the client side, after executing testXXX() on the server side and thus, do not have access to any of the class variables that represent API objects (their values are null)

TestCase specific details

Before reading any of the following detailed tutorials, make sure you have read the previous general principles.