@BeforeClass注解:Junit与TestNG的区别

13
为什么在JUnit中@BeforeClass方法是static的,而在TestNG中是non-static的? TestNG是作为对JUnit的改进而开发的,所以为什么他们选择了这种实现方式?
由于@BeforeClass仅运行一次,因此将其设置为static比将其设置为非静态更有意义。此外,在调用@BeforeClass方法的TestNG实例上是什么?能否举个例子以更好地理解?

请注意,TestNG的注释是在JUnit之前开发的;TestNG是对JUnit v3.*的改进,但现在似乎它们大致相当,因为JUnit也有了注释(在JUnit v4.*中)。 - jpaugh
2个回答

16
JUnit和TestNG的主要区别在于测试类实例化方式。JUnit总是为每个测试方法运行创建一个新的测试类实例,而TestNG只创建一个测试类实例,然后运行该实例的所有测试方法。
JUnit的方法保证了所有测试方法的独立性,无论它们以何种顺序运行。此外,对于每个测试方法,所有实例字段始终设置相同。对于所有测试方法通用的数据初始化必须在类级别上进行,因此必须是静态的。这就是为什么@BeforeClass方法必须是静态的原因。
TestNG方法不保证独立性。事实上,在TestNG测试中,您无法像在JUnit测试中那样使用实例字段。如果您在一个测试方法中更改这样的字段,则在另一个测试方法中仍然可以观察到已更改的值。但是,这种行为也有一个优点:有时某些测试方法之间存在依赖关系。使用TestNG,测试人员可以表达它们。
由于TestNG的单个实例方法,@BeforeClass设置也可以是非静态方法,但仍仅运行一次。这是一个设计决策,但使用TestNG的测试人员必须意识到这一点。

3
在JUnit中,您可以使用实例字段并保持隔离,而在TestNG中则不行。如果您想破坏隔离,仍然可以在JUnit中使用静态字段……或者在TestNG中使用任何字段。如果TestNG用户想要保持测试的隔离,他们不会遇到任何问题。当他们想要创建依赖测试(无论原因是什么)时,问题就出现了,TestNG可以更好地支持它,尽管您必须知道其代价。将TestNG测试视为Servlet——您可以在那里准备东西,但它是共享的。这是好事还是坏事?这只是一个事实。 - virgo47
@virgo47 - 在"@BeforeClass"中初始化非静态类变量是否可以? - MasterJoe
嗯,你应该始终查阅文档并自己判断 - 但如果你相信我; 对于非静态,在JUnit和TestNG中都是一样的。 :-) (区别在于静态字段。)新年快乐。 - virgo47

1
使方法静态或非静态与只能在开始时调用该方法一次无关。您可以随意调用静态方法。您只能调用非静态方法一次。两者之间没有必要的相关性:静态和仅调用一次。至少,我不知道使方法静态的任何直接后果,使其能够被调用一次。 "static"正确地与单个类相关联,但与单个调用无关。使方法静态会防止它访问类的非静态成员。但是通过具有非静态的@BeforeClass方法,您也可以访问非静态成员,从而为您提供更多访问类变量的范围。也许这就是为什么testng删除了@BeforeClass方法必须是静态的限制的原因。

我的问题与一次或多次调用无关。 '@BeforeClass' 在测试用例开始时执行(而不是每个测试用例),因此它不能与任何实例相关联。 Junit为每个测试方法创建一个新的类实例。由于 '@beforeclass' 在testNG中是非静态的,因此必须将其与实例关联起来。这是否意味着在testNG中,@beforeclass会为每个测试执行?如果不是,那么它是如何工作的? - dejavu
@BeforeClass只是一个注释。Junit运行器只需要获取所有使用此方法注释的方法列表,并在执行每个测试之前执行它们一次。在testng中,@BeforeClass也仅为整个测试类执行一次。据我所知,Junit会反射地收集所有使用@Test注释的方法并调用它们。我不确定junit是否真的为每个测试用例创建了一个新实例。 - Shiva Kumar
它为每个测试用例创建一个新的实例:https://dev59.com/unNA5IYBdhLWcg3wNa6T#3353183 - dejavu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接