赛程

来自维基百科

测试夹具用于一致地测试某些项目,设备或软件。

它还可以通过从测试方法本身中提取常见的初始化/完成代码来增强测试的可读性。

在常规初始化可以执行一次而不是在每次测试之前,这也可以减少运行测试所花费的时间。

以下示例旨在显示 JUnit 提供的主要选项。假设类 Foo 初始化很昂贵:

public class Foo {
    public Foo() {
        // expensive initialization
    }

    public void cleanUp() {
        // cleans up resources
    }
}

另一类 Bar 引用了 Foo

public class Bar {
    private Foo foo;
    
    public Bar(Foo foo) {
        this.foo = foo;
    }

    public void cleanUp() {
        // cleans up resources
    }
}

下面的测试需要一个包含单个 Bar 的 List 的初始上下文。

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import java.util.Arrays;
import java.util.List;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class FixturesTest {
    
    private static Foo referenceFoo;
    
    private List<Bar> testContext;
    
    @BeforeClass
    public static void setupOnce() {
        // Called once before any tests have run
        referenceFoo = new Foo();
    }

    @Before
    public void setup() {
        // Called before each test is run
        testContext = Arrays.asList(new Bar(referenceFoo));
    }
    
    @Test
    public void testSingle() {
        assertEquals("Wrong test context size", 1, testContext.size());
        Bar baz = testContext.get(0);
        assertEquals(referenceFoo, baz.getFoo());
    }
    
    @Test
    public void testMultiple() {
        testContext.add(new Bar(referenceFoo));
        assertEquals("Wrong test context size", 2, testContext.size());
        for (Bar baz : testContext) {
            assertEquals(referenceFoo, baz.getFoo());
        }
    }
    
    @After
    public void tearDown() {
        // Called after each test is run
        for (Bar baz : testContext) {
            baz.cleanUp();
        }
    }
    
    @AfterClass
    public void tearDownOnce() {
        // Called once after all tests have run
        referenceFoo.cleanUp();
    }
}

在示例中,@BeforeClass 注释方法 setupOnce() 用于创建 Foo 对象,初始化起来很昂贵。重要的是它不能被任何测试修改,否则测试运行的结果可能取决于各个测试的执行顺序。这个想法是每个测试都是独立的,并测试一个小功能。

@Before 注释方法 setup() 设置测试上下文。在测试执行期间可以修改上下文,这就是为什么必须在每次测试之前初始化它。通过在每个测试方法的开头包含此方法中包含的代码,可以实现等效的效果。

@After 注释方法 tearDown() 清理测试环境中的资源。它在每次测试调用后调用,因此通常用于释放在 @Before 注释方法中分配的资源。

所有测试运行后,@AfterClass 注释方法 tearDownOnce() 清理资源。这些方法通常用于释放在初始化期间或在注释方法中分配的资源。也就是说,最好避免在单元测试中使用外部资源,这样测试就不依赖于测试类之外的任何东西。