Параметрированные тесты JUnit5 на уровне класса

Можно ли использовать параметризованные новые функции JUnit5 для запуска тестовых классов для получения тестовых параметров вместо того, чтобы делать это на уровне метода?

С JUnit 4 бегун, такой как @RunWith(Parameterized::class) плюс наследование, может использоваться для передачи массива параметров в подклассы, но я не уверен, что можно добиться чего-то эквивалентного, но используя новый JUnit 5 api.

Ответ 1

JUnit 5 имеет свой собственный подход для создания параметризованных тестов, и, конечно, он отличается от JUnit 4. Новый подход не позволяет использовать параметризованные приборы на уровне класса, т.е. Через каждый метод тестирования. Таким образом, каждый параметризованный метод тестирования должен быть явно помечен ссылкой на параметры.

JUnit 5 предоставляет множество типов источников параметров, которые можно найти в документации и руководствах

В вашем случае самый простой способ перехода с @Parameters из Junit 4 - это использовать @MethodSource или @ArgumentsSource из org.junit.jupiter.params.provider.*.

JUnit 4:

@RunWith(Parameterized.class)
public class MyTestWithJunit4 {
    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {     
                 { 0, 0, 0 }, { 1, 2, 3 }, { 5, 3, 8 } 
        });
    }

    int first;
    int second;
    int sum;

    public MyTestWithJunit4(int first, int second, int sum) {
        this.first = first;
        this.second = second;
        this.sum = sum;
    }

    @Test
    public void test() {
        assertEquals(sum, first + second));
    }
}

JUnit 5 (с @MethodSource):

class MyTestWithJunit5
{
  @DisplayName( "Test with @MethodSource" )
  @ParameterizedTest( name = "{index}: ({0} + {1}) => {2})" )
  @MethodSource( "localParameters" )
  void test( int first, int second, int sum )
  {
    assertEquals( sum, first + second );
  }

  static Stream< Arguments > localParameters()
  {
    return Stream.of(
        Arguments.of( 4, 4, 8 ),
        Arguments.of( 2, -2, 0 ),
        Arguments.of( 1, 5, 6 ) );
  }
}

JUnit 5 (с @ArgumentsSource):

class MyTestWithJunit5
{
  @DisplayName( "Test with @ArgumentsSource" )
  @ParameterizedTest( name = "{index}: ({0} + {1}) => {2})" )
  @ArgumentsSource( Params.class )
  void test( int first, int second, int sum )
  {
    assertEquals( sum, first + second );
  }

  static class Params implements ArgumentsProvider
  {
    @Override
    public Stream< ? extends Arguments > provideArguments( ExtensionContext context )
    {
      return Stream.of(
          Arguments.of( 0, 0, 0 ),
          Arguments.of( 1, 2, 3 ),
          Arguments.of( 5, 3, 8 )
      );
    }
  }
}

Учтите, что метод в @MethodSource и класс в @ArgumentsSource могут находиться где угодно, а не только внутри одного класса, содержащего методы тестирования, которые их используют. Также @MethodSource позволяет предоставлять несколько методов источника, поскольку его value является String[].

Некоторые замечания и сравнения

В JUnit 4 у нас мог быть только один фабричный метод, обеспечивающий параметры, и тесты должны были быть построены вокруг этих параметров. Напротив, JUnit 5 дает больше абстракции и гибкости в привязке параметров и отделяет тестовую логику от ее параметров, которые являются вторичными. Это позволяет создавать тесты независимо от источников параметров и легко изменять их при необходимости.

Требование зависимости

Функция параметризованных тестов не включена в базовый junit-jupiter-engine, но находится в отдельной зависимости junit-jupiter-params.