我的 JUnit 规则打开断言似乎在我们的 Jenkins 构建中不起作用



我想在整个代码中断言失败,以使我的测试失败。

我有这样的junit规则:

public class AcmeTestRule implements TestRule {
    @Override
    public Statement apply(final Statement statement, Description description) {
        return new Statement() {
            @Override
            public void evaluate() throws Throwable {
                ClassLoader classLoader = getClass().getClassLoader();
                classLoader.clearAssertionStatus();
                classLoader.setDefaultAssertionStatus(true);
                //classLoader.setPackageAssertionStatus("com.acme", true); // no effect
                statement.evaluate();
            }
        }
    }
}

,它在这样的基础测试类中:

public abstract class AcmeTestCase {
    @ClassRule
    public static final AcmeTestRule acmeTestRule = new AcmeTestRule();
}

然后确认规则本身正在起作用,我有以下测试:

public class TestAcmeTestRule extends AcmeTestCase4 {
    @Test
    public void testAssertions() {
        try {
            assert false;
        } catch (AssertionError) {
            // good.
            return;
        }
        fail("Didn't throw AssertionError on assert false");
    }
}

测试在我们的自动化构建中失败,因为"断言false"仍然没有引发异常。完全相同的测试通过从IDE运行。我们没有设置任何命令行标志来打开断言(尽管IDE可能会在我们的背后做。)

顺便说一句,如果我这样做:

public class TestAcmeTestRule {
    @ClassRule
    public static final AcmeTestRule acmeTestRule = new AcmeTestRule();
    @Test
    public void testAssertions() {
        try {
            assert false;
        } catch (AssertionError) {
            // good.
            return;
        }
        fail("Didn't throw AssertionError on assert false");
    }
}

最终的测试现在在IDE中也失败了。我所做的就是将规则从抽象类移至测试类。

我认为这是一些奇怪的班级加载问题。我的理论:仅在bytecode中阅读时才使用断言状态,因此,到您运行字节码时,更改值为时已晚。

ClassLoader.setDefaultAssertionStatus的问题(以及所有类似的方法)是,它们对已经加载的类没有影响。从文档

此设置确定 Future 在此类加载程序加载和初始化的中是否加载的类。P>

因此,只要您不确定在加载所有其他类之前,您就无法可靠地启用代码中的断言(这可能是错误的)。

在IDE中起作用的原因可能是IDE倾向于通过适当的命令行参数来启用断言,或者类别加载的顺序可能不同。

相关内容

最新更新