2016-08-12 102 views
0

作为测试的先决条件,我需要设置大型复杂对象模型,稍后将作为参数发布到特定API以处理它。模型的值是在Fitnesse页面上显示的测试输入数据。如何在Fitnesse SLIM中设置复杂的复合Pojo对象?

这个模型看起来像:

class FinalEntity extends DoFixture{ 
    public String field1; 
    public String field2; 
    // More fields.... 
    public String field20; 
    public ArgumentOneEntity argOne; 
    public List<ArgumentTwoEntity> argTwo; 
    // More fields.... 
    //Getters and setters .... 

} 

class ArgumentOneEntity{ 
    public String field1; 
    public String field2; 
    // More fields.... 
    public List<String> argList = new ArrayList(); 
    public List<String> argList1 = new ArrayList(); 

    //Getters and setters .... 
} 

class ArgumentTwoEntity{ 
    public String field1; 
    public String field2; 
    // More fields.... 
    //Getters and setters .... 
} 

它可以使用表,但它是非常inconvinient。 相契合,有可能做这样的事情:

!define argOne (|field1|value1| 
|field2|value2| 
|setArgList;|arg1,arg2,arg3| 
|setArgList1;|arg4,arg5,arg6| 
) 

!define argTwo (|field1|value1| 
|field2|value2| 
) 

|FinalEntity | 
|setField1;|${argOne}| 
|setField2;|${argTwo}| 

这将解析从变量所需的问题一些神奇的方式表。现在的问题是:如何使它与Slim一起工作?如果这是不可能的,那么在SLIM中构建这样的对象的合理替代方案是什么,而不需要制造任何人都无法理解的大杂乱表格。

选项我虽然约: 1.将测试数据存储在相应JSON对象的文件中,解析它们并显示给Fitnesse页面中的业务用户。我不喜欢它。因为维护这样的测试非常不方便 - 您需要运行测试或使用数据搜索相应的文件。 2.为了同时从slim和fixlibrary中获益,添加SLIM和FIT的依赖关系。这并不奏效 - Fitnesse服务器根本无法启动。 3.使用表 - 这是非常痛苦和难以维护。

您对此问题有任何合理的解决方法吗?

不需要说像更新你的模型这样的东西 - 我不能这样做,或者使用像JBehave这样的其他东西 - 我很喜欢这样做,而且我过去对JBehave有积极的经验,但是在这种情况下我很遗憾并不是那些对技术和方法做出决定的人。

+0

您是否需要填充Java对象,还是只需要获取API的正确请求?你表示你必须发布,你是在谈论一个json,XML或其他的http帖子? –

+0

然后将Java对象作为模型参数传递给API。作为一种可能性,我正在考虑将变量包装为JSON或XML,然后将其作为字符串传递给Java,然后我可以使用Jackson或JAXB来解析它,但它看起来很奇怪 - 太多的转换操作。因此,我想也许有一些我不知道的直接解决方案,因为我不是Fitnesse的专家。 –

回答

0

我建议把重点放在对API的调用上,而不是填充一个并非真正想测试的POJO结构。 POST只不过是在http调用中发送一个字符串,所以要编写一个测试你需要设置正确的字符串发送给API。

您可以通过创建/生成Java客户端来完成此操作,然后从wiki中填充它的(复杂)模型来进行调用,正如您的问题所暗示的那样。 另一种方法(我推荐并创建了generic fixtures to support)是创建一个主体模板来发布和使用wiki来填充该模板中的占位符。那么不需要(API)特定的Java代码,换句话说就是不会有POJO来填充。

该模板既可以完全在wiki中使用Slim场景(如果有一组固定的占位符被填充),也可以在使用模板引擎填充的单独文件中(如果需要更多的灵活性,例如作为可选占位符或可变长度的列表)。在后一种情况下,为模板引擎提供占位符的数据结构只是一个带有键和值的散列/映射(而不是带有getters和setter的pojo)。在前一种情况下,占位符作为参数提供给场景。

方案基于

使用场景以产生两个请求,与占位符邮政编码:

