JUnit 5-为整个测试套件提供设置和拆卸 [英] JUnit 5 - Providing setUp and tearDown for an entire Test Suite

查看:636
本文介绍了JUnit 5-为整个测试套件提供设置和拆卸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的要求是对一组测试进行一些初始化,并在所有测试完成后将其清除.这些测试涵盖了一些测试类,因为它们之间的关系并不密切,但是需要共同的初始化.

我正在使用@SelectClasses形成套件,并尝试使用应该处理预处理和后处理的自定义扩展来使用@ExtendWith.这不起作用,我不确定JUnit中是否存在适当的解决方案.共享已经尝试过的示例代码.

套房:

@SelectClasses({FirstTest.class, SecondTest.class})
@ExtendWith(SuiteExtension.class)
@RunWith(JUnitPlatform.class)
@SuiteDisplayName("test suite")
public class SuiteClass {
}

扩展名:

public class SuiteExtension implements BeforeAllCallback, AfterAllCallback {

    @Override
    public void afterAll(ExtensionContext context) throws Exception {
        System.out.println("afterAll");
    }

    @Override
    public void beforeAll(ExtensionContext context) throws Exception {
        System.out.println("beforeAll");
    }
}

测试类别1:

public class FirstTest {

    @Test
    void test1(){
        System.out.println("test1");
    }
}

测试类别2:

public class SecondTest {

    @Test
    void test2(){
        System.out.println("test2");
    }
}

输出:

test1
test2

预期输出:

beforeAll
test1
test2
afterAll

解决方案

不支持将@RunWith(来自JUnit 4)和@ExtendWith(来自JUnit Jupiter)组合:这是来自两个不同框架的扩展机制.

从技术上讲,您的SuiteClass是JUnit 4测试类.因此,JUnit Jupiter将不会为其注册或执行任何扩展.

关于JUnit 5中的 suites ,我们(JUnit团队)计划为不需要JUnit 4 Runner 的套件提供一流的支持(即@RunWith(JUnitPlatform.class)).查看所有以了解详细信息.随时观看和/或评论任何这些问题.

在此期间,我相信在JUnit Jupiter中实现套件前后"支持最接近的一种方法是实现实现BeforeAllCallbackAfterAllCallback的自定义扩展.该扩展名需要通过将标志存储在 root ExtensionContext Store(作为BeforeAllCallback)中来跟踪它是否已经被调用,以便仅执行一次在套件"之前.同样,它需要计算要为其执行的类的数量,并在 root Store中对其进行跟踪.这将用作StackCountDownLatch.作为AfterAllCallback,扩展将需要减少全局计数器,并且仅在所有测试类完成后才执行.

您显然需要确保为套件的每个测试类注册了套件扩展.定制的注释可能会简化您的工作.

现在,坦率地说,我只是在脑海中实现了该功能,但还没有实际编码这样的"suite"扩展名.因此,如果您实际实现它,那么我很想听听您的经验并可能会看到您的代码. ;-)

干杯

Sam(JUnit 5的核心提交者)

My requirement is to have some initialization done for a set of tests and clear it off once all the tests are complete. These tests spin over a few test classes as they are not closely related, but require a common initialization.

I am using @SelectClasses to form the suite and trying to make use of @ExtendWith using a custom extension that should handle the pre and post processing. This does not work and I am unsure if an appropriate solution exists in JUnit. Sharing the sample code of what was already attempted.

Suite:

@SelectClasses({FirstTest.class, SecondTest.class})
@ExtendWith(SuiteExtension.class)
@RunWith(JUnitPlatform.class)
@SuiteDisplayName("test suite")
public class SuiteClass {
}

Extension:

public class SuiteExtension implements BeforeAllCallback, AfterAllCallback {

    @Override
    public void afterAll(ExtensionContext context) throws Exception {
        System.out.println("afterAll");
    }

    @Override
    public void beforeAll(ExtensionContext context) throws Exception {
        System.out.println("beforeAll");
    }
}

Test Class 1:

public class FirstTest {

    @Test
    void test1(){
        System.out.println("test1");
    }
}

Test Class 2:

public class SecondTest {

    @Test
    void test2(){
        System.out.println("test2");
    }
}

Output:

test1
test2

Expected Output:

beforeAll
test1
test2
afterAll

解决方案

Combining @RunWith (from JUnit 4) and @ExtendWith (from JUnit Jupiter) is not supported: those are extension mechanisms from two different frameworks.

Technically speaking, your SuiteClass is a JUnit 4 test class. Thus JUnit Jupiter will not register or execute any extensions for it.

With regard to suites in JUnit 5, we (the JUnit Team) have plans to provide first-class support for suites that do not require a JUnit 4 Runner (i.e., @RunWith(JUnitPlatform.class)). See all GitHub issues labeled with "suites" for details. Feel free to watch and/or comment on any of those issues.

In the interim, I believe the closest one could come to implementing "before and after suite" support in JUnit Jupiter would be to implement a custom extension that implements BeforeAllCallback and AfterAllCallback. That extension would need to track whether it has already been invoked by storing a flag in the root ExtensionContext Store (as a BeforeAllCallback), so that it only executes once before the "suite". Similarly, it would need to count the number of classes it is executed for and track that in the root Store. This would serve as a Stack or CountDownLatch. As an AfterAllCallback, the extension would need to decrement the global counter and only execute once all test classes have completed.

You'd obviously need to ensure that your suite extension is registered for each test class that belongs to the suite. Perhaps a custom composed annotation would simplify matters for you there.

Now, admittedly, I just implemented that in my head but have not yet actually coded such a "suite" extension. So if you actually implement it, I'd be interested in hearing about your experience and possibly seeing your code. ;-)

Cheers,

Sam (core committer for JUnit 5)

这篇关于JUnit 5-为整个测试套件提供设置和拆卸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