Skip to content
Advertisement

Can’t attach RestAssured’s RQ/RS of Spring Cloud Contract’s tests to Allure report

I’ve successfully added Allure2 to my project with Spring Cloud Contract tests (it uses JUnit5), but tab “Overview” is blank in all successed test of report.

I created a listener class, that gets RQ and RS from RestAssured:

public class JunitListener extends RunListener {
    public ByteArrayOutputStream request = new ByteArrayOutputStream();
    public ByteArrayOutputStream response = new ByteArrayOutputStream();

    public PrintStream requestVar = new PrintStream(request, true);
    public PrintStream responseVar = new PrintStream(response, true);

    @Override
    public void testStarted(Description description) throws Exception {
        RestAssured.filters(new ResponseLoggingFilter(LogDetail.ALL, responseVar),
                new RequestLoggingFilter(LogDetail.ALL, requestVar));
    }

    @Override
    public void testFinished(Description description) throws Exception {
        logRequest(request);
        logResponse(response);
    }

    @Attachment(value = "Client RQ", type = "plain/text", fileExtension = ".log")
    public byte[] logRequest(ByteArrayOutputStream stream) {
        return attach(stream);
    }

    @Attachment(value = "Client RS", type = "plain/text", fileExtension = ".log")
    public byte[] logResponse(ByteArrayOutputStream stream) {
        return attach(stream);
    }

    public byte[] attach(ByteArrayOutputStream log) {
        byte[] array = log.toByteArray();
        log.reset();
        return array;
    }
}

And runner class, that uses listener class:

public class JunitRunner extends BlockJUnit4ClassRunner {
    public JunitListener junitListener;

    public JunitRunner(Class<?> klass) throws InitializationError {
        super(klass);
        junitListener = new JunitListener();
    }

    @Override
    public void run(RunNotifier notifier) {
        notifier.addListener(junitListener);
        super.run(notifier);
    }
}

And then I’ve added runner class to my base test class:

@SpringBootTest(
        webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
        properties = "server.port=0"
)
@ExtendWith({RestDocumentationExtension.class, SpringExtension.class})
@RunWith(JunitRunner.class)
@AutoConfigureWireMock(port = 8081)
@ActiveProfiles("test")
public abstract class BaseTest {
    
    @LocalServerPort
    int localPort;

    @BeforeEach
    public void setUp(TestInfo testInfo, RestDocumentationContextProvider restDocumentation) {
        RestAssured.baseURI = "http://localhost";
        RestAssured.port = localPort;

        final RequestSpecification idx = new RequestSpecBuilder()
                .setBaseUri("http://localhost")
                .setPort(localPort)
                .addFilter(documentationConfiguration(restDocumentation))
                .build();

        RestAssured.requestSpecification =
                idx.filter(document("contract/" + testInfo.getTestMethod().orElseThrow().getName()));
    }

    @AfterEach
    public void tearDown() {
        RestAssured.reset();
    }
}

But no record was added to my Allure report and, as I see in debugger, content of listener and runner is never used 🙁 What am I doing wrong?

Advertisement

Answer

I learned that SCC does not use JUnit to run tests, but uses SpringBootTest .

So I’ve created a SBT listener class:

public class CustomTestExecutionListener implements TestExecutionListener, Ordered {

    public ByteArrayOutputStream request = new ByteArrayOutputStream();
    public ByteArrayOutputStream response = new ByteArrayOutputStream();

    public PrintStream requestVar = new PrintStream(request, true);
    public PrintStream responseVar = new PrintStream(response, true);

    public void beforeTestMethod(TestContext testContext) throws Exception {
        RestAssured.filters(new ResponseLoggingFilter(LogDetail.ALL, responseVar),
                new RequestLoggingFilter(LogDetail.ALL, requestVar));
    }

    public void afterTestMethod(TestContext testContext) throws Exception {
        logRequest(request);
        logResponse(response);
    }

    @Override
    public int getOrder() {
        return Integer.MAX_VALUE;
    }

    @Attachment(value = "Client RQ", type = "text/html")
    public byte[] logRequest(ByteArrayOutputStream stream) {
        return attach(stream);
    }

    @Attachment(value = "Client RS", type = "text/html")
    public byte[] logResponse(ByteArrayOutputStream stream) {
        return attach(stream);
    }

    public byte[] attach(ByteArrayOutputStream log) {
        byte[] array = log.toString().getBytes(StandardCharsets.UTF_8);
        log.reset();
        return array;
    }
}

And added that to my SCC base test class:

@TestExecutionListeners(
        value = { CustomTestExecutionListener.class },
        mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)

Now it works and I have 2 log sections in my Allure report.

User contributions licensed under: CC BY-SA
5 People found this is helpful
Advertisement