目录
Spring4.1新特性——页面自动化测试框架Spring MVC Test HtmlUnit简介
本文其实不应该算作Spring4.1新特性,该测试框架目前是独立于Spring Framework发展的。Spring MVC Test HtmlUnit提供了Spring MVC测试框架、HtmlUnit、 WebDriver、Geb的集成测试,简化页面自动化测试,利用这些技术可以完成无需启动服务器即可进行页面测试、自动化页面/页面流程测试、Javascript测试、Mock Service提高集成测试速度。本文只会带你使用HtmlUnit和WebDriver进入基本的页面自动化测试一览,不会深入。
注:目前不支持JSP页面模板,因为其运行需要web容器支持,请选择如velocity、freemarker等模板引擎。
1、定义控制器
@Controller
public class TestController {
@RequestMapping("/test1")
public String test1(Model model) {
return "test1";
}
@RequestMapping("/test2")
public String test2(@RequestParam Long id, @RequestParam String name, Model model) {
model.addAttribute("id", id);
model.addAttribute("name", name);
return "test2";
}
}
2、页面test1.vm
<!DOCTYPE html>
<html>
<head>
<title></title>
<link href="/static/css/style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/static/js/jquery-1.11.1.min.js"></script>
</head>
<body>
<form id="form" action="/test2" method="post">
<label for="id">id:</label>
<input type="text" id="id" name="id"/><br/>
<label for="name">name:</label>
<input type="text" id="name" name="name"/><br/>
<input type="submit" value="submit"/>
</form>
</body>
</html>
输入id和name会跳转到test2页面
3、页面test2.vm
<!DOCTYPE html>
<html>
<head>
<title></title>
<link href="/static/css/style.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="/static/js/jquery-1.11.1.min.js"></script>
</head>
<body>
<form id="form" method="post">
<label for="id">id:</label>
<input type="text" id="id" name="id" value="${id}"/><br/>
<label for="name">name:</label>
<input type="text" id="name" name="id" value="${name}"/><br/>
<input id="submit-btn" type="submit" value="submit"/>
</form>
<script type="text/javascript">
$("#submit-btn").click(function() {
$(this).closest("form").attr("action", "/submit");
$("#id").val("123");
$("#name").val("zhangsan");
return false;
});
</script>
</body>
</html>
在该页面绑定id和name数据,然后点击submit按钮会重新设置id和name数据。
4、使用HtmlUnit测试
4.1、初始化Web环境
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:spring-mvc.xml")
@WebAppConfiguration(value = "spring4.1-htmlunit/src/main/webapp")
public class MockMvcHtmlUnitHelloWorldTest {
@Autowired
private WebApplicationContext context;
MockMvc mockMvc;
WebClient webClient;
服务端端配置请参考《Spring MVC测试框架详解——服务端测试》。
4.2、创建WebClient
@Before
public void setup() throws Exception {
mockMvc = webAppContextSetup(context).build();
String contextPath = "";
webClient = new WebClient();
webClient.setWebConnection(new MockMvcWebConnection(mockMvc, contextPath));
}
此处需要指定contextPath,如果不指定会把uri路径中的第一个目录作为上下文,如http://localhost/ctx/path,即ctx是上下文,如果不想带上下文需要指定为“”。
获取页面1数据,然后设置form表单数据,其操作方式和Javascript DOM类似:
HtmlPage page1 = webClient.getPage("http://localhost/test1");
HtmlForm form1 = page1.getHtmlElementById("form");
assertEquals("/test2", form1.getAttribute("action"));
page1.getElementById("id").setAttribute("value", "1");
page1.getElementById("name").setAttribute("value", "lisi");
接着提交表单,当前页面会跳转到test2:
HtmlPage page2 = form1.getElementsByAttribute("input", "type", "submit").get(0).click();
assertEquals("http://localhost/test2", page2.getUrl().toString());
assertEquals("1", page2.getElementById("id").getAttribute("value"));
assertEquals("lisi", page2.getElementById("name").getAttribute("value"));
然后断言该页面的数据是否是上个页面提交过来的。
接着点击表单的submit按钮:
HtmlForm form2 = page2.getHtmlElementById("form");
form2.getElementsByAttribute("input", "type", "submit").get(0).click();
assertEquals("123", page2.getElementById("id").getAttribute("value"));
assertEquals("zhangsan", page2.getElementById("name").getAttribute("value"));
点击该按钮后,会重新设置该页面的id和name输入框的数据。
整个测试过程还是比较简单的,当然实际页面要比这个复杂很多。
5、使用WebDriver进行测试
5.1、初始化Web环境
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value = "classpath:spring-mvc.xml")
@WebAppConfiguration(value = "spring4.1-htmlunit/src/main/webapp")
public class MockMvcWebDriverHelloWorldTest {
@Autowired
private WebApplicationContext context;
MockMvc mockMvc;
MockMvcHtmlUnitDriver webDriver;
和使用HtmlUnit类似,就不多介绍了。
5.2、创建MockMvcHtmlUnitDriver
@Before
public void setup() throws Exception {
mockMvc = webAppContextSetup(context).build();
boolean enableJavascript = true;
String contextPath = "";
webDriver = new MockMvcHtmlUnitDriver(mockMvc, enableJavascript);
DirectFieldAccessor accessor = new DirectFieldAccessor(webDriver);
BeanWrapper wrapper = new BeanWrapperImpl(accessor.getPropertyValue("webClient"));
wrapper.setPropertyValue("webConnection", new MockMvcWebConnection(mockMvc, contextPath));
}
此处需要使用反射把WebClient的上下文修改掉,否则必须带着上下文,这是目前它考虑不完善的地方。
最后测试完成后,关闭WebDriver
@After
public void tearDown() {
webDriver.close();
}
首先请求test1页面,然后查找相应的元素并输入数据
webDriver.get("http://localhost/test1");
WebElement form1 = webDriver.findElement(By.id("form"));
webDriver.findElement(By.id("id")).sendKeys("1");
webDriver.findElement(By.id("name")).sendKeys("lisi");
form1.findElement(By.cssSelector("input[type=submit]")).click();
WebDriver支持CSS选择器,在实现负责逻辑时非常有用。
提交表单后,跳转到test2页面
assertEquals("http://localhost/test2", webDriver.getCurrentUrl());
assertEquals("1", webDriver.findElementById("id").getAttribute("value"));
assertEquals("lisi", webDriver.findElementById("name").getAttribute("value"));
接着点击test2页面的submit按钮
webDriver.findElementByCssSelector("#form input[type=submit]").click();
assertEquals("/submit", webDriver.findElementById("form").getAttribute("action"));
assertEquals("123", webDriver.findElementById("id").getAttribute("value"));
assertEquals("zhangsan", webDriver.findElementById("name").getAttribute("value"));
整个测试过程和HtmlUnit类似,不过API更易用。
从目前来看,Spring MVC Test HtmlUnit框架本身只是起到了Spring MVC测试框架和HtmlUnit和WebDriver之间的粘合剂,把它们结合起来,如果没有Spring MVC测试框架的强大,这种融合还是比较麻烦的。
相关文章
http://htmlunit.sourceforge.net/
https://code.google.com/p/selenium/wiki/HtmlUnitDriver(需 翻 墙)
https://github.com/spring-projects/spring-test-htmlunit/blob/master/src/asciidoc/index.adoc
Spring4新特性
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
源码下载
https://github.com/zhangkaitao/spring4-1-showcase/tree/master/spring4.1-htmlunit