Google app engine Google应用程序引擎(java)的集成测试
我正在尝试为我的GAE/j应用程序开发一些有效的集成测试。我很熟悉——这些工具对于小型单元测试非常有用。我现在对开发测试实际web请求的集成测试感兴趣。例如,我想测试web.xml是否将servlet和过滤器映射到预期的URL,并测试我的JSP是否生成预期的URL 我的目标是在JVM中建立一个本地开发服务器,我可以对其发出请求。不过,我对其他整合策略持开放态度;如上所述,我只想有效地测试JSP生成和其他请求级功能 我已经设法使用DevAppServerFactory在同一JVM中启动了一个开发服务器。但是,它生成的DevAppServer似乎使用了与主JVM不同的类加载器。这使得测试更具挑战性——我不能使用任何本地unittesting local*TestConfig类来控制此服务器的行为。类似地,我不能通过静态“滚动我自己的”钩子来修改行为,因为我可以在测试工具中变异的静态与DevAppServer看到的静态不同。这使得跳过与当前测试无关的功能(例如,需要登录)、注入失败、注入模拟等变得非常困难。这确实限制了我测试代码的完整性和效率Google app engine Google应用程序引擎(java)的集成测试,google-app-engine,testing,integration-testing,Google App Engine,Testing,Integration Testing,我正在尝试为我的GAE/j应用程序开发一些有效的集成测试。我很熟悉——这些工具对于小型单元测试非常有用。我现在对开发测试实际web请求的集成测试感兴趣。例如,我想测试web.xml是否将servlet和过滤器映射到预期的URL,并测试我的JSP是否生成预期的URL 我的目标是在JVM中建立一个本地开发服务器,我可以对其发出请求。不过,我对其他整合策略持开放态度;如上所述,我只想有效地测试JSP生成和其他请求级功能 我已经设法使用DevAppServerFactory在同一JVM中启动了一个开发服
我发现web上与AppEngine集成测试的文档非常缺乏。我相信以前有人做过这件事……你有什么建议或资源可以分享吗?基本上,你需要做两件事:
我同意这一问题的记录不充分。
我设法编写了一个端到端测试,将服务器作为黑盒启动并向其发送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"));
}
}
package com.project.org;
导入静态org.junit.Assert.assertEquals;
导入java.io.File;
导入java.net.MalformedURLException;
导入java.net.URL;
导入java.util.ArrayList;
导入java.util.List;
导入org.junit.After;
导入org.junit.Before;
导入org.junit.Test;
导入org.junit.runner.RunWith;
导入com.google.appengine.api.urlfetch.HTTPResponse;
导入com.google.appengine.api.urlfetch.URLFetchServiceFactory;
导入com.google.appengine.tools.development.testing.BaseDevAppServerTestConfig;
导入com.google.appengine.tools.development.testing.DevAppServerTest;
导入com.google.appengine.tools.development.testing.DevAppServerTestRunner;
导入com.google.appengine.tools.development.testing.LocalServiceTestHelper;
@RunWith(DevAppServerTestRunner.class)
@DevAppServerTest(HelloWorldTest.TestConfig.class)
公共类HelloWorldTest{
公共类TestConfig扩展了BaseDevAppServerTestConfig{
@重写公共文件getSdkRoot(){
//您可能需要对此进行调整。
返回新文件(“../../appengine-java-sdk-1.9.15”);
}
@重写公共文件getAppDir(){
返回新文件(“war”);
}
@凌驾
公共列表getClasspath(){
//也许有一种更简单的方法可以做到这一点。
List classPath=new ArrayList();
试一试{
字符串分隔符=System.getProperty(“path.separator”);
String[]pathElements=System.getProperty(“java.class.path”).split(分隔符);
for(字符串pathElement:pathElements){
添加(新文件(pathElement.toURI().toul());
}
}
捕获(格式错误){
抛出新的运行时异常(e);
}
返回类路径;
}
}
私有最终LocalServiceTestHelper testHelper;
专用最终字符串端口;
公共HelloWorldTest(){
testHelper=新的LocalServiceTestHelper();
port=System.getProperty(“appengine.devappserver.test.port”);
}
@在public void setUpServer()之前{
testHelper.setUp();
}
@公开作废后拆除(){
testHelper.tearDown();
}
@Test public void testHelloWorld()引发异常{
URL=新URL(“http://localhost:“+端口+”/hello”);
HTTPResponse response=URLFetchServiceFactory.getURLFetchService().fetch(url);
assertEquals(200,response.getResponseCode());
assertEquals(“helloworld!”,新字符串(response.getContent(),“UTF-8”);
}
}
现在我遇到的问题是,如果您有两个这样的测试,每个测试都单独通过,那么您不能在同一个二进制文件中运行它们。 get-Trown第37行的异常: IllegalStateException(“开发应用服务器已在运行。”) 我不知道如何解决这个问题