shell 即使在测试失败后也强制生成成功,以便继续生成管道

but5z9lq  于 2023-03-19  发布在  Shell
关注(0)|答案(1)|浏览(140)

bounty将在3天后过期。回答此问题可获得+100声望奖励。Ilyas Patel希望引起更多人关注此问题。

我有一系列的JUnit 5测试,这些测试必须分批运行(使用标记)。一旦一个批次完成,下一个批次应该继续。如果第一个批次中有任何测试失败,第二个批次不会启动,这不是我想要的行为。
我被告知使用Gradle或Shell返回退出代码零(这表示成功),以便批量测试在管道中继续。我理解这意味着构建将始终显示为通过。
在我的build.gradle文件中,我尝试过:

test {
    ignoreFailures = true

    useJUnitPlatform {
        includeTags  itags
        excludeTags  etags
    }
    testLogging {
        events("passed", "skipped", "failed")
    }
    afterSuite {
        if (test.result == TestResult.FAILURE) {
            System.exit(0)
        }
    }
}

afterSuite抛出了一个错误,所以我不确定我是否有语法错误。构建不识别“test”。
我也试过在壳牌

set +x
gradle clean build test
if [ $? -ne 0 ]; then
  exit 0
fi
set -x

但也不管用。

5m1hhzi4

5m1hhzi41#

您可以在下面找到一个完整的示例项目,希望它能满足您的需求(已使用Gradle 8.0.2进行测试)。该项目使用JVM Test Suite Plugin为每批测试定义一个测试套件,并使用特定的JUnit 5标记。

示例项目中的文件

我们有以下目录结构(为简洁起见,未显示Gradle Wrapper文件):

├── build.gradle
├── settings.gradle
└── src
    └── test
        └── java
            └── org
                └── example
                    └── MyTest.java

settings.gradle为空,build.gradle包含以下内容:

plugins {
    id 'java'
}

repositories {
    mavenCentral()
}

testing {
    suites {
        configureEach {
            useJUnitJupiter('5.9.2')
            sources {
                java {
                    // Override the default which is based on the suite name.
                    srcDirs = ['src/test/java']
                }
            }
            targets {
                all {
                    testTask.configure {
                        ignoreFailures = true
                    }
                }
            }
        }

        // The "test" suite is provided by default. Let's use it for the first
        // batch tagged with "my-tag1".
        test {
            targets {
                all {
                    testTask.configure {
                        options {
                            includeTags 'my-tag1'
                        }
                    }
                }
            }
        }
        // The "test2" suite is created here. We use it for the second batch of
        // tests that are tagged with "my-tag2".
        test2(JvmTestSuite) {
            targets {
                all {
                    testTask.configure {
                        options {
                            includeTags 'my-tag2'
                        }
                    }
                }
            }
        }
    }
}

tasks.named('check').configure {
    dependsOn(testing.suites.names)
}

下面是MyTest.java的内容:

package org.example;

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;

import static org.junit.jupiter.api.Assertions.fail;

public class MyTest {

    @Tag("my-tag1")
    @Test
    public void myTest1() {
        fail("test 1 fails");
    }

    @Tag("my-tag2")
    @Test
    public void myTest2() {
        fail("test 2 fails");
    }
}

注意,我们所有的标签都有失败的测试。

运行示例项目

我们可以使用./gradlew test./gradlew test2分别运行批处理,也可以使用./gradlew check一次性运行所有批处理。对于后者,我们得到以下输出:

> Task :test

MyTest > myTest1() FAILED
    org.opentest4j.AssertionFailedError at MyTest.java:13

1 test completed, 1 failed
There were failing tests. See the report at: file:///path/to/my_proj/build/reports/tests/test/index.html

> Task :test2

MyTest > myTest2() FAILED
    org.opentest4j.AssertionFailedError at MyTest.java:19

1 test completed, 1 failed
There were failing tests. See the report at: file:///path/to/my_proj/build/reports/tests/test2/index.html

BUILD SUCCESSFUL in 1s
4 actionable tasks: 4 executed

尽管每个批次的测试都失败了,但整个构建都被标记为成功(因为使用了ignoreFailures = true配置),因此整个构建的退出代码也是0。

相关问题