如何根据相同(但不断变化的)信息/设置运行不同的junit测试

时间:2011-11-04 09:40:15

标签: java junit

我得到了许多不同的流程,这些流程正在重新生成模块。像这样Flow1 = M1-> M2-> M3-> M5或Flow2 = M1-> M2-> M4-> M6-> M3-> M5。

现在我想为每个模块编写一个testCase,以缩短testdevelopement的时间,然后将这些情况组合起来测试流程。这些测试都需要初始设置,有时其他参数和某些信息应该通过流程进行。如何将它们插入到testmodul中而不将它们硬编码到模型中,因为它们应该可以更改以便重复使用。 由于测试用例不支持构造函数,参数化测试用例不是我想要的。

所以不喜欢 Running the same JUnit test case multiple time with different data 但是使用相同的数据源运行不同的JUnit测试用例。

有可能这样做,还是我走错了路?

如果有任何不清楚的地方请询问。 我真的很感激帮助。

问候 Tarken

2 个答案:

答案 0 :(得分:1)

让我们看看我是否正确理解了您的问题。您想为M1(testM1)定义测试,测试M2(testM2)测试M3(testM3)等。然后,您可以通过调用所有测试M1-> M2-> M3的组合测试方法testM1,testM2,testM3的顺序,但在这些方法之间传递一些任意数据。因此调用testM1,它会生成一些传递给testM2的数据,这会产生传递给testM3的数据。以下解决方案专为此而设计,但可以轻松扩展为包含类。

有两种方法可以做到这一点。最简单的方法是在类中定义一个@Rule,它将上下文存储在Suite类的静态字段中并更新它。如果扩展ExternalResource,可以执行以下操作:

private Context context;

@Rule
public ExternalResource resource= new ExternalResource() {
    @Override
    protected void before() throws Throwable {
        // get context from Suite class
        context = MySuite.getContext();
    };

    @Override
    protected void after() {
        // put context into Suite class
        MySuite.setContext(context);
    };
};

然后您的方法将正常使用该上下文。这在大多数情况下都有效,但会创建从测试到特定MySuite类的依赖。

更复杂的选项

您可以使用自定义@Suite课程与客户亚军进行此操作。我对How to define JUnit method rule in a suite?的回答显示了如何在特定方法之前和之后执行自定义代码(在这种情况下,使用@decrecreated注释)。

你需要做类似的事情。因此,您的Suite将为测试创建上下文,并且在执行特定测试方法之前,运行器从套件中检索上下文,在测试类中调用setter。测试方法使用该上下文,返回并且运行器从测试类检索上下文并更新套件类。存储上下文的显而易​​见的地方是套件,因为每次都会创建测试类本身。我认为尝试将上下文作为参数传递是太多的工作,你必须更改更多的代码。

所以在你的跑步者中,你会有像

这样的东西
public class MyRunner extends BlockJUnit4ClassRunner {
    private MySuite suite;

    public MyRunner(Class<?> klass, MySuite suite) throws InitializationError {
        super(klass);
        this.suite = suite;
    }

    @Override
    protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
        Description description= describeChild(method);
        if (method.getAnnotation(Ignore.class) != null) {
            notifier.fireTestIgnored(description);
        } else {
            // call suite.getContext()
            // call setContext() in class
            runLeaf(methodBlock(method), description, notifier);
            // call getContext() in class
            // call suite.setContext()
        }
    }
}

也可以覆盖前类行为。

答案 1 :(得分:-1)

使用BeforeClass