Maven 没有显示参数化测试的参数,可能有什么问题?

问题描述

测试似乎运行良好(有些失败,但它们正在运行),但日志没有向我显示参数,为什么?

@ExtendWith( SpringExtension.class )
@ContextConfiguration(
    locations = {
        "classpath:spring/testContext.xml","classpath:applicationContext-mock.xml"
    } )
@Transactional
@ActiveProfiles( Profiles.TEST )
@Category( IntegrationTest.class )
public abstract class AbstractDalTestBase {
    @ParameterizedTest
    @ArgumentsSource(LetterSearchWithFilterandPagingForHCPCSCodeArguments.class)
    public void letterSearchWithFilterandPagingForHCPCSCode(String searchTerm,int expected) {
        List<?> results = findMatchingItemsWithFilterandPaging(searchTerm,CatalogItemType.HCPCSCODE,null);
        int projection = loadTotalNumberOfItems(searchTerm,CatalogItemType.HCPCSCODE);
        assertthat(projection).as("projection eq results").isEqualTo(results.size());
        assertthat(projection).as("projection eq expected").isEqualTo(expected);
        assertthat(results.size()).as("results eq expected").isEqualTo(expected);
    }
class LetterSearchWithFilterandPagingForHCPCSCodeArguments implements ArgumentsProvider {

    @Override
    public Stream<? extends Arguments> provideArguments(ExtensionContext extensionContext) {
        int count = 5643;
        return Stream.of(
            Arguments.of("A",count),Arguments.of("a"),Arguments.of("b",2151)
        );
    }
}
[ThreadedStreamConsumer] ERROR org.apache.maven.plugin.surefire.SurefirePlugin - letterSearchWithFilterandPagingForHCPCSCode{String,int}[1]  Time elapsed: 2.496 s  <<< FAILURE!
java.lang.AssertionError: 
[projection eq results] 
Expecting:
 <5643>
and actual:
 <5643>
to refer to the same object

我认为 junit 应该记录传递给方法的值,我该如何让它这样做?

解决方法

我找到了 this JUnit ticket,问题是肯定的。它已在 3.0.0-M5 中修复,不幸的是,我无法使用。

不使用显示名称的理由是它会“破坏”Surefire 生成的 XML 报告。因此,我们需要一种新的报告格式,Surefire 需要采用它才能报告显示名称(参见 #373)。

从插件版本 3.0.0-M4 开始,您可以使用细粒度的报告配置,并在测试中与 @DisplayName 一起启用短语名称。这是特定对象的完整属性列表。您不必指定例如禁用,版本和编码。如果没有另外指定,布尔值达到默认值 false。

<build>
    <plugins>
        ...
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-surefire-plugin</artifactId>
            <version>3.0.0-M5</version>
            <configuration>
                <statelessTestsetReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5Xml30StatelessReporter">
                    <disable>false</disable>
                    <version>3.0</version>
                    <usePhrasedFileName>false</usePhrasedFileName>
                    <usePhrasedTestSuiteClassName>true</usePhrasedTestSuiteClassName>
                    <usePhrasedTestCaseClassName>true</usePhrasedTestCaseClassName>
                    <usePhrasedTestCaseMethodName>true</usePhrasedTestCaseMethodName>
                </statelessTestsetReporter>
                <consoleOutputReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5ConsoleOutputReporter">
                    <disable>false</disable>
                    <encoding>UTF-8</encoding>
                    <usePhrasedFileName>false</usePhrasedFileName>
                </consoleOutputReporter>
                <statelessTestsetInfoReporter implementation="org.apache.maven.plugin.surefire.extensions.junit5.JUnit5StatelessTestsetInfoReporter">
                    <disable>false</disable>
                    <usePhrasedFileName>false</usePhrasedFileName>
                    <usePhrasedClassNameInRunning>true</usePhrasedClassNameInRunning>
                    <usePhrasedClassNameInTestCaseSummary>true</usePhrasedClassNameInTestCaseSummary>
                </statelessTestsetInfoReporter>
            </configuration>
        </plugin>
    </plugins>
</build>
,

Surefire 插件可能对此无能为力:JUnit5 似乎没有公开有关运行/结束测试的测试用例参数信息,而是提供特定测试的显示名称,该名称包含测试运行序号和传递给测试的 toString-ed 参数,例如 [ORDINAL] ARG1,ARG2...(出现在 IntelliJ IDEA JUnit runner 中的那个)。但是,Surefire 插件不会解析此类名称(无论出于何种原因,因为它们将来可能会更改?),或者在某些情况下会直接忽略它们。

这是一个示例测试(@MethodSource 似乎不会影响结果):

public final class FooTest {

    private static Stream<? extends Arguments> test() {
        return Stream.of(
                Arguments.of(1,1),Arguments.of(1,0)
        );
    }

    @ParameterizedTest
    @MethodSource
    public void test(final Object a,final Object b) {
        Assertions.assertEquals(a,b);
    }

}

上述测试失败,maven-surefire-plugin:3.0.0-M5 下的以下断言失败:

[ERROR] FooTest.test(Object,Object)[2]  Time elapsed: 0.002 s  <<< FAILURE!
org.opentest4j.AssertionFailedError: expected: <1> but was: <0>
    at FooTest.test(FooTest.java:31)

我查看了当前的 3.0.6-SNAPSHOT 源代码,并应用了以下补丁(在 be236f772724aab93087c82b84ef484e2e0bfa80 之上),然后在测试中将 Surefire 版本更新为 3.0.0-M6-SNAPSHOT {{ 1}}:

pom.xml

然后使用 From 9b01ccc020c5c2040ef0ee6988f5faa2d179a1db Mon Sep 17 00:00:00 2001 From: - <-> Date: Wed,6 Jan 2021 02:53:27 +0200 Subject: [PATCH] Append test arguments to the method description --- .../maven/surefire/junitplatform/RunListenerAdapter.java | 5 +++++ 1 file changed,5 insertions(+) diff --git a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java index b193ba5ed..8af18c110 100644 --- a/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java +++ b/surefire-providers/surefire-junit-platform/src/main/java/org/apache/maven/surefire/junitplatform/RunListenerAdapter.java @@ -287,6 +287,11 @@ private StackTraceWriter toStackTraceWriter( String realClassName,String realMe boolean hasLegacyDescription = description.startsWith( methodName + '(' ); boolean hasDisplayName = !equalDescriptions || !hasLegacyDescription; String methodDesc = equalDescriptions || !hasParams ? methodSign : description; + int argsPos = display.indexOf( "] " ); + if ( argsPos != -1 ) + { + methodDesc += " (" + display.substring( argsPos + 2 ) + ')'; + } String methodDisp = hasDisplayName ? display : methodDesc; // The behavior of methods getLegacyReportingName() and getDisplayName(). -- 2.30.0 将修补版本安装到我的本地存储库。现在断言失败变成这样:

mvn -Dmaven.test.skip=true clean install

其中[ERROR] FooTest.test(Object,Object)[2] (1,0) Time elapsed: 0.002 s <<< FAILURE! org.opentest4j.AssertionFailedError: expected: <1> but was: <0> at FooTest.test(FooTest.java:31) ,测试参数,现在出现在测试名称之后。

我想您必须在 https://issues.apache.org/jira/browse/SUREFIRE 提出一张票,以便维护人员可以在可能的情况下改进参数化测试名称的支持(不确定是否还需要改进 JUnit)。