JUnit5的五大新特性

JUnit5的五个可能不知道的新特性

指定测试方法执行顺序

使用@TestMethodOrder(MethodOrderer.OrderAnnotation.class),然后使用@Order注解就可以指定一个类中方法执行的优先级,其中,数字越小,代表优先级越高。

    @TestMethodOrder(MethodOrderer.OrderAnnotation.class)
    public class OrderedExecutionTest {
 
  	@Test
  	@Order(2)
  	public void testTwo() {
    	System.out.println("Executing testTwo");
    	assertEquals(4, 2 + 2);
  	}
 
  	@Test
  	@Order(1)
  	public void testOne() {
    	System.out.println("Executing testOne");
    	assertEquals(4, 2 + 2);
  	}
 
  	@Test
  	@Order(3)
  	public void testThree() {
    	System.out.println("Executing testThree");
    	assertEquals(4, 2 + 2);
  	}
    }

内部类测试

对于日益增长的测试用例,在不好管理的情况下,JUnit5支持内部类的测试注解。

public class NestedTest {
 
  @Nested
  @DisplayName("Testing division functionality")
  class DivisionTests {
 
    @Test
    public void shouldDivideByTwo() {
      assertEquals(4, 8 / 2);
    }
 
    @Test
    public void shouldThrowExceptionForDivideByZero() {
      assertThrows(ArithmeticException.class, () -> {
        int result = 8 / 0;
      });
    }
  }
 
  @Nested
  @DisplayName("Testing addition functionality")
  class AdditionTests {
 
    @Test
    public void shouldAddTwo() {
      assertEquals(4, 2 + 2);
    }
 
    @Test
    public void shouldAddZero() {
      assertEquals(2, 2 + 0);
    }
  }
 
}

参数注入

可以在测试类的构造参数,或者测试方法支持参数注入。有内建的常用注解参数,也可以自定义。

//对于方法的这几个参数都是内建的
@RepeatedTest(5)
public void testMethodName(TestInfo testInfo, TestReporter testReporter, RepetitionInfo repetitionInfo) {
  System.out.println(testInfo.getTestMethod().get().getName());
  testReporter.publishEntry("secretMessage", "JUnit 5");
  System.out.println(repetitionInfo.getCurrentRepetition() + " from " + repetitionInfo.getTotalRepetitions());
}

对于自定的,需要实现接口ParameterResolver,使用的时候使用ExtendWith注解将实现类注入。

public class RandomUUIDParameterResolver implements ParameterResolver {
 
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.PARAMETER)
  public @interface RandomUUID {
  }
 
  @Override
  public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
    return parameterContext.isAnnotated(RandomUUID.class);
  }
 
  @Override
  public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
    return UUID.randomUUID().toString();
  }
 
}
//使用
@ExtendWith(RandomUUIDParameterResolver.class)
public class ParameterInjectionTest {
 
  @RepeatedTest(5)
  public void testUUIDInjection(@RandomUUID String uuid) {
    System.out.println("Random UUID: " + uuid);
  }
}

并行测试

从5.3版本开始支持并行测试,作为一个实验特性。可以通过在maven插件中配置属性,或者使用junit-platform.propertiessrc/test/resources路径下。

//属性
junit.jupiter.execution.parallel.enabled = true
junit.jupiter.execution.parallel.mode.default = concurrent
//maven配置中

  maven-surefire-plugin
  2.22.2
  
    
      
        junit.jupiter.execution.parallel.enabled = true
        junit.jupiter.execution.parallel.mode.default = concurrent
      
    
  

条件失效测试(Conditionally disable tests)

测试执行的时候,可以根据某些条件,选择那些测试方法不执行。可以是比如操作系统、或者不同环境之类的各种条件,同样的,有内置的部分,也可以自定义条件。

@Test
@DisabledOnOs(OS.LINUX)
public void disabledOnLinux() {
  assertEquals(42, 40 + 2);
}
 
@Test
@DisabledIfEnvironmentVariable(named = "FLAKY_TESTS", matches = "false")
public void disableFlakyTest() {
  assertEquals(42, 40 + 2);
}

自定义的,实现ExecutionCondition接口即可:

@Test
@DisabledOnMidnight
public void disabledOnMidNight() {
  assertEquals(42, 40 + 2);
}
//自定义的实现
public class DisabledOnMidnightCondition implements ExecutionCondition {
 
  private static final ConditionEvaluationResult ENABLED_BY_DEFAULT =
    enabled("@DisabledOnMidnight is not present");
 
  private static final ConditionEvaluationResult ENABLED_DURING_DAYTIME =
    enabled("Test is enabled during daytime");
 
  private static final ConditionEvaluationResult DISABLED_ON_MIDNIGHT =
    disabled("Disabled as it is around midnight");
 
  @Documented
  @Target({ElementType.TYPE, ElementType.METHOD})
  @Retention(RetentionPolicy.RUNTIME)
  @ExtendWith(DisabledOnMidnightCondition.class)
  public @interface DisabledOnMidnight {
  }
 
  @Override
  public ConditionEvaluationResult evaluateExecutionCondition(ExtensionContext context) {
    Optional optional = findAnnotation(context.getElement(), DisabledOnMidnight.class);
    if (optional.isPresent()) {
      LocalDateTime now = LocalDateTime.now();
      if (now.getHour() == 23 || now.getHour() <= 1) {
        return DISABLED_ON_MIDNIGHT;
      } else {
        return ENABLED_DURING_DAYTIME;
      }
    }
    return ENABLED_BY_DEFAULT;
  }
}

你可能感兴趣的:(java,junit5,junit,java)