!*> Scenario definition 
!define POST_BODY_2 { {{{ 
<s11:Envelope xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s11:Body> 
    <ns1:GetCityWeatherByZIP xmlns:ns1="http://ws.cdyne.com/WeatherWS/"> 
     <ns1:ZIP>@{zip}</ns1:ZIP> 
    </ns1:GetCityWeatherByZIP> 
    </s11:Body> 
</s11:Envelope> 
}}} } 

|script|xml http test| 

|scenario |send request _|zip, City              | 
|post   |${POST_BODY_2} |to     |${URL}      | 
|check   |response status|200             | 
|show   |response               | 
|register prefix|weather  |for namespace  |http://ws.cdyne.com/WeatherWS/| 
|check   |xPath   |//weather:City/text()|@{City}      | 
*! 

|send request  | 
|zip |City   | 
|10007|New York  | 
|94102|San Francisco| 

Test output with scenario

Freemarker模板

通过使用的Freemarker模板我们可以有mo re动态主体内容(并且占位符使用'set value for'方法填充)。有了这个模板(samplePost.ftl.xml):

<s11:Envelope xmlns:s11="http://schemas.xmlsoap.org/soap/envelope/"> 
    <s11:Body> 
     <ns1:GetWeather xmlns:ns1="http://www.webserviceX.NET"> 
      <#if cityName??> 
      <ns1:CityName>${cityName}</ns1:CityName> 
      </#if> 
      <ns1:CountryName>${countryName}</ns1:CountryName> 
     </ns1:GetWeather> 
    </s11:Body> 
</s11:Envelope> 

以下维基可以创建:

!define GLOBAL_WEATHER_URL {http://www.webservicex.com/globalweather.asmx} 
!define GLOBAL_WEATHER_TEMPLATE_NAME {samplePost.ftl.xml} 

!3 Don't send a cityName element: error 

The Freemarker template will not send a cityName element if no value is supplied (the whole element will be omitted, as can be seen in the request below). The service will not like this. 
Omitting the element on a null value could not be done when the body was in the scenario content. 

|script   |xml http test            | 
|template  |${GLOBAL_WEATHER_TEMPLATE_NAME}        | 
|set value  |http://www.webserviceX.NET/GetWeather|for header|SOAPAction | 
|set value  |Canada        |for  |countryName| 
|post template to|${GLOBAL_WEATHER_URL}          | 
|check   |response status      |500     | 
|show   |request              | 
|show   |response             | 

!3 Send a cityName element: success 

When a cityName value is set the enclosing element is sent by the Freemarker template (as visible in the shown request content below), and the SOAP call will succeed. 

|script   |xml http test                 | 
|template  |${GLOBAL_WEATHER_TEMPLATE_NAME}             | 
|set value  |http://www.webserviceX.NET/GetWeather |for header |SOAPAction    | 
|set value  |Canada         |for   |countryName    | 
|set value  |Vancouver International Air-Port, B. C.|for   |cityName     | 
|post template to|${GLOBAL_WEATHER_URL}               | 
|check   |response status      |200          | 
|show   |request                   | 
|show   |response                  | 
|register prefix |wsX         |for namespace|http://www.webserviceX.NET| 
|show   |xPath         |!-//wsX:GetWeatherResult/text()-!  | 

Freemarker based test output

这两个例子发布XML,但同样的方法就可以了,当然,也可用于JSON APIs(然后我建议使用'json http test' fixture,它支持json路径而不是xPath来对收到的响应进行断言)。当你需要更复杂的占位符(例如可变长度列表)或者你想将你的占位符分组为多个嵌套散列(就像你在POJO模型中使用嵌套对象一样)时,这也可以通过使用更复杂的键的名称(例如|set value|[email protected]|for|email.to[1]|

上面使用的灯具可以是downloaded from GitHub,或通过Maven的使用:

<dependency> 
    <groupId>nl.hsac</groupId> 
    <artifactId>hsac-fitnesse-fixtures</artifactId> 
    <version>2.7.1</version> 
</dependency> 

你可以试试这个方法是否仅通过下载'standalone zip' version of the project适合你的API,解压它,运行它,然后更新t之一他可以通过更新的模板将wiki页面发布到您的API的URL并执行页面/测试。