Java JUnit集成测试应报告HTTP请求/响应详细信息

Java JUnit集成测试应报告HTTP请求/响应详细信息,java,unit-testing,maven,junit,jenkins,Java,Unit Testing,Maven,Junit,Jenkins,我正在编写一些使用Maven Failsafe插件运行的集成测试 简而言之,它们执行HTTP调用并分析JSON响应,以确保存在某些元素 当测试失败时,我希望能够看到HTTP请求和响应头、正文等的详细信息,而不仅仅是断言失败消息 如果我的测试看起来像这样: public class FooBarTest { MyHttpClient httpClient; @Before public void setupHttpClient(){ this.httpCl

我正在编写一些使用Maven Failsafe插件运行的集成测试

简而言之,它们执行HTTP调用并分析JSON响应,以确保存在某些元素

当测试失败时,我希望能够看到HTTP请求和响应头、正文等的详细信息,而不仅仅是断言失败消息

如果我的测试看起来像这样:

public class FooBarTest {

    MyHttpClient httpClient;

    @Before
    public void setupHttpClient(){
       this.httpClient = ...
    }

    @Test
    public void testFooBarBaz(){
       Response response = this.httpClient.get("http://some/url");
       Assert.assertEquals(200, response.getStatus());
       String json = response.getBody();
       Assert.assertEquals("baz", evalJsonPath(json, "foo.bar.id"));
    }
}
当测试从命令行通过Maven运行时,我希望能够看到断言错误以及请求和响应的详细信息。我认为这需要打印到System.out/err,但最好通过一些日志系统来完成

此外,我希望在surefire/failsafe生成的测试TXT报告文件中提供相同的信息:

-------------------------------------------------------------------------------
Test set: com.sample.FooBarTest
-------------------------------------------------------------------------------

REQUEST: {...}
RESPONSE: {...}

Tests run: 1, Failures: 1, Errors: 0, Skipped: 0, Time elapsed: 3.273 sec <<< FAILURE! - in com.sample.FooBarTest
testFooBarBaz(com.sample.FooBarTest)  Time elapsed: 3.27 sec  <<< ERROR!
junit.framework.AssertionFailedError: expected:<200> but was:<404>
     at junit.framework.Assert.fail(Assert.java:47)
     at junit.framework.Assert.failNotEquals(Assert.java:283)
     at junit.framework.Assert.assertEquals(Assert.java:64)
     at junit.framework.Assert.assertEquals(Assert.java:195)
     at junit.framework.Assert.assertEquals(Assert.java:201)
     at com.sample.FooBarTest.testFooBarBaz(FooBarTest.java:XX)
最后,同样的细节应该以某种方式出现在XML报告中,Jenkins在深入到失败的测试页面时也会以这种方式显示这些信息

如果可能的话,我只关心在测试失败时打印这些信息

我怎样才能做到这一点?我已经开始研究这些选项,但如果能提供更多指导,我将不胜感激

自定义JUnit报告程序、运行程序或侦听器 JUnit@Rules方法/类规则、ErrorCollector等。 使用一些特殊的记录器 ... <> P.S.我不想寻找一个简单的解决方案,因为我认为这样的细节对用户来说不太友好。
谢谢

您需要做的就是生成一条自定义错误消息,以便打印您想要的内容

 assertEquals( getResponseDetails(response), 200, response.getStatus());
 ...
 assertEquals( getResponseDetails(response), "baz", evalJsonPath(json, "foo.bar.id"));
其中getResponseDetails是您编写的方法

private String getResponseDetails(Response response){
   StringBuider builder = new StringBuilder();

   buider.append("header = '").append(response.getHeader()).append("'\n");
   ...//similar code for body etc

   return builder.toString();

}
该字符串将被写入在Maven配置中配置测试输出的任何位置,并且仅在测试失败时才会打印

或者,由于Response可能是您创建的自定义类,因此您可以使ResponsetoString包含所需的信息,在这种情况下,您只需执行以下操作:

 assertEquals( response, 200, response.getStatus());
 ...
 assertEquals( response, "baz", evalJsonPath(json, "foo.bar.id"));

附带说明:我从堆栈跟踪中注意到,您使用的是junit.framework.Assert,它是旧的junit 3库。您应该改用JUnit4,您所需要做的就是生成一条自定义错误消息来打印您想要的内容

 assertEquals( getResponseDetails(response), 200, response.getStatus());
 ...
 assertEquals( getResponseDetails(response), "baz", evalJsonPath(json, "foo.bar.id"));
其中getResponseDetails是您编写的方法

private String getResponseDetails(Response response){
   StringBuider builder = new StringBuilder();

   buider.append("header = '").append(response.getHeader()).append("'\n");
   ...//similar code for body etc

   return builder.toString();

}
该字符串将被写入在Maven配置中配置测试输出的任何位置,并且仅在测试失败时才会打印

或者,由于Response可能是您创建的自定义类,因此您可以使ResponsetoString包含所需的信息,在这种情况下,您只需执行以下操作:

 assertEquals( response, 200, response.getStatus());
 ...
 assertEquals( response, "baz", evalJsonPath(json, "foo.bar.id"));
附带说明:我从堆栈跟踪中注意到,您使用的是junit.framework.Assert,它是旧的junit 3库。您应该改用JUnit4,您可以使用带有自定义匹配器的Hamcrest

在Matchers上做一点工作,就可以将测试编写为:

assertThat(response, hasStatus(200));
assertThat(response, hasJsonPathEval("foo.bar.id", eq("baz"));
任何失败都将包括您的响应的toString表示

这在功能上等同于:

assertEquals(response.toString(), 200, response.getStatus());
但更清楚的是,您希望在失败时显示测试的响应和描述。

您可以将Hamcrest与自定义匹配器一起使用

在Matchers上做一点工作,就可以将测试编写为:

assertThat(response, hasStatus(200));
assertThat(response, hasJsonPathEval("foo.bar.id", eq("baz"));
任何失败都将包括您的响应的toString表示

这在功能上等同于:

assertEquals(response.toString(), 200, response.getStatus());

但更清楚的是,您希望在失败时显示响应和测试说明。

谢谢您的建议。虽然这种方法没有错,但我希望有更优雅的解决方案。如果我找不到任何其他的解决方案,我可能会走这条路。tho:PS。感谢您关注JUnit版本issueThanks的建议。虽然这种方法没有错,但我希望有更优雅的解决方案。如果我找不到任何其他解决方案,我可能会走这条路。tho:PS。感谢您关注JUnit版本。这比@dkatzel的建议稍微好一点,但这种方法的问题是我需要响应和请求的详细信息,尽管我只会从响应中断言一些东西。我知道我可以将这两个对象包装成一个单独的对象,并在其上使用自定义匹配器,但它仍然感觉有些粗糙。另外,我将使用各种匹配器,我不想为每个匹配器创建一个自定义匹配器。你知道有没有一种简单的方法可以在所有匹配者的个人默认设置之外用自定义消息装饰他们吗?谢谢Joe。这比@dkatzel的建议稍微好一点,但这种方法的问题是我需要响应和请求的详细信息,尽管我只会从响应中断言一些东西。我知道我可以将两者包装成一个对象并在其上使用自定义匹配器,但是 感觉还是有点不舒服。另外,我将使用各种匹配器,我不想为每个匹配器创建一个自定义匹配器。你知道有没有一种简单的方法可以在每个匹配器的默认值之外,用一条自定义消息来装饰所有匹配器?