[java] 매개 변수화 된 테스트 이름 변경

JUnit4에서 매개 변수화 된 테스트를 사용할 때 고유 한 사용자 정의 테스트 케이스 이름을 설정하는 방법이 있습니까?

기본값 [Test class].runTest[n]을 의미있는 것으로 변경하고 싶습니다 .



답변

이 기능은 JUnit 4.11 로 만들어졌습니다 .

매개 변수가 지정된 테스트의 이름을 변경하려면 다음과 같이 말합니다.

@Parameters(name="namestring")

namestring 문자열은 다음과 같은 특수 자리 표시자를 가질 수 있습니다.

  • {index}-이 인수 세트의 인덱스 기본값 namestring{index}입니다.
  • {0} -이 테스트 호출의 첫 번째 매개 변수 값
  • {1} -두 번째 매개 변수 값
  • 등등

테스트의 최종 이름은 namestring아래에 표시된대로 테스트 방법의 이름이며 뒤에 괄호 가 붙습니다 .

예를 들어 ( Parameterized주석에 대한 단위 테스트에서 수정 ) :

@RunWith(Parameterized.class)
static public class FibonacciTest {

    @Parameters( name = "{index}: fib({0})={1}" )
    public static Iterable<Object[]> data() {
        return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 },
                { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } });
    }

    private final int fInput;
    private final int fExpected;

    public FibonacciTest(int input, int expected) {
        fInput= input;
        fExpected= expected;
    }

    @Test
    public void testFib() {
        assertEquals(fExpected, fib(fInput));
    }

    private int fib(int x) {
        // TODO: actually calculate Fibonacci numbers
        return 0;
    }
}

이름이 같은 줄 것이다 testFib[1: fib(1)=1]testFib[4: fib(4)=3]. testFib이름 의 일부는의 메소드 이름입니다 @Test.


답변

JUnit 4.5를 살펴보면 해당 러너는 로직이 Parameterized 클래스의 개인 클래스에 묻혀 있기 때문에이를 지원하지 않습니다. JUnit Parameterized 러너를 사용할 수 없으며 대신 이름의 개념을 이해하는 이름을 직접 만들 수 있습니다 (이름을 설정하는 방법에 대한 질문으로 이어짐).

JUnit 관점에서 증분을 전달하는 대신 쉼표로 구분 된 인수를 전달하는 것이 좋습니다. TestNG가이를 수행합니다. 이 기능이 중요한 경우 www.junit.org에서 참조하는 yahoo 메일 링리스트에 의견을 남길 수 있습니다.


답변

JUnit 4.3.1을 사용할 때 최근에 동일한 문제가 발생했습니다. LabelledParameterized라는 Parameterized를 확장하는 새로운 클래스를 구현했습니다. JUnit 4.3.1, 4.4 및 4.5를 사용하여 테스트되었습니다. @Parameters 메서드에서 각 매개 변수 배열의 첫 번째 인수에 대한 String 표현을 사용하여 Description 인스턴스를 재구성합니다. 이 코드는 다음에서 확인할 수 있습니다.

http://code.google.com/p/migen/source/browse/trunk/java/src/…/LabelledParameterized.java?r=3789

그리고 그 사용 예 :

http://code.google.com/p/migen/source/browse/trunk/java/src/…/ServerBuilderTest.java?r=3789

테스트 설명은 Eclipse에서 멋지게 형식화되어 실패한 테스트를 훨씬 쉽게 찾을 수 있기 때문에 원했습니다. 다음 며칠 / 주 동안 수업을 더 세분화하고 문서화 할 것입니다. ‘?’를 삭제하십시오. 출혈 가장자리를 원할 경우 URL의 일부입니다. 🙂

사용하려면 해당 클래스 (GPL v3)를 복사하고 매개 변수 목록의 첫 번째 요소가 합리적인 레이블이라고 가정하고 @RunWith (Parameterized.class)를 @RunWith (LabelledParameterized.class)로 변경하면됩니다.

JUnit의 이후 릴리스 에서이 문제를 해결하는지 알 수는 없지만, 공동 개발자가 모두 업데이트해야하고 재 툴링보다 우선 순위가 높기 때문에 JUnit을 업데이트 할 수 없습니다. 따라서 클래스의 작업은 여러 버전의 JUnit에서 컴파일 할 수 있습니다.


참고 : 위에 나열된 것과 같이 다른 JUnit 버전에서 실행되도록 일부 리플렉션 jiggery-pokery가 있습니다. 구체적의 JUnit 4.3.1 버전이 발견 될 수있다 여기서 , JUnit을 4.4 및 4.5 그리고 여기 .


답변

Parameterized모델로, 나는 내 자신의 사용자 정의 테스트 러너 / 제품군을 썼다 – 절반 밖에 시간 정도 걸렸다. darrenp와는 약간 다르 LabelledParameterized므로 첫 번째 매개 변수에 의존하지 않고 명시 적으로 이름을 지정할 수 있습니다 toString().

배열을 싫어하기 때문에 배열을 사용하지 않습니다. 🙂

public class PolySuite extends Suite {

  // //////////////////////////////
  // Public helper interfaces

  /**
   * Annotation for a method which returns a {@link Configuration}
   * to be injected into the test class constructor
   */
  @Retention(RetentionPolicy.RUNTIME)
  @Target(ElementType.METHOD)
  public static @interface Config {
  }

  public static interface Configuration {
    int size();
    Object getTestValue(int index);
    String getTestName(int index);
  }

  // //////////////////////////////
  // Fields

  private final List<Runner> runners;

  // //////////////////////////////
  // Constructor

  /**
   * Only called reflectively. Do not use programmatically.
   * @param c the test class
   * @throws Throwable if something bad happens
   */
  public PolySuite(Class<?> c) throws Throwable {
    super(c, Collections.<Runner>emptyList());
    TestClass testClass = getTestClass();
    Class<?> jTestClass = testClass.getJavaClass();
    Configuration configuration = getConfiguration(testClass);
    List<Runner> runners = new ArrayList<Runner>();
    for (int i = 0, size = configuration.size(); i < size; i++) {
      SingleRunner runner = new SingleRunner(jTestClass, configuration.getTestValue(i), configuration.getTestName(i));
      runners.add(runner);
    }
    this.runners = runners;
  }

  // //////////////////////////////
  // Overrides

  @Override
  protected List<Runner> getChildren() {
    return runners;
  }

  // //////////////////////////////
  // Private

  private Configuration getConfiguration(TestClass testClass) throws Throwable {
    return (Configuration) getConfigMethod(testClass).invokeExplosively(null);
  }

  private FrameworkMethod getConfigMethod(TestClass testClass) {
    List<FrameworkMethod> methods = testClass.getAnnotatedMethods(Config.class);
    if (methods.isEmpty()) {
      throw new IllegalStateException("@" + Config.class.getSimpleName() + " method not found");
    }
    if (methods.size() > 1) {
      throw new IllegalStateException("Too many @" + Config.class.getSimpleName() + " methods");
    }
    FrameworkMethod method = methods.get(0);
    int modifiers = method.getMethod().getModifiers();
    if (!(Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
      throw new IllegalStateException("@" + Config.class.getSimpleName() + " method \"" + method.getName() + "\" must be public static");
    }
    return method;
  }

  // //////////////////////////////
  // Helper classes

  private static class SingleRunner extends BlockJUnit4ClassRunner {

    private final Object testVal;
    private final String testName;

    SingleRunner(Class<?> testClass, Object testVal, String testName) throws InitializationError {
      super(testClass);
      this.testVal = testVal;
      this.testName = testName;
    }

    @Override
    protected Object createTest() throws Exception {
      return getTestClass().getOnlyConstructor().newInstance(testVal);
    }

    @Override
    protected String getName() {
      return testName;
    }

    @Override
    protected String testName(FrameworkMethod method) {
      return testName + ": " + method.getName();
    }

    @Override
    protected void validateConstructor(List<Throwable> errors) {
      validateOnlyOneConstructor(errors);
    }

    @Override
    protected Statement classBlock(RunNotifier notifier) {
      return childrenInvoker(notifier);
    }
  }
}

그리고 예 :

@RunWith(PolySuite.class)
public class PolySuiteExample {

  // //////////////////////////////
  // Fixture

  @Config
  public static Configuration getConfig() {
    return new Configuration() {
      @Override
      public int size() {
        return 10;
      }

      @Override
      public Integer getTestValue(int index) {
        return index * 2;
      }

      @Override
      public String getTestName(int index) {
        return "test" + index;
      }
    };
  }

  // //////////////////////////////
  // Fields

  private final int testVal;

  // //////////////////////////////
  // Constructor

  public PolySuiteExample(int testVal) {
    this.testVal = testVal;
  }

  // //////////////////////////////
  // Test

  @Ignore
  @Test
  public void odd() {
    assertFalse(testVal % 2 == 0);
  }

  @Test
  public void even() {
    assertTrue(testVal % 2 == 0);
  }

}


답변

junit4.8.2부터는 단순히 Parameterized 클래스를 복사하여 MyParameterized 클래스를 작성할 수 있습니다. TestClassRunnerForParameters에서 getName () 및 testName () 메소드를 변경하십시오.


답변

JUnitParams를 시도 할 수도 있습니다 : http://code.google.com/p/junitparams/


답변

당신은 같은 방법을 만들 수 있습니다

@Test
public void name() {
    Assert.assertEquals("", inboundFileName);
}

항상 사용하지는 않지만 정확히 143의 테스트 번호를 알아내는 것이 유용합니다.