摘要:Fitnesse插件RestFixture在最新版Fitnesse输出测试结果为html文本,而非html。本博文记录RestFixture定制代码的过程。
假定你已经正确安装JDK, Eclipse, Ant, Maven,安装步骤可以参见博文:
http://www.cnblogs.com/fitnessefan/p/3895706.html
https://git.oschina.net/fitneesefan/FitnesseKit.git
步骤:
Eclipse Menu > Window > Open Perspective > Other… > Git > Clone a Git Repository and add it to this view:
克隆FitnesseKit到D:\git\FitnesseKit
编译Fitneese
1
|
D:\git\FitnesseKit\fitnesse >ant
|
编译RestFixture
1
|
D:\git\FitnesseKit\RestFixture>mvn clean
package
|
启动Fitneese
1
|
D:\git\FitnesseKit\fitnesse >ant run
|
打开Fitnesse网站:
Fitnesse FrontPage页点击Edit按钮:
插入代码:
1
2
3
4
5
|
检查RestFixture是否已正确安装
| RestFixtureInstallTest |
百度地图服务API测试集
| BaiduMapApiSuite |
|
点击Save:
上图中可以看到:
附带说明一下Fitnesse的wiki语法:
两个大写字母开头的英文单词(比如HelloWorld)连在一起,称为WikiWord,直接指向链接:http://localhost:8001/HelloWorld,如果该wiki页存在,就指向它,否则显示为一个”?“,并指向创建改wiki页的链接。
点击 RestFixtureInstallTest的链接,看到:
Edit后看到wiki文本为:
1
2
3
4
5
6
7
8
9
10
|
!define TEST_SYSTEM {slim}
!path D:\git\FitnesseKit\RestFixture\target\dependencies\*
!path D:\git\FitnesseKit\RestFixture\target\smartrics-RestFixture-
3.1
-SNAPSHOT.jar
!path D:\git\FitnesseKit\RestFixture\extra\slf4j-simple-
1.6
.
6
.jar
| Table:smartrics.rest.fitnesse.fixture.RestFixture | http:
//www.w3school.com.cn |
| GET | /example/xmle/note.xml |
200
| Content-Type: text/xml |
//body[text()="Don't forget the meeting!"]|
|
点击Cancel,回到wiki页,
点击Test运行测试:
输出测试结果为html文本,而非html
测试结果表格:
Table:smartrics.rest.fitnesse.fixture.RestFixture | http://www.w3school.com.cn | |||
GET | /example/xmle/note.xml | 200 | Content-Type: text/xml<br/><i><span class='fit_label'>expected</span></i><hr/><br/>Content-Length : 209<br/>Content-Type : text/xml<br/>Last-Modified : Mon, 29 Jul 2013 17:25:37 GMT<br/>Accept-Ranges : bytes<br/>ETag : "344628a4808cce1:28cc"<br/>Server : Microsoft-IIS/6.0<br/>X-Powered-By : ASP.NET<br/>Date : Sun, 03 Aug 2014 01:20:44 GMT<br/><i><span class='fit_label'>actual</span></i> | //body[text()="Don't forget the meeting!"]<br/><i><span class='fit_label'>expected</span></i><hr/><br/><?xml version="1.0" encoding="ISO-8859-1"?> <br/><!-- Copyright w3school.com.cn --> <br/><note> <br/> <to>George</to> <br/> <from>John</from> <br/> <heading>Reminder</heading> <br/> <body>Don't forget the meeting!</body> <br/></note> <br/><br/><i><span class='fit_label'>actual</span></i> |
Markdown语法不支持表格,只能从Fitnesse中把html文本直接贴到这里。
分析上面的表格,发现测试结果对原wiki内容作了替换:
*好像找到问题的线索了,对比一下第二行第二列为什么正确,而第二行第四列为什么不正确。
接下去笨办法:在所有文件中查找html字段:
Eclipse Menu > Search > Search… > File Search
接下去经过痛苦无助的人肉搜索,找到关键代码:
文件: D:\git\FitnesseKit\fitnesse\src\fitnesse\testsystems\slim\HtmlTable.java
1
2
3
4
|
static
boolean
qualifiesAsHtml(String text) {
// performance improvement: First check 1st character.
return
text.startsWith(
"<"
) && HTML_PATTERN.matcher(text).matches();
}
|
函数名qualifiesAsHtml意思是可以当做html
函数代码意思是必须以”<“开头且符合HTML_PATTERN定义的html匹配正则表达式
在HTML_PATTERN上按F3键,或者鼠标右键菜单中选择Open Declaration,可以看到HTML_PATTERN的定义:
1
2
3
4
|
private
final
static
Pattern HTML_PATTERN = Pattern.compile(
"^<(p|hr|pre|ul|ol|dl|div|h[1-6]|hgroup|address|"
+
"blockquote|ins|del|object|map||video|audio|figure|table|fieldset|canvas|a|em|strong|small|mark|"
+
"abbr|dfn|i|b|s|u|code|var|samp|kbd|sup|sub|q|cite|span|br|ins|del|img|embed|object|video|audio|label|"
+
"output|datalist|progress|command|canvas|time|meter)([ >].*</\\1>|[^>]*/>)$"
, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
|
再回去看一下,测试结果表格:
第二行第二列(/example/xmle/note.xml)的html文本为:
<a href=“http://www.w3school.com.cn/example/xmle/note.xml”>/example/xmle/note.xml</a>
第二行第四列(Content-Type:…)的html文本为:
Content-Type: text/xml<br/><i><span class='fit_label'>expected</span></i><hr/><br/>Content-Length : 209<br/>Content-Type : text/xml<br/>Last-Modified : Mon, 29 Jul 2013 17:25:37 GMT<br/>Accept-Ranges : bytes<br/>ETag : “344628a4808cce1:28cc”<br/>Server : Microsoft-IIS/6.0<br/>X-Powered-By : ASP.NET<br/>Date : Sun, 03 Aug 2014 01:20:44 GMT<br/><i><span class='fit_label'>actual</span></i>
显然第二行第四列(Content-Type:…)不能被识别为html。
接下去,有两条路可走:
第1条路我试过,编译成功,但是编译后自动单元测试和验收测试时,报了无数个测试结果失败。
主要原因是”<"和">“是有关键用处的,看下面Fitnesse验收用例:
http://fitnesse.org/FitNesse.SuiteAcceptanceTests.SuiteSlimTests.TestComparators
结果证明第1条路走不同,为了一个Fixture,更改Fitneese语法显然得不尝试。
接下去走第2条路:修改RestFixture中测试结果,套一个<span> tag
RestFixture实现为一个Slim TableTable,SlimTable的帮助文档在这里:
接下去在Project RestFixture中搜索"pass:“,很容易定位到:
D:\git\FitnesseKit\RestFixture\src\main\java\smartrics\rest\fitnesse\fixture\SlimFormatter.java
1
|
102
expected.body(
"pass:"
+ Tools.makeContentForRightCell(expected.body(), typeAdapter,
this
, minLenForToggle));
|
给测试结果套上一层<span> tag,把这一行修改为:
1
|
102
expected.body(
"pass:<span>"
+ Tools.makeContentForRightCell(expected.body(), typeAdapter,
this
, minLenForToggle) +
"</span>"
);
|
编译RestFixture:
1
2
3
4
5
6
7
8
9
10
|
D:\git\FitnesseKit\RestFixture>mvn compile
...
[INFO] Compiling
1
source file to D:\git\FitnesseKit\RestFixture\target\classes
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time:
25.678
s
[INFO] Finished at:
2014
-
08
-03T13:
13
:
07
+
08
:
00
[INFO] Final Memory: 18M/64M
[INFO] ------------------------------------------------------------------------
|
编译生成一个新的class文件: SlimFormatter.class
mvn compile命令没有生成新的smartrics-RestFixture-3.1-SNAPSHOT.jar
所以需要修改 http://localhost:8001/RestFixtureInstallTest
1
2
3
|
!path D:\git\FitnesseKit\RestFixture\target\smartrics-RestFixture-
3.1
-SNAPSHOT.jar
-->
!path D:\git\FitnesseKit\RestFixture\target\classes
|
再次运行测试用例 http://localhost:8001/RestFixtureInstallTest:
耶!太完美了。
到此结束了吗?显然没有,接下去要执行 mvn package,打包生成smartrics-RestFixture-3.1-SNAPSHOT.jar。
执行mvn package命令打包:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
D:\git\FitnesseKit\RestFixture>mvn
package
Results :
...
Failed tests: shouldDisplayPassOnCheckIfExpectedAndActualMatch_whenDisplayingActual(smartrics.rest.fitnesse.fixture.SlimFormatterTest): (..)
shouldDisplayPassOnCheckIfExpectedAndActualMatch(smartrics.rest.fitnesse.fixture.SlimFormatterTest): (..)
shouldDisplayXmlDataInActual(smartrics.rest.fitnesse.fixture.SlimFormatterTest): (..)
...
Tests run:
264
, Failures:
3
, Errors:
6
, Skipped:
0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time:
14.866
s
[INFO] Finished at:
2014
-
08
-03T19:
32
:
44
+
08
:
00
[INFO] Final Memory: 18M/133M
[INFO] ------------------------------------------------------------------------
...
|
打包时,执行单元测试时,有3个测试失败。
shouldDisplayPassOnCheckIfExpectedAndActualMatch_whenDisplayingActual函数在文件D:\git\FitnesseKit\RestFixture\src\test\java\smartrics\rest\fitnesse\fixture的第70行:
1
2
3
4
5
6
7
|
public
void
shouldDisplayPassOnCheckIfExpectedAndActualMatch_whenDisplayingActual() {
SlimCell c =
new
SlimCell(
"something matching logically abc123"
);
...
assertThat(
c.body(),
is(equalTo(
"pass:something matching logically abc123<br/><i><span class='fit_label'>expected</span></i><hr/><br/>abc123<br/><i><span class='fit_label'>actual</span></i>"
)));
}
|
按照之前代码的修改,pass:xxx应改成pass:<span>xxx</span>
assertThat语句对应修改为:
1
2
3
|
assertThat(
c.body(),
is(equalTo(
"pass:<span>something matching logically abc123<br/><i><span class='fit_label'>expected</span></i><hr/><br/>abc123<br/><i><span class='fit_label'>actual</span></i></span>"
)));
|
再次执行mvn package,报告失败测试用例数为2个,说明修改正确。
继续修改另两个失败的测试用例,
具体的修改内容可以到git中查看对应commit:
不知道什么原因,反正修改代码后,再次编译RestFixture时总是用mvn clean package就行了。