企业系统集成点测试策略
作者:网络转载 发布时间:[ 2013/5/20 11:29:10 ] 推荐标签:
再指定用Failsafe插件执行所有集成测试:
<plugin>
<artifactId>maven-failsafe-plugin</artifactId>
<version>2.12</version>
<configuration>
<includes>
<include>**/integration/**/*Test.java</include>
</includes>
</configuration>
<executions>
<execution>
<id>failsafe-integration-tests</id>
<phase>integration-test</phase>
<goals>
<goal>integration-test</goal>
</goals>
</execution>
<execution>
<id>failsafe-verify</id>
<phase>verify</phase>
<goals>
<goal>verify</goal>
</goals>
</execution>
</executions>
</plugin>
这时如果执行“mvn test”,集成测试已经不会运行;如果执行“mvn integration-test”,由于“integration-test”是在“test”之后的一个阶段,因此两组测试都会运行。这样我们可以在持续集成服务器(例如Jenkins)上创建两个不同的构建任务:一个是提交构建,每次有代码修改时执行,其中不运行集成测试;另一个是完整构建,每天定时执行一次,其中运行集成测试。如此,我们便做到了速度与质量兼顾:平时提交时执行的构建足以覆盖我们开发的功能,执行速度飞快,而且不会因为外部服务宕机而失败;每日一次的完整构建覆盖了被集成的外部服务,确保我们足够及时地知晓外部服务是否仍然如我们期望地正常运行。
对已有系统的重构
如果一开始按照前文所述的模式来设计集成点,自然很容易保障系统的可测试性;但如果一开始没有做好设计,没有抽象出“网络端点”的概念,而是把网络访问的逻辑与其他逻辑耦合在一起,自然也难以写出专门针对网络访问的测试,从而使得大量测试会发起真实的网络访问,使构建变得缓慢而不可靠。
下面是一段典型的代码结构,其中杂糅了几种不同的职责:准备请求正文;发起网络请求;处理应答内容。
PostMethod postMethod = getPostMethod(
velocityContext, templateName, soapAction);
new HttpClient().executeMethod(postMethod);
String responseBodyAsString = postMethod.getResponseBodyAsString();
if (responseBodyAsString.contains("faultstring")) {
throw new WmbException();
}
Document document;
try {
LOGGER.info("request:
" + responseBodyAsString);
document = DocumentHelper.parseText(responseBodyAsString);
} catch (Exception e) {
throw new WmbParseException(
e.getMessage() + "
response:
" + responseBodyAsString);
}
return document;
针对每个要集成的服务方法,类似的代码结构都会出现,从而出现了“重复代码”的坏味道。由于准备请求正文、处理应答内容等逻辑各处不同(例如上面的代码使用Velocity来生成请求正文、使用JDOM来解析应答),这里的重复并不那么直观,自动化的代码检视工具(例如Sonar)通常也不能发现。因此第一步的重构是让重复的结构浮现出来。
使用抽取函数(Extract Method)、添加参数(Add Parameter)、删除参数(Remove Parameter)等重构手法,我们可以把上述代码整理成如下形状:
// 1. prepare request body
String requestBody = renderTemplate(velocityContext, templateName);
// 2. execute a post method and get back response body
PostMethod postMethod = getPostMethod(soapAction, requestBody);
new HttpClient().executeMethod(postMethod);
String responseBody = postMethod.getResponseBodyAsString();
if (responseBodyAsString.contains("faultstring")) {
throw new WmbException();
}
// 3. deal with response body
Document document = parseResponse(responseBody);
return document;
这时,第2段代码(使用预先准备好的请求正文执行一个POST请求,并拿回应答正文)的重复变得明显了。《重构》对这种情况做了介绍:
如果两个毫不相关的类出现Duplicated Code,你应该考虑对其中一个使用Extract Class,将重复代码提炼到一个独立类中,然后在另一个类内使用这个新类。但是,重复代码所在的函数也可能的确只应该属于某个类,另一个类只能调用它,抑或这个函数可能属于第三个类,而另两个类应该引用这第三个类。你必须决定这个函数放在哪儿合适,并确保它被安置后不会再在其他任何地方出现。

sales@spasvo.com