代码之家  ›  专栏  ›  技术社区  ›  Uri

有没有办法让Eclipse多次运行JUnit测试直到失败?

  •  25
  • Uri  · 技术社区  · 16 年前

    我们偶尔会有在每X次运行中出现一次的错误。在人们签入东西之前(它自动是junit'd),我们的开发者需要通过eclipse在本地传递junit。

    是否有一些方便的方法(内置的或高质量的插件)使Eclipse运行相同的测试x次,并在出现故障时停止?只需点击运行x次?

    请注意,我在UI中寻找一些东西(例如,右键单击并说“运行x次”,而不是只说“运行”)。

    7 回复  |  直到 11 年前
        1
  •  10
  •   Michael Rusch    16 年前

    如果for循环有效,那么我同意nos.

    如果需要重复整个安装测试拆卸,则可以使用测试套件:

    1. 右键单击包含要重复的测试的包
    2. 转到“新建”并选择创建JUnit测试套件
    3. 确保只选择要重复的测试,然后单击“通过”完成。
    4. 编辑文件以多次运行。

    在文件中,您只需找到

    addTestSuite(YourTestClass.class)
    

    行,并将其包装为for循环。

    我敢肯定,如果您只想重复一个测试方法,可以使用addtest而不是addtestsuite让它只运行该类中的一个测试。

        2
  •  7
  •   akuhn    16 年前

    如果你真的想运行一个测试类直到失败,你需要你自己的运行者。

    @RunWith(RunUntilFailure.class)
    public class YourClass {
    
        // ....
    
    }
    

    它可以实现如下…

    package com.example;
    
    import org.junit.internal.runners.*;
    import org.junit.runner.notification.*;
    import org.junit.runner.*;
    
    public class RunUntilFailure extends Runner {
    
        private TestClassRunner runner;
    
        public RunUntilFailure(Class<?> klass) throws InitializationError {
            this.runner = new TestClassRunner(klass);
        }
    
        @Override
        public Description getDescription() {
            Description description = Description.createSuiteDescription("Run until failure");
            description.addChild(runner.getDescription());
            return description;
        }
    
        @Override
        public void run(RunNotifier notifier) {
            class L extends RunListener {
                boolean fail = false;
                public void testFailure(Failure failure) throws Exception { fail = true; }
            }
            L listener = new L();
            notifier.addListener(listener);
            while (!listener.fail) runner.run(notifier);
        }
    
    }
    

    …释放未测试的代码,感到TDD内疚:)

        3
  •  3
  •   Kenneth Cochran    16 年前

    我知道它不能直接回答问题,但如果每次测试都不通过,那就是一种测试气味 不稳定试验 . 这有几个可能的原因(从 Xunit测试模式 ):

    • 交互测试
    • 交互测试套件
    • 孤独测试
    • 资源泄漏
    • 资源乐观主义
    • 不可重复试验
    • 试车战
    • 非确定性试验

    其中每一项的细节记录在第16章 Xunit测试模式 .

        4
  •  3
  •   Kreich    15 年前

    下面是我写的一篇文章,展示了使用代码示例重复运行测试的几种方法: http://codehowtos.blogspot.com/2011/04/run-junit-test-repeatedly.html

    您可以使用@parameterized runner,或者使用post中包含的特殊runner 还引用了@retry实现

        5
  •  3
  •   benvolioT    14 年前

    基于@akuhn的回答,我想到的是-而不是永远跑,这将运行50次或直到失败,无论哪个先发生。

    package com.foo    
    
    import org.junit.runner.Description;
    import org.junit.runner.Runner;
    import org.junit.runner.notification.Failure;
    import org.junit.runner.notification.RunListener;
    import org.junit.runner.notification.RunNotifier;
    import org.junit.runners.BlockJUnit4ClassRunner;
    import org.junit.runners.model.InitializationError;
    
    public class RunManyTimesUntilFailure extends Runner {
    
        private static final int MAX_RUN_COUNT = 50;
    
        private BlockJUnit4ClassRunner runner;
    
        @SuppressWarnings("unchecked")
        public RunManyTimesUntilFailure(final Class testClass) throws InitializationError {
            runner = new BlockJUnit4ClassRunner(testClass); 
        }
    
        @Override
        public Description getDescription() {
            final Description description = Description.createSuiteDescription("Run many times until failure");
            description.addChild(runner.getDescription());
            return description;
        }
    
        @Override
        public void run(final RunNotifier notifier) {
            class L extends RunListener {
                boolean shouldContinue = true;
                int runCount = 0;
    
                @Override
                public void testFailure(@SuppressWarnings("unused") final Failure failure) throws Exception {
                    shouldContinue = false;
                }
    
                @Override
                public void testFinished(@SuppressWarnings("unused") Description description) throws Exception {
                    runCount++;
    
                    shouldContinue = (shouldContinue && runCount < MAX_RUN_COUNT);
                }
            }
    
            final L listener = new L();
            notifier.addListener(listener);
    
            while (listener.shouldContinue) {
                runner.run(notifier);
            }
        }
    }
    
        6
  •  2
  •   Ralph    11 年前

    可以用 TestRule S(自6月4日9日起)

    一个非常简单的实现,每次测试运行10次:

    import org.junit.rules.TestRule;
    import org.junit.runner.Description;
    import org.junit.runners.model.Statement;
    
    public class SimpleRepeatRule implements TestRule {
    
        private static class SimpleRepeatStatement extends Statement {
    
            private final Statement statement;
    
            private SimpleRepeatStatement(Statement statement) {
                this.statement = statement;
            }
    
            @Override
            public void evaluate() throws Throwable {
                for (int i = 0; i < 10; i++) {
                    statement.evaluate();
                }
            }
        }
    
        @Override
        public Statement apply(Statement statement, Description description) {
            return new SimpleRepeatStatement(statement);
        }
    }
    

    用途:

    public class Run10TimesTest {
    
       @Rule
       public SimpleRepeatRule repeatRule = new SimpleRepeatRule();
    
       @Test
       public void myTest(){...}
    }
    

    对于一个 更有用的实现 基于定义必须执行哪个测试方法的注释,查看此日志的频率: http://www.codeaffine.com/2013/04/10/running-junit-tests-repeatedly-without-loops/

        7
  •  1
  •   nos    16 年前

    我不相信有一种内在的方式让朱尼特做你想要的。

    如果多次运行产生不同的结果,那么应该对该案例进行单元测试。wich可能和在相关测试用例中运行for循环一样简单。