11

GAE/j アプリケーションの効果的な統合テストを開発しようとしています。私はhttps://developers.google.com/appengine/docs/java/tools/localunittestingに精通しています。これらのツールは小さな単体テストに最適です。現在、実際の Web リクエストをテストする統合テストの開発に興味があります。たとえば、web.xml がサーブレットとフィルタを期待される URL にマッピングしていることをテストし、JSP が期待どおりに生成されることをテストしたいと考えています。

私の目的は、JVM 内でローカル開発サーバーを立ち上げ、それに対してリクエストを発行できるようにすることでした。ただし、他の統合戦略にもオープンです。上で述べたように、JSP 生成とその他の要求レベルの機能を効果的にテストしたいだけです。

DevAppServerFactory を使用して、同じ JVM で開発サーバーを起動することができました。ただし、これが生成する DevAppServer は、メインの JVM とは別のクラスローダーを使用しているようです。これにより、テストがさらに困難になります。このサーバーの動作を制御するために、ローカルの単体テスト Local*TestConfig クラスを使用することはできません。同様に、テスト ハーネスで変更できる静的は、DevAppServer が見ている静的と同じではないため、静的などを介して動作を変更するための「独自の」フックを作成することはできません。これにより、現在のテストの中心ではない機能 (ログインが必要など) をスキップしたり、失敗を挿入したり、モックを挿入したりすることが困難になります。これにより、コードを完全かつ効率的にテストする方法が実際に制限されます。

App Engine との統合テストに関するドキュメントがウェブ上で非常に不足していることを発見しました。誰かが以前にこれを行ったことがあると思います...共有できるヒントやリソースはありますか?

4

2 に答える 2

2

基本的に、次の 2 つのことを行う必要があります。

  1. 2 つのサーブレット (または何でも) を追加します。これは、テスト中にのみ有効にする必要があり、ヘルパーのセットアップとティアダウンをリモートで呼び出すことができます。
  2. サーブレット エンジンがリクエストを完全にシングル スレッドで処理するようにします。何らかの理由で、Google が提供する Helper クラスは現在のスレッドでのみ有効になるため、これが必要です。
于 2012-09-06T09:59:25.660 に答える
0

この問題が十分に文書化されていないことに同意します。
サーバーをブラック ボックスとして起動し、HTTP 要求を送信するエンド ツー エンドのテストを作成することができました。

それはこのように動作します:

package com.project.org;

import static org.junit.Assert.assertEquals;
import java.io.File;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import com.google.appengine.api.urlfetch.HTTPResponse;
import com.google.appengine.api.urlfetch.URLFetchServiceFactory;
import com.google.appengine.tools.development.testing.BaseDevAppServerTestConfig;
import com.google.appengine.tools.development.testing.DevAppServerTest;
import com.google.appengine.tools.development.testing.DevAppServerTestRunner;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;

@RunWith(DevAppServerTestRunner.class)
@DevAppServerTest(HelloWorldTest.TestConfig.class)
public class HelloWorldTest {

  public class TestConfig extends BaseDevAppServerTestConfig {

    @Override public File getSdkRoot() {
      // You may need to tweak this.
      return new File("../../appengine-java-sdk-1.9.15");
    }

    @Override public File getAppDir() {
      return new File("war");
    }

    @Override
    public List<URL> getClasspath() {
      // There may be an easier way to do this.
      List<URL> classPath = new ArrayList<>();
      try {
        String separator = System.getProperty("path.separator");
        String[] pathElements = System.getProperty("java.class.path").split(separator);
        for (String pathElement : pathElements) {
          classPath.add(new File(pathElement).toURI().toURL());
        }
      }
      catch (MalformedURLException e) {
        throw new RuntimeException(e);
      }
      return classPath;
    }
  }

  private final LocalServiceTestHelper testHelper;
  private final String port;

  public HelloWorldTest() {
    testHelper = new LocalServiceTestHelper();
    port = System.getProperty("appengine.devappserver.test.port");
  }

  @Before public void setUpServer() {
    testHelper.setUp();
  }

  @After public void tearDown() {
    testHelper.tearDown();
  }

  @Test public void testHelloWorld() throws Exception {
    URL url = new URL("http://localhost:" + port + "/hello");
    HTTPResponse response = URLFetchServiceFactory.getURLFetchService().fetch(url);
    assertEquals(200, response.getResponseCode());
    assertEquals("Hello world!", new String(response.getContent(), "UTF-8"));
  }
}

今私が抱えている問題は、これらのテストが 2 つあり、それぞれが個別に合格する場合、それらを同じバイナリで実行できないことです。このファイルの 37 行目の例外がスローされます。

IllegalStateException("Dev Appserver は既に実行されています。")

これを修正する方法がわかりません。

于 2015-04-12T12:21:41.533 に答える