如何构建可配置的JUnit4测试套件?

Lou*_*man 20 java junit junit4

Guava对用JUnit3编写的集合实现进行了大量测试,如下所示:

/*
 * Copyright (C) 2008 The Guava Authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
public class CollectionRemoveTester<E> extends AbstractTester<E> {

  @CollectionFeature.Require(SUPPORTS_REMOVE)
  @CollectionSize.Require(absent = ZERO)
  public void testRemove_present() {
     ...
  }
}
Run Code Online (Sandbox Code Playgroud)

然后使用TestSuiteBuilder传入集合类型的一组特性和生成器的s 来测试不同的集合,并且反射性框架标识要运行的测试方法集.

我想在JUnit4中构建一些类似的东西,但我不清楚如何去做:构建我自己的东西Runner?理论?到目前为止,我最好的猜测是写一些像

abstract class AbstractCollectionTest<E> {
   abstract Collection<E> create(E... elements);
   abstract Set<Feature> features();

   @Test
   public void removePresentValue() {
      Assume.assumeTrue(features().contains(SUPPORTS_REMOVE));
      ...
   }
}

@RunWith(JUnit4.class)
class MyListImplTest<E> extends AbstractCollectionTest<E> {
  // fill in abstract methods
}
Run Code Online (Sandbox Code Playgroud)

一般问题是这样的:在JUnit4中,我可以如何为接口类型构建一套测试,然后将这些测试应用于单个实现?

bor*_*jab 5

在Junit中,您可以使用类别.例如,这个套件将从注释为集成的AllTestSuite执行al test:

import org.junit.experimental.categories.Categories;
import org.junit.experimental.categories.Categories.IncludeCategory;
import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Categories.class)
@IncludeCategory(Integration.class)
@Suite.SuiteClasses ({AllTestsSuite.class} )
public class IntegrationTestSuite {}
Run Code Online (Sandbox Code Playgroud)

您也可以使用@ExcludeCategory.这对于删除慢速测试很有用.类别类只是普通的旧Java类或接口.例如:

public interface Integration{}
public interface Performance{}
public interface Slow{}
public interface Database{}
Run Code Online (Sandbox Code Playgroud)

您只需要依次调整测试:

@Category(Integration.class)
public class MyTest{

   @Test
   public void myTest__expectedResults(){
   [...]
Run Code Online (Sandbox Code Playgroud)

一个测试可能有多个这样的类别:

   @Category({Integration.class,Database.class})  
   public class MyDAOTest{
Run Code Online (Sandbox Code Playgroud)

为简单起见,我通常使用google工具箱创建一个包含测试文件夹中所有类的套件:

import org.junit.runner.RunWith;

import com.googlecode.junittoolbox.ParallelSuite;
import com.googlecode.junittoolbox.SuiteClasses;

@RunWith(ParallelSuite.class)
@SuiteClasses({"**/**.class",           //All classes
             enter code here  "!**/**Suite.class" })    //Excepts suites
public class AllTestsSuite {}
Run Code Online (Sandbox Code Playgroud)

这包括在AllTestSuite中包含相同文件夹和子文件夹中的所有类,即使它们没有_Test修复程序也是如此.但是无法看到不在同一文件夹或子文件夹中的测试.junit-toolbox在Maven中可用:

<dependency>
    <groupId>com.googlecode.junit-toolbox</groupId>
    <artifactId>junit-toolbox</artifactId>
    <version>2.2</version>
</dependency>
Run Code Online (Sandbox Code Playgroud)

现在您只需要执行适合您需求的套件:)

更新:在Spring中有@IfProfileValue注释,允许您有条件地执行测试,如:

@IfProfileValue(name="test-groups", values={"unit-tests", "integration-tests"})
@Test
public void testProcessWhichRunsForUnitOrIntegrationTestGroups() {
Run Code Online (Sandbox Code Playgroud)

有关更多信息,请参阅Spring JUnit测试注释