• 为Fitnesse-20140630定制RestFixture代码


    摘要:Fitnesse插件RestFixture在最新版Fitnesse输出测试结果为html文本,而非html。本博文记录RestFixture定制代码的过程。

    准备开发环境

    假定你已经正确安装JDK, Eclipse, Ant, Maven,安装步骤可以参见博文:

    http://www.cnblogs.com/fitnessefan/p/3895706.html

    Eclipse中用Git下载 git.oschina.net上的FitnesseKit源代码

    https://git.oschina.net/fitneesefan/FitnesseKit.git

    步骤: 
    Eclipse Menu > Window > Open Perspective > Other… > Git > Clone a Git Repository and add it to this view:

    下载git仓库

    克隆FitnesseKit到D:gitFitnesseKit

    编译并启动Fitneese

    编译Fitneese

    1
    D:gitFitnesseKitfitnesse >ant

    编译RestFixture

    1
    D:gitFitnesseKitRestFixture>mvn clean package

    启动Fitneese

    1
    D:gitFitnesseKitfitnesse >ant run

    打开Fitnesse网站:

    localhost:8001

    添加测试wiki页

    Fitnesse FrontPage页点击Edit按钮:

    编辑FrontPage

    插入代码:

    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:gitFitnesseKitRestFixture argetdependencies*
    !path D:gitFitnesseKitRestFixture argetsmartrics-RestFixture-3.1-SNAPSHOT.jar
    !path D:gitFitnesseKitRestFixtureextraslf4j-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页,

    测试wiki页

    点击Test运行测试:

    在此输入图片描述

    输出测试结果为html文本,而非html

    修改RestFixture代码直到测试结果显示为正常的html

    分析测试结果

    测试结果表格:

    Table:smartrics.rest.fitnesse.fixture.RestFixture http://www.w3school.com.cn
    GET /example/xmle/note.xml 200 Content-Type:&nbsp;text/xml<br/><i><span class='fit_label'>expected</span></i><hr/><br/>Content-Length&nbsp;:&nbsp;209<br/>Content-Type&nbsp;:&nbsp;text/xml<br/>Last-Modified&nbsp;:&nbsp;Mon,&nbsp;29&nbsp;Jul&nbsp;2013&nbsp;17:25:37&nbsp;GMT<br/>Accept-Ranges&nbsp;:&nbsp;bytes<br/>ETag&nbsp;:&nbsp;"344628a4808cce1:28cc"<br/>Server&nbsp;:&nbsp;Microsoft-IIS/6.0<br/>X-Powered-By&nbsp;:&nbsp;ASP.NET<br/>Date&nbsp;:&nbsp;Sun,&nbsp;03&nbsp;Aug&nbsp;2014&nbsp;01:20:44&nbsp;GMT<br/><i><span class='fit_label'>actual</span></i> //body[text()="Don't&nbsp;forget&nbsp;the&nbsp;meeting!"]<br/><i><span class='fit_label'>expected</span></i><hr/><br/>&lt;?xml&nbsp;version="1.0"&nbsp;encoding="ISO-8859-1"?&gt; <br/>&lt;!--&nbsp;&nbsp;Copyright&nbsp;w3school.com.cn&nbsp;--&gt; <br/>&lt;note&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;to&gt;George&lt;/to&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;from&gt;John&lt;/from&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;heading&gt;Reminder&lt;/heading&gt; <br/>&nbsp;&nbsp;&nbsp;&nbsp;&lt;body&gt;Don't&nbsp;forget&nbsp;the&nbsp;meeting!&lt;/body&gt; <br/>&lt;/note&gt;&nbsp; <br/><br/><i><span class='fit_label'>actual</span></i>

    Markdown语法不支持表格,只能从Fitnesse中把html文本直接贴到这里。

    分析上面的表格,发现测试结果对原wiki内容作了替换:

    • 第一行第一列(Table:smartrics.rest.fitnesse.fixture.RestFixture)被设置了绿色背景色
    • 第二行第二列(/example/xmle/note.xml)被替换为<a>标签,能正确显示html。
    • 第二行第四列(Content-Type:…)被替换为html文本,不能正确显示html。

    *好像找到问题的线索了,对比一下第二行第二列为什么正确,而第二行第四列为什么不正确。

    接下去笨办法:在所有文件中查找html字段:

    Eclipse Menu > Search > Search… > File Search

    search对话框

    search结果

    接下去经过痛苦无助的人肉搜索,找到关键代码:

    ashtml

    文件: D:gitFitnesseKitfitnessesrcfitnesse estsystemsslimHtmlTable.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:&nbsp;text/xml<br/><i><span class='fit_label'>expected</span></i><hr/><br/>Content-Length&nbsp;:&nbsp;209<br/>Content-Type&nbsp;:&nbsp;text/xml<br/>Last-Modified&nbsp;:&nbsp;Mon,&nbsp;29&nbsp;Jul&nbsp;2013&nbsp;17:25:37&nbsp;GMT<br/>Accept-Ranges&nbsp;:&nbsp;bytes<br/>ETag&nbsp;:&nbsp;“344628a4808cce1:28cc”<br/>Server&nbsp;:&nbsp;Microsoft-IIS/6.0<br/>X-Powered-By&nbsp;:&nbsp;ASP.NET<br/>Date&nbsp;:&nbsp;Sun,&nbsp;03&nbsp;Aug&nbsp;2014&nbsp;01:20:44&nbsp;GMT<br/><i><span class='fit_label'>actual</span></i>

    显然第二行第四列(Content-Type:…)不能被识别为html。

    接下去,有两条路可走:

    1. 修改Fitnesse中的qualifiesAsHtml函数,直接return true。
    2. 修改RestFixture中测试结果,套一个<span> tag。

    第1条路我试过,编译成功,但是编译后自动单元测试和验收测试时,报了无数个测试结果失败。 
    主要原因是”<"和">“是有关键用处的,看下面Fitnesse验收用例:

    http://fitnesse.org/FitNesse.SuiteAcceptanceTests.SuiteSlimTests.TestComparators

    比较符号

    结果证明第1条路走不同,为了一个Fixture,更改Fitneese语法显然得不尝试。

    接下去走第2条路:修改RestFixture中测试结果,套一个<span> tag

    修改RestFixture代码

    RestFixture实现为一个Slim TableTable,SlimTable的帮助文档在这里: 
    slim tabletable

    接下去在Project RestFixture中搜索"pass:“,很容易定位到:

    D:gitFitnesseKitRestFixturesrcmainjavasmartrics estfitnessefixtureSlimFormatter.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:gitFitnesseKitRestFixture>mvn compile     
    ...
    [INFO] Compiling 1 source file to D:gitFitnesseKitRestFixture argetclasses
    [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 
    编译结果class文件

    mvn compile命令没有生成新的smartrics-RestFixture-3.1-SNAPSHOT.jar

    所以需要修改 http://localhost:8001/RestFixtureInstallTest

    1
    2
    3
    !path D:gitFitnesseKitRestFixture argetsmartrics-RestFixture-3.1-SNAPSHOT.jar
    -->
    !path D:gitFitnesseKitRestFixture argetclasses

    再次运行测试用例 http://localhost:8001/RestFixtureInstallTest:

    测试结果显示正确

    耶!太完美了。

    到此结束了吗?显然没有,接下去要执行 mvn package,打包生成smartrics-RestFixture-3.1-SNAPSHOT.jar。

    修改单元测试代码并打包RestFixture

    执行mvn package命令打包:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    D:gitFitnesseKitRestFixture>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:gitFitnesseKitRestFixturesrc estjavasmartrics estfitnessefixture的第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&nbsp;matching&nbsp;logically&nbsp;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&nbsp;matching&nbsp;logically&nbsp;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个,说明修改正确。

    继续修改另两个失败的测试用例,

    • 执行mvn package,报0个失败,6个错误,BUILD FAILURE。
    • 执行mvn clean package,报0个失败,0个失败,BUILD SUCCESS,smartrics-RestFixture-3.1-SNAPSHOT.jar生成了新版。

    具体的修改内容可以到git中查看对应commit:

    不知道什么原因,反正修改代码后,再次编译RestFixture时总是用mvn clean package就行了。

  • 相关阅读:
    myeclipse的debug模式启动不了,但run模式可以启动
    修改tomcat的端口号
    mybatis报错:Caused by: java.lang.IllegalArgumentException: Caches collection already contains value for com.crm.dao.PaperUserMapper
    mysql报错:java.sql.SQLException: Incorrect string value: 'xE4xB8x80xE6xACxA1...' for column 'excelName' at row 1
    修改tomcat命令黑窗口的名字
    myeclipse无法部署项目的解决
    我说精通字符串,面试官竟然问我 Java 中的 String 有没有长度限制?
    14个Java并发容器,你用过几个?
    6 种微服务 RPC 框架,你知道几个?
    Java中Set与Set<?>到底区别在哪?
  • 原文地址:https://www.cnblogs.com/fitnessefan/p/3895697.html
Copyright © 2020-2023  润新知