maven - 当单元测试耗时太长时失败

时间:2012-02-16 13:32:45

标签: java testing maven junit build-process

我的项目中有很多单元测试,用JUnit和TestNG编写。构建过程基于带有surefire插件的maven。

当至少一个单元测试花费太多秒时,maven是否有任何方法/插件可以使构建失败?我知道有一些插件可以在TeamCity,Jenkins中构建失败,但这“太过分了”。

在我的项目中,我希望只进行快速测试,以使单元测试过程有效。我可以改进我的旧测试,但我需要保护未来的承诺

6 个答案:

答案 0 :(得分:11)

如果你的所有测试扩展了一些基类,我认为你可以将@Rule放在那里,这将适用于子类中的所有@Test

e.g。

import org.junit.rules.Timeout;
public abstract class BaseTestConfiguration {
    @Rule public Timeout testTimeout = new Timeout(60000); // 60k ms = 1 minute
}

public class ThingTests extends BaseTestConfiguration {
    @Test
    public void testThis() {
        /*will fail if not done in 1 minute*/
    }
    @Test
    public void testThat() {
        /*will fail if not done in 1 minute*/
    }
}

我们发现这是最容易的,而不是搞乱AspectJ或秘密配置指令。开发人员更有可能找出Java部分,而不是所有秘密的XML。 您也可以在基类中放置@Before @After和任意数量的其他junit指令。

答案 1 :(得分:6)

在maven surefire中,您可以使用forkedProcessTimeoutInSeconds以及forkMode=once

如果花费太长时间,这会杀死分叉的jvm。如果你想在每个测试中做这个,你可以forkMode = pertest或forkMode = always(这是为每个类做的)。

答案 2 :(得分:4)

为什么不在每个测试的基础上添加超时。我假设您使用Java进行编程,因此在JUnit中您可以执行以下操作:

 @Test(timeout=100) public void testQuickly()

如果测试在100毫秒后没有结束,它将失败。

答案 3 :(得分:1)

您是否尝试通过@Test(timeout = xx)指定测试的超时?在此处查找官方api文档:http://junit.sourceforge.net/javadoc/org/junit/Test.html

EDIT ---

您还可以考虑使用TestNg套件的超时属性,但您必须将所有测试移至TestNg,但这将允许您为组指定超时。

这是官方的api文档:http://testng.org/javadoc/org/testng/xml/XmlSuite.html#setTimeOut(java.lang.String

答案 4 :(得分:0)

我曾经有同样的要求,因为我使用的是TestNG,所以我使用了"group feature"

如果您遇到JUnit,请尝试使用测试套件(http://stackoverflow.com/questions/817135/grouping-junit-tests)

答案 5 :(得分:0)

尝试将junit Ant任务与timeout参数一起使用。

http://ant.apache.org/manual/Tasks/junit.html

编辑:
你可以做的另一件事是使用aspectj与这样的东西:

public aspect TestTimeoutChecker {
    long TIMEOUT = 60000;

    pointcut invokeEvent() :
        execution(@Test * *(..));

    Object around() : invokeEvent() {

        long start = System.currentTimeMillis();
        Object object = proceed();
        long took = System.currentTimeMillis() - start;
        if (took > TIMEOUT) {
            throw new RuntimeException("timeout! it took:" + took);
        }
        return object;
    }
}