简体   繁体   English

Junit 测试在后台如何工作?

[英]How does Junit test work in the background?

I just started with Junit Testing very recently, so please excuse me if my terminology is not correct.我最近才开始使用 Junit 测试,所以如果我的术语不正确,请见谅。 As far as I know, the methods become a test method if we annotate it with a @test and we can run it with an IDE(I am using Intellij) by clicking on the play button next to it.据我所知,如果我们用@test 注释它,这些方法就变成了一个测试方法,我们可以通过单击旁边的播放按钮来使用 IDE(我正在使用 Intellij)运行它。 In the background, it probably instantiates an instance of the Test class and run the selected method.在后台,它可能会实例化 Test 类的一个实例并运行选定的方法。 My question is, in the example below, if test1 and test2 both use and edit the same hello string of the same instance of the Test class, since test2 runs after test1, it should print the edited version of the hello String?我的问题是,在下面的例子中,如果 test1 和 test2 都使用和编辑 Test 类的同一个实例的同一个 hello 字符串,因为 test2 在 test1 之后运行,它应该打印 hello 字符串的编辑版本? ie: test2 should print "1".即:test2 应该打印“1”。 But in this case it prints an empty String.但在这种情况下,它打印一个空字符串。 Why is this ?为什么是这样 ?

class Test{
   private  String hello = "";

   @Test
   void test1() {
      hello = hello + "1";
      System.out.println(hello);
   }
   @Test
   void test2() {
      System.out.println(hello)
   }
}

This happens due to the lifecycle of the test.这是由于测试的生命周期而发生的。 You've guessed correctly, indeed JUnit instantiates the Class of the test ( class Test in this case).您已经猜对了,确实 JUnit 实例化了测试的类(在本例中为class Test )。

In other words somewhere in the code of JUnit there is a line: Test test = new Test() (in the real code it uses reflection, but it doesn't matter for the sake of the question).换句话说,在 JUnit 代码的某处有一行: Test test = new Test() (在实际代码中它使用反射,但就问题而言这无关紧要)。

Then it runs the test methods, so far so good - you were right:然后它运行测试方法,到目前为止一切顺利 - 你是对的:

Test test = new Test();

test.test1();

test.test2();
// handle failures, exceptions, etc.

However, JUnit is designed in a way that it instantiates the class of test before running every single test method .但是, JUnit 的设计方式是在运行每个测试方法之前实例化测试类 This is a design decision of the JUnit framework.这是 JUnit 框架的设计决策。

So, the "more accurate" representation of what happens in JUnit looks like this:因此,JUnit 中发生的事情的“更准确”表示如下所示:

Test test = new Test();

test.test1();

....

test = new Test();

test.test2();

This is a default behavior of JUnit, all the data fields get instantiated over and over again for each test and it guarantees that test1 prints 1 and test2 prints an empty string.这是 JUnit 的默认行为,所有数据字段都会为每个测试一遍又一遍地实例化,并保证test1打印1并且test2打印空字符串。

This happens regardless the order of actual tests execution.无论实际测试执行的顺序如何,都会发生这种情况。

Now, this behavior can be altered by using @TestInstance(LifeCycle.PER_CLASS) annotation on the test class, but its a pretty advanced stuff.现在,可以通过在测试类上使用@TestInstance(LifeCycle.PER_CLASS)注释来改变这种行为,但它是一个非常高级的东西。 It will instruct the JUnit engine to create only one single object of class Test and run all the test methods in it.它将指示 JUnit 引擎仅创建 Test 类的一个对象并运行其中的所有测试方法。 So if one test method will change the data field defined in the class Test the other test will actually see this change.因此,如果一个测试方法将更改Test类中定义的数据字段,则另一个测试实际上会看到此更改。

If you're interested to learn more about @TestInstance - consider reading this article for example如果您有兴趣了解有关@TestInstance更多信息 -例如,请考虑阅读这篇文章

In most case Unit tests should not depend on the order or execution.在大多数情况下,单元测试不应依赖于顺序或执行。

By default JUnit won't guaranty you an order of execution, in this case test1 could be executed after or before test2 .默认情况下,JUnit 不会保证您的执行顺序,在这种情况下, test1可以在test2之后或之前执行。

For tests you can use @BeforeEach or @BeforeAll to execute some code before your tests.对于测试,您可以使用@BeforeEach@BeforeAll在测试之前执行一些代码。

Also you can use @Order(1) to run force the test order.您也可以使用@Order(1)来运行强制测试订单。 However I would strongly advocate again it except in really specific case.但是我会再次强烈主张它,除非在真正的特定情况下。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM