何时在JunitTests中使用@BeforeClass?

时间:2015-10-02 16:48:42

标签: java unit-testing testing junit

@BeforeClass对我来说真的没有意义。该方法中的所有内容都将在所有测试用例之前执行。但是,我们不能简单地在测试类的开头编写它并产生相同的效果吗?

2 个答案:

答案 0 :(得分:4)

你可以“技术上”做同样的事情,但是你在幕后有不同的行为,因为 @BeforeClass由JUnit 处理,而静态块或类初始化程序中的标准java代码被处理由JVM。

您可以将@BeforeClass与jvm静态块进行“比较”,但JUnit会调用 @BeforeClass,而JVM会调用静态块。

如果初始化程序(JUnit或JVM)出现故障,则会出现其他错误。

由JUnit处理

public class TestCase {
    static private int number;

    @BeforeClass
    public static void init(){
        number = 1/0; // Makes a failure
    }
}
// THROWS THIS STACK TRACE
java.lang.ArithmeticException: / by zero
    at com.creditsesame.integration.util.GenericUtilsTest.test(GenericUtilsTest.java:26)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)

Maven测试目标输出

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.005 sec <<< FAILURE! - in com.fede.TestCase 
com.fede.TestCase  Time elapsed: 0.005 sec  <<< ERROR!
java.lang.ArithmeticException: / by zero
        at com.fede.TestCase.init(TestCase.java:24)


Results :

Tests in error:
  TestCase.init:24 Arithmetic / by zero

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 13.864 s
[INFO] Finished at: 2015-10-02T11:35:32-06:00
[INFO] Final Memory: 33M/448M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test (default-test) on project integration: There are test failures.
[ERROR]
[ERROR] Please refer to E:\Project\workspace\fede\target\surefire-reports for the individual test results.
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

由JVM处理

public class TestCase {
    static int i=1/0; // Makes a failure

    @BeforeClass
    public static void init(){
        number = 1/0; 
    }
}

// THROWS THIS STACK TRACE
java.lang.ExceptionInInitializerError
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
    at java.lang.reflect.Method.invoke(Unknown Source)
Caused by: java.lang.ArithmeticException: / by zero

Maven测试目标输出

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.008 sec - in com.fede.TestCase

Results :

Tests run: 1, Failures: 0, Errors: 1, Skipped: 0

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 01:09 min
[INFO] Finished at: 2015-10-02T11:34:02-06:00
[INFO] Final Memory: 28M/607M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.18.1:test (default-test) on project integration: ExecutionException: java.lang.RuntimeException: There was an error in the forked process
[ERROR] java.lang.ExceptionInInitializerError
[ERROR] at java.lang.Class.forName0(Native Method)
[ERROR] at java.lang.Class.forName(Class.java:191)
[ERROR] at org.junit.runner.Description.getTestClass(Description.java:206)
[ERROR] at org.apache.maven.surefire.common.junit48.FilterFactory$GroupMatcherCategoryFilter.shouldRun(FilterFactory.java:281)
[ERROR] at org.apache.maven.surefire.common.junit48.FilterFactory$GroupMatcherCategoryFilter.shouldRun(FilterFactory.java:227)
[ERROR] at org.junit.runners.ParentRunner.shouldRun(ParentRunner.java:299)
[ERROR] at org.junit.runners.ParentRunner.filter(ParentRunner.java:254)
[ERROR] at org.junit.runner.manipulation.Filter.apply(Filter.java:79)
[ERROR] at org.apache.maven.surefire.junitcore.JUnitCoreWrapper$FilteringRequest.<init>(JUnitCoreWrapper.java:139)
[ERROR] at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.createRequestAndRun(JUnitCoreWrapper.java:100)
[ERROR] at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.executeEager(JUnitCoreWrapper.java:78)
[ERROR] at org.apache.maven.surefire.junitcore.JUnitCoreWrapper.execute(JUnitCoreWrapper.java:54)
[ERROR] at org.apache.maven.surefire.junitcore.JUnitCoreProvider.invoke(JUnitCoreProvider.java:144)
[ERROR] at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:203)
[ERROR] at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:155)
[ERROR] at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:103)
[ERROR] Caused by: java.lang.ArithmeticException: / by zero
[ERROR] at com.creditsesame.integration.util.GenericUtilsTest.<clinit>(GenericUtilsTest.java:22)
[ERROR] ... 16 more
[ERROR] -> [Help 1]
[ERROR]
[ERROR] To see the full stack trace of the errors, re-run Maven with the -e switch.
[ERROR] Re-run Maven using the -X switch to enable full debug logging.
[ERROR]
[ERROR] For more information about the errors and possible solutions, please read the following articles:
[ERROR] [Help 1] http://cwiki.apache.org/confluence/display/MAVEN/MojoFailureException

JUnit评论

当您使用@BeforeClass进行批注时,该方法仅执行一次,这对于您希望仅执行一次的初始化/记录非常有用。您可以查看解释此here的非常有用的链接。与@Before的区别在于它是在每个测试用例之后执行的。

看一下这个例子:

package com.javacodegeeks.junit;

import static org.junit.Assert.*;
import java.util.ArrayList;
import org.junit.*;

public class JunitTestExample {

    private ArrayList testList;

            @BeforeClass
            public static void onceExecutedBeforeAll() {
                System.out.println("@BeforeClass: onceExecutedBeforeAll");
            }

            @Before
            public void executedBeforeEach() {
                testList = new ArrayList();
                System.out.println("@Before: executedBeforeEach");
            }

            @Test
            public void EmptyCollection() {
                assertTrue(testList.isEmpty());
                System.out.println("@Test: EmptyArrayList");

            }

            @Test
            public void OneItemCollection() {
                testList.add("oneItem");
                assertEquals(1, testList.size());
                System.out.println("@Test: OneItemArrayList");
            }
}

输出将是:

@BeforeClass: onceExecutedBeforeAll
@Before: executedBeforeEach
@Test: EmptyArrayList
@Before: executedBeforeEach
@Test: OneItemArrayList

您可以在@BeforeClass vs static{}

中找到详细说明

答案 1 :(得分:0)

在课程开始时我不确定你的意思&#39;, 但@BeforeClass方法可用于初始化一组测试用例。

想象一下,某种初始化非常耗时,并且对于许多测试用例来说都是一样的。你不想重复那么多次因为这会使整个测试运行得太久。