Integration tests for Google App Engine (java)

后端 未结 2 1684
忘掉有多难
忘掉有多难 2021-02-08 05:09

I\'m trying to develop some effective integration tests for my GAE/j application. I\'m familiar with https://developers.google.com/appengine/docs/java/tools/localunittesting --

2条回答
  •  心在旅途
    2021-02-08 06:04

    I agree this issue is poorly documented.
    I managed to write an end-to-end test that starts a server as a black box and sends it HTTP requests.

    It works like this:

    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 getClasspath() {
          // There may be an easier way to do this.
          List 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"));
      }
    }
    

    Now the issue I have is that if you have two of those tests, with each passing individually, you cannot run them in the same binary. The exception on line 37 of this file get thrown:

    IllegalStateException("Dev Appserver is already running.")

    Not sure how to fix this.

提交回复
热议问题