用 Cucumber 放心:如何将请求信息放入 HTML 报告中
Rest Assured with Cucumber: How to put the request information inside the HTML report
我想在我的 HTML 报告中显示我的请求和响应的详细信息。
特征文件示例:
Feature: Rest Assured under Cucumber POC
Scenario: Azure Login Scenario
Given Request specifications are set with base uri "https://login.microsoftonline.com/"
When Azure Login Request Executed
Then Verify Status Code is 200
亚军class是:
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/main/resources/features",
glue = {""},
tags = "@tests",
plugin = { "pretty",
"json:target/cucumber-reports/Cucumber.json",
"html:target/cucumber-reports"}//reporting plugin
)
public class CucumberRunner {}
步骤是:
@Given("Request specifications are set with base uri {string}")
public void setRequestsSpec(String baseUri){
RequestSpecification spec = new RequestSpecBuilder()
.setBaseUri(baseUri)
.addFilter(new ResponseLoggingFilter())//log request and response for better debugging. You can also only log if a requests fails.
.addFilter(new RequestLoggingFilter())
.build();
testContext().setRequestSpec(spec);
}
@When("^Azure Login Request Executed$")
public void azureLoginExecuted() {
response =
given() //Add x-www-form-urlencoded body params:
.formParam(GRANT_TYPE_KEY, GRANT_TYPE_VALUE)
.formParam(AUTO_TEAM_CLIENT_ID_KEY, AUTO_TEAM_CLIENT_ID_VALUE)
.formParam(AUTO_TEAM_CLIENT_SECRET_KEY, AUTO_TEAM_CLIENT_SECRET_VALUE)
.formParam(RESOURCE_KEY, RESOURCE_VALUE)
.when()
.post(AUTO_TEAM_TENANT_ID + RESOURCE); //Send the request along with the resource
testContext().setResponse(response);
setAuthorizationToken();
}
@Then("Verify Status Code is {int}")
public void verifyStatusCode(int expected_repsonse_code) {
testContext().getResponse().then().statusCode(expected_repsonse_code);
}
目前我发现了如何仅在我的 IntelliJ 控制台中显示这些详细信息:
例如:
@tests
Feature: Rest Assured under Cucumber POC
@tests
Scenario: Azure Login Scenario # src/main/resources/features/poc.feature:5
Given Request specifications are set with base uri "https://login.microsoftonline.com/" # CommonStepsDefinitions.setRequestsSpec(String)
Request method: POST
Request URI: https://login.microsoftonline.com/6ae4e000-b5d0-4f48-a766-402d46119b76/oauth2/token
Proxy: <none>
Request params: <none>
Query params: <none>
还有更多..
但是 HTML 报告只显示:
谢谢!
我可以给你一些细节,但可能无法完全回答你的问题。
为了向 Cucumber HTML 报告中添加数据,您可以使用:
@After
public void addDataToReport(Scenario scenario) { //scenario is provided from Cucumber
scenario.write(string with the information about scenario);
}
它不会被格式化,我不知道如何更改报告的显示方式。每条消息都将在每个测试用例下。
你必须以某种方式将信息传递给 @After
钩子。
我希望其他人能更详细地回答。
编辑:
为了存储当前运行正在发生什么场景的信息,甚至是并行的,我们可以创建一个class来存储必要的信息,基于线程,所以它将是 Thread-safe.
让我们创建一个 class 来存储 Scenario
。我们称它为 Storage
public class Storage {
private static final HashMap<Thread, Scenario> map = new HashMap<>();
public static void putScenario(Scenario scenario) {
map.put(Thread.currentThread(), scenario);
}
public static Scenario getScenario() {
return map.get(Thread.currentThread());
}
}
现在,我们必须以某种方式获得 Scenario
。它可以通过使用 @Before
挂钩来实现,如下所示:
public class BeforeHook {
@Before(order = 1)
public void getScenario(Scenario scenario) {
Storage.putScenario(scenario);
}
}
@Before
挂钩在每个场景之前 运行。我们获取有关 Scenario 的信息并将其放入 Storage 中,这样我们就知道什么 Scenario 在什么线程上 运行。
请记住,钩子必须可以通过 Cucumber Runner 中的 glue
参数访问!
现在,如果我们想在报告中写入额外信息:
@Then("Data is saved to the report")
public void data_is_saved_to_the_report() {
System.out.println("Saving data to report");
Storage.getScenario().write("Test data and stuff");
}
我们只是从存储中获取当前场景并使用Scenario.write()
方法将信息添加到报告中。
它在报告中看起来像这样:
您只需按以下方式设置 RequestSpecification
过滤器,即可将 RestAssured 输出记录到您的 Cucumber 场景报告中:
ByteArrayOutputStream requestResponseBuffer = new ByteArrayOutputStream();
PrintStream requestResponsePrintStream = new PrintStream(requestResponseBuffer , true);
List<Filter> loggingFilters = Arrays.asList(
new RequestLoggingFilter(requestResponsePrintStream),
new CucumberReportLoggingFilter(requestResponseBuffer, scenario),
new ResponseLoggingFilter(requestResponsePrintStream)
);
RequestSpecification requestSpecification = RestAssured.given()
.filters(loggingFilters)
:
其中 CucumberReportLoggingFilter
class 看起来像这样:
class CucumberReportLoggingFilter implements Filter {
ByteArrayOutputStream requestResponseBuffer;
Scenario scenario;
CucumberReportLoggingFilter(ByteArrayOutputStream requestResponseBuffer, Scenario scenario) {
this.requestResponseBuffer = requestResponseBuffer;
this.scenario = scenario;
}
@Override
Response filter(FilterableRequestSpecification requestSpec,
FilterableResponseSpecification responseSpec, FilterContext ctx) {
// Call the next filter(s) which logs the response to the requestResponseBuffer
Response response = ctx.next(requestSpec, responseSpec);
scenario.write(requestResponseBuffer.toString());
return response;
}
}
此解决方案将自定义 CucumberReportLoggingFilter
夹在标准 RequestLoggingFilter
和 ResponseLoggingFilter
过滤器之间。
RequestSpecification 发送 Request 时发生的过滤事件顺序是:
- 标准
RequestLoggingFilter
filter()
方法运行并将请求详细信息漂亮地打印到 requestResponseBuffer
。
- 自定义
CucumberReportLoggingFilter
filter()
方法运行并调用下一个过滤器(标准 ResponseLoggingFilter
过滤器)。
- 标准
ResponseLoggingFilter
filter()
方法运行并漂亮地将响应详细信息打印到 requestResponseBuffer
。
- 控制返回到自定义
CucumberReportLoggingFilter
filter()
方法,该方法使用 scenario.write()
方法将 requestResponseBuffer
的内容发送到 Cucumber 报告。
仅在场景失败时才写出消息
您可以将上述解决方案修改为:
- 删除
CucumberReportLoggingFilter
.
- 使
requestResponseBuffer
变量 'scenario-scoped'(即每个场景只有一个缓冲区)。
- 让在您的 stepdefs 代码中运行的最后一个
@After
挂钩检查场景结果,如果失败,将 requestResponseBuffer
的内容写入黄瓜报告。
我想在我的 HTML 报告中显示我的请求和响应的详细信息。
特征文件示例:
Feature: Rest Assured under Cucumber POC
Scenario: Azure Login Scenario
Given Request specifications are set with base uri "https://login.microsoftonline.com/"
When Azure Login Request Executed
Then Verify Status Code is 200
亚军class是:
@RunWith(Cucumber.class)
@CucumberOptions(
features = "src/main/resources/features",
glue = {""},
tags = "@tests",
plugin = { "pretty",
"json:target/cucumber-reports/Cucumber.json",
"html:target/cucumber-reports"}//reporting plugin
)
public class CucumberRunner {}
步骤是:
@Given("Request specifications are set with base uri {string}")
public void setRequestsSpec(String baseUri){
RequestSpecification spec = new RequestSpecBuilder()
.setBaseUri(baseUri)
.addFilter(new ResponseLoggingFilter())//log request and response for better debugging. You can also only log if a requests fails.
.addFilter(new RequestLoggingFilter())
.build();
testContext().setRequestSpec(spec);
}
@When("^Azure Login Request Executed$")
public void azureLoginExecuted() {
response =
given() //Add x-www-form-urlencoded body params:
.formParam(GRANT_TYPE_KEY, GRANT_TYPE_VALUE)
.formParam(AUTO_TEAM_CLIENT_ID_KEY, AUTO_TEAM_CLIENT_ID_VALUE)
.formParam(AUTO_TEAM_CLIENT_SECRET_KEY, AUTO_TEAM_CLIENT_SECRET_VALUE)
.formParam(RESOURCE_KEY, RESOURCE_VALUE)
.when()
.post(AUTO_TEAM_TENANT_ID + RESOURCE); //Send the request along with the resource
testContext().setResponse(response);
setAuthorizationToken();
}
@Then("Verify Status Code is {int}")
public void verifyStatusCode(int expected_repsonse_code) {
testContext().getResponse().then().statusCode(expected_repsonse_code);
}
目前我发现了如何仅在我的 IntelliJ 控制台中显示这些详细信息:
例如:
@tests
Feature: Rest Assured under Cucumber POC
@tests
Scenario: Azure Login Scenario # src/main/resources/features/poc.feature:5
Given Request specifications are set with base uri "https://login.microsoftonline.com/" # CommonStepsDefinitions.setRequestsSpec(String)
Request method: POST
Request URI: https://login.microsoftonline.com/6ae4e000-b5d0-4f48-a766-402d46119b76/oauth2/token
Proxy: <none>
Request params: <none>
Query params: <none>
还有更多..
但是 HTML 报告只显示:
谢谢!
我可以给你一些细节,但可能无法完全回答你的问题。
为了向 Cucumber HTML 报告中添加数据,您可以使用:
@After
public void addDataToReport(Scenario scenario) { //scenario is provided from Cucumber
scenario.write(string with the information about scenario);
}
它不会被格式化,我不知道如何更改报告的显示方式。每条消息都将在每个测试用例下。
你必须以某种方式将信息传递给 @After
钩子。
我希望其他人能更详细地回答。
编辑:
为了存储当前运行正在发生什么场景的信息,甚至是并行的,我们可以创建一个class来存储必要的信息,基于线程,所以它将是 Thread-safe.
让我们创建一个 class 来存储 Scenario
。我们称它为 Storage
public class Storage {
private static final HashMap<Thread, Scenario> map = new HashMap<>();
public static void putScenario(Scenario scenario) {
map.put(Thread.currentThread(), scenario);
}
public static Scenario getScenario() {
return map.get(Thread.currentThread());
}
}
现在,我们必须以某种方式获得 Scenario
。它可以通过使用 @Before
挂钩来实现,如下所示:
public class BeforeHook {
@Before(order = 1)
public void getScenario(Scenario scenario) {
Storage.putScenario(scenario);
}
}
@Before
挂钩在每个场景之前 运行。我们获取有关 Scenario 的信息并将其放入 Storage 中,这样我们就知道什么 Scenario 在什么线程上 运行。
请记住,钩子必须可以通过 Cucumber Runner 中的 glue
参数访问!
现在,如果我们想在报告中写入额外信息:
@Then("Data is saved to the report")
public void data_is_saved_to_the_report() {
System.out.println("Saving data to report");
Storage.getScenario().write("Test data and stuff");
}
我们只是从存储中获取当前场景并使用Scenario.write()
方法将信息添加到报告中。
它在报告中看起来像这样:
您只需按以下方式设置 RequestSpecification
过滤器,即可将 RestAssured 输出记录到您的 Cucumber 场景报告中:
ByteArrayOutputStream requestResponseBuffer = new ByteArrayOutputStream();
PrintStream requestResponsePrintStream = new PrintStream(requestResponseBuffer , true);
List<Filter> loggingFilters = Arrays.asList(
new RequestLoggingFilter(requestResponsePrintStream),
new CucumberReportLoggingFilter(requestResponseBuffer, scenario),
new ResponseLoggingFilter(requestResponsePrintStream)
);
RequestSpecification requestSpecification = RestAssured.given()
.filters(loggingFilters)
:
其中 CucumberReportLoggingFilter
class 看起来像这样:
class CucumberReportLoggingFilter implements Filter {
ByteArrayOutputStream requestResponseBuffer;
Scenario scenario;
CucumberReportLoggingFilter(ByteArrayOutputStream requestResponseBuffer, Scenario scenario) {
this.requestResponseBuffer = requestResponseBuffer;
this.scenario = scenario;
}
@Override
Response filter(FilterableRequestSpecification requestSpec,
FilterableResponseSpecification responseSpec, FilterContext ctx) {
// Call the next filter(s) which logs the response to the requestResponseBuffer
Response response = ctx.next(requestSpec, responseSpec);
scenario.write(requestResponseBuffer.toString());
return response;
}
}
此解决方案将自定义 CucumberReportLoggingFilter
夹在标准 RequestLoggingFilter
和 ResponseLoggingFilter
过滤器之间。
RequestSpecification 发送 Request 时发生的过滤事件顺序是:
- 标准
RequestLoggingFilter
filter()
方法运行并将请求详细信息漂亮地打印到requestResponseBuffer
。 - 自定义
CucumberReportLoggingFilter
filter()
方法运行并调用下一个过滤器(标准ResponseLoggingFilter
过滤器)。 - 标准
ResponseLoggingFilter
filter()
方法运行并漂亮地将响应详细信息打印到requestResponseBuffer
。 - 控制返回到自定义
CucumberReportLoggingFilter
filter()
方法,该方法使用scenario.write()
方法将requestResponseBuffer
的内容发送到 Cucumber 报告。
仅在场景失败时才写出消息
您可以将上述解决方案修改为:
- 删除
CucumberReportLoggingFilter
. - 使
requestResponseBuffer
变量 'scenario-scoped'(即每个场景只有一个缓冲区)。 - 让在您的 stepdefs 代码中运行的最后一个
@After
挂钩检查场景结果,如果失败,将requestResponseBuffer
的内容写入黄瓜报告。