测试调用:如何进行所有测试套件通用的设置

发布于 2024-12-18 06:28:48 字数 167 浏览 6 评论 0原文

有没有办法在 JUnit 4 测试类中知道该类是否由 Test-Suite 启动? 我想在所有测试之前运行全局的东西(关于内存数据库),所以我想在测试套件中执行它。但是,我仍然希望能够在没有测试服的情况下一次启动一个测试,所以我需要知道是否需要在测试的 @Before 部分中初始化全局事物...有人知道吗如果可能的话?

Is there a way to know in a JUnit 4 test Class, if the Class was initiated by a Test-Suite ?
I have global things that I want to run before all tests (regarding in-memory DB), so I thought doing it in the test-suit. However, I still want to be able to initiate one test at a time without a Test-Suit, So I need to know if I need to initialize the global things in the @Before part of the test... Does any-one know if it's possible ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

残月升风 2024-12-25 06:28:48

有多种方法可以实现这一目标。最简单的方法是在套件的开头和结尾运行一个“测试”,它设置数据库,然后设置全局标志。在 @Before 和 @After 测试中,您检查此标志,并在必要时进行设置/拆卸。

@RunWith(Suite.class)
@SuiteClasses({SetupTest.class, RealTest.class, TeardownTest.class});

这是最简单的解决方案,但它不是很好,所以一个更简洁的解决方案是使用 测试规则。查看扩展 ExternalResource。这实现了 before &在围绕您的测试方法的逻辑之后。这将允许您分解 @Before 和 @After 方法,以便在任何地方重用相同的代码。

然后,对于您的套件,您还需要实现之前/之后逻辑。不幸的是,用 @RunWith(Suite.class) 注解的类实际上并未实例化,因此您不能使用该类的构造函数,但您可以扩展 套件。根据您运行此程序的方式,您将需要实现其中一个构造函数,以 @RunWith 为例:

public class MySuite extends Suite {
    /**
     * Called reflectively on classes annotated with <code>@RunWith(Suite.class)</code>
     * 
     * @param klass the root class
     * @param builder builds runners for classes in the suite
     * @throws InitializationError
     */
    public MySuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
        this(builder, klass, getAnnotatedClasses(klass));
        // put your global setup here
        // set global variable
    }
}

然后运行您的测试套件

@RunWith(MySuite.class)

有几个构造函数用于不同的情况,请查看每个构造函数旁边的注释了解具体情况。您仍然需要使用全局变量,以便您的规则不会重新执行设置代码。如果您只想执行安装代码,则上面的方法将起作用,执行拆卸代码会更困难,但可以完成。如果您需要它,请告诉我:-)

如果您想要更大的灵活性(例如仅针对特定方法执行设置代码),请参阅我对 如何在套件中定义 JUnit 方法规则?

There are several ways to achieve this. The easiest and simplest is to have a 'test' which is run at the beginning and end of your suite which set up your database and then set a global flag. In your @Before and @After tests you check this flag and if necessary do the setup/teardown.

@RunWith(Suite.class)
@SuiteClasses({SetupTest.class, RealTest.class, TeardownTest.class});

This is the simplest solution, but it isn't very nice, so a neater solution would be to use a TestRule. Look at extending ExternalResource. This implements before & after logic which surrounds your test methods. This would allow you to factor out your @Before and @After methods, to reuse the same code everywhere.

Then, for your suite, you need to implement before/after logic as well. Unfortunately, the class annotated with @RunWith(Suite.class) isn't actually instantiated, so you can't use the constructor of that class, but you can extend Suite. Depending upon how you will run this, you will will need to implement one of the constructors, using @RunWith as an example:

public class MySuite extends Suite {
    /**
     * Called reflectively on classes annotated with <code>@RunWith(Suite.class)</code>
     * 
     * @param klass the root class
     * @param builder builds runners for classes in the suite
     * @throws InitializationError
     */
    public MySuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {
        this(builder, klass, getAnnotatedClasses(klass));
        // put your global setup here
        // set global variable
    }
}

Then run your test suite with

@RunWith(MySuite.class)

There are several constructors which are used in different situations, look at the comments next to each for specifics. You still need to use a global variable so that your Rules don't re-execute the setup code. The above will work if you're wanting to execute only setup code, executing teardown code is harder, but can be done. Let me know if you need it :-)

If you're wanting more flexibility (say executing setup code only for specific methods), then see my answer to How to define JUnit method rule in a suite?.

丶视觉 2024-12-25 06:28:48

我会使用 JUnit 的 @BeforeClass@AfterClass 注释来指示执行此类工作的方法。

来自 @BeforeClass Javadoc:

有时多个测试需要共享计算成本高昂的设置
(就像登录数据库一​​样)。虽然这可能会损害
测试的独立性,有时这是必要的优化。
使用 @BeforeClass 注释 public static void no-arg 方法会导致
它在类中的任何测试方法之前运行一次。这
超类的 @BeforeClass 方法将在超类的方法之前运行
当前班级。

I would use JUnit's @BeforeClass and @AfterClass annotations to indicate methods to do this type of work.

From the @BeforeClass Javadoc:

Sometimes several tests need to share computationally expensive setup
(like logging into a database). While this can compromise the
independence of tests, sometimes it is a necessary optimization.
Annotating a public static void no-arg method with @BeforeClass causes
it to be run once before any of the test methods in the class. The
@BeforeClass methods of superclasses will be run before those the
current class.

离线来电— 2024-12-25 06:28:48

您可以在每个测试套件中放置一些 @BeforeClass 代码,该代码委托给执行公共设置的辅助类。辅助类可以有一个静态布尔值来记录设置是否已经完成。如果已经完成,辅助类将不执行任何操作。

You could place some @BeforeClass code in each test suite, which delegates to an auxiliary class that does the common set up. The auxiliary class could have a static boolean that records whether the set up has already been done. If it has already been done, the auxiliary class would do nothing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文