Исключая непарамный тест в параметризованном тестовом классе - PullRequest
49 голосов
/ 29 июля 2010

Есть ли в JUnit аннотация, исключающая непарамный тест в параметризованном тестовом классе?

Ответы [ 8 ]

53 голосов
/ 29 января 2015

JUnit 5

Начиная с Junit 5.0.0 теперь вы можете комментировать свои методы тестирования с помощью @ParameterizedTest.Так что нет необходимости во внутренних классах.Существует много способов предоставления аргументов для параметризованного теста, кроме ValueSource, как показано ниже.См. Официальное руководство пользователя для получения более подробной информации:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

public class ComponentTest {

    @ParameterizedTest
    @ValueSource(strings = { "racecar", "radar", "able was I ere I saw elba" })
    public void testCaseUsingParams(String candidate) throws Exception {
    }

    @Test
    public void testCaseWithoutParams() throws Exception {
    }
}

JUnit 4

Если вы все еще используете Junit 4 (я тестировал с v4.8.2), вы можете использоватьЗакрытый бегун вместе с внутренними классами и параметризованным бегуном:

import org.junit.Test;
import org.junit.experimental.runners.Enclosed;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Enclosed.class)
public class ComponentTest {

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

        @Parameters
        ...

        @Test
        public void testCaseUsingParams() throws Exception {
        }
    }

    public static class ComponentSingleTests {

        @Test
        public void testCaseWithoutParams() throws Exception {
        }
    }
}
12 голосов
/ 25 июня 2011

I только что обнаружил , что можно использовать JUnitParams .Я теперь преобразовал один из моих тестов, чтобы использовать его, и он прекрасно работает.

6 голосов
/ 30 июля 2010

Нет.Рекомендуется перенести эти непараметрические тесты в другой класс (файл .java)

2 голосов
/ 24 октября 2017

Я смог сделать что-то очень похожее на ответ Мэтью Мэдсона и нашел полезным создать базовый класс для инкапсуляции настроек и общих вспомогательных функций между тестами single и param.Это работает без использования Enclosed.class .

 @RunWith(Suite.class)
 @SuiteClasses({ComponentTest.ComponentParamTests.class, ComponentTest.ComponentSingleTests.class})
 public class ComponentTest {

    public static class TestBase {
        @Spy
        ...
        @Before
        ...
    }

    @RunWith(Parameterized.class)
    public static class ComponentParamTests extends TestBase{
        @Parameter
        ...
        @Parameters
        ...
        @Test
        ...
    }
    public static class ComponentSingleTests extends TestBase{
        @Test
        ...
    }
}
2 голосов
/ 20 декабря 2016

Zohhak test runner - это более простой способ параметризации конкретных тестов. Спасибо Петр!

0 голосов
/ 29 марта 2016

Я сделал что-то похожее на Решение Мэтью.Тем не менее, я создал два новых java-файла, которые расширяют текущий файл, чтобы ComponentSingleTests не запускались дважды.Таким образом, они могут совместно использовать общие переменные-члены и вспомогательные методы из родительского класса.Проблема, с которой у меня было решение Мэтью, заключалась в том, что мой одиночный тест выполнялся дважды, а не один раз, так как класс Enclosed.class (который расширяет класс Suite.class) сделает ваш тест выполненным дважды, как описано в этой ссылке Предотвращение выполнения тестов junitдважды

ComponentTest.java

public class ComponentTest {
    public int sharedMemberVariables; 
    ... 
}

ComponentParamTests.java

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;

@RunWith(Parameterized.class)
public class ComponentParamTests extends ComponentTest {

    @Parameters
    ...

    @Test
    public void testCaseUsingParams() throws Exception {
    }
}

ComponentSingleTests.java

import org.junit.Test;

public class ComponentSingleTests {

    @Test
    public void testCaseWithoutParams() throws Exception {
        ...
    }
}
0 голосов
/ 27 апреля 2012

Предполагается, что вы используете Parametrized.class для запуска своего класса теста - пометьте все непараметризированные тесты как @Ignored. В противном случае вы можете создать статический внутренний класс для группировки всех ваших параметризованных тестов, а другой - для непараметризированных.

0 голосов
/ 11 июня 2011

Похоже, что TestNG не страдает от этой проблемы . Я не настолько отчаялся, поэтому я изменил встроенный класс Parameterized для поддержки этой функции. Просто аннотируйте применимые тесты как @NonParameterized. Обратите внимание, что этот класс работает только со своими аннотациями, т.е. проверяет ваш импорт.

<code>import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;

import org.junit.Test;
import org.junit.runner.Runner;
import org.junit.runner.notification.RunNotifier;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.Suite;
import org.junit.runners.model.FrameworkMethod;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.Statement;
import org.junit.runners.model.TestClass;

/**
 * <p>
 * The custom runner <code>Parameterized</code> implements parameterized tests.
 * When running a parameterized test class, instances are created for the
 * cross-product of the test methods and the test data elements.
 * </p>
 * For example, to test a Fibonacci function, write:
 *
 * <pre>
 * &#064;RunWith(Parameterized.class)
 * public class FibonacciTest {
 *     &#064;Parameters
 *     public static List&lt;Object[]&gt; data() {
 *         return Arrays.asList(new Object[][] {
 *                 Fibonacci,
 *                 { {0, 0}, {1, 1}, {2, 1}, {3, 2}, {4, 3}, {5, 5},
 *                         {6, 8}}});
 *     }
 *
 *     private int fInput;
 *
 *     private int fExpected;
 *
 *     public FibonacciTest(int input, int expected) {
 *         fInput = input;
 *         fExpected = expected;
 *     }
 *
 *     &#064;Test
 *     public void test() {
 *         assertEquals(fExpected, Fibonacci.compute(fInput));
 *     }
 * }
 * 
*

* Каждый экземпляр FibonacciTest будет построен с использованием * конструктор с двумя аргументами и значения данных в * &#064;Parameters метод. *

* / открытый класс Parameterized extends Suite { / ** * Аннотация для метода, который предоставляет параметры для ввода в * конструктор тестового класса Parameterized * / @Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public static @interface Parameters { } / ** * Аннотация для методов, которые не должны быть параметризованы * / @Retention (RetentionPolicy.RUNTIME) @Target (ElementType.METHOD) public static @interface NonParameterized { } закрытый класс TestClassRunnerForParameters extends BlockJUnit4ClassRunner { private final int fParameterSetNumber; приватный финал List fParameterList; TestClassRunnerForParameters (Class <?> Type, List parameterList, int i) throws InitializationError { супер (типа); fParameterList = parameterList; fParameterSetNumber = i; } @Override public Object createTest () выдает Exception { return getTestClass (). getOnlyConstructor (). newInstance ( computeParams ()); } закрытый объект [] computeParams () создает исключение { пытаться { return fParameterList.get (fParameterSetNumber); } catch (ClassCastException e) { бросить новое исключение (String.format ( "% s.% s () должен вернуть коллекцию массивов.", getTestClass (). getName (), getParametersMethod ( . GetTestClass ()) GetName ())); } } @Override protected String getName () { return String.format ("[% s]", fParameterSetNumber); } @Override Защищенное String testName (окончательный метод FrameworkMethod) { return String.format ("% s [% s]", method.getName (), fParameterSetNumber); } @Override protected void validateConstructor (Список ошибок) { validateOnlyOneConstructor (ошибки); } @Override Защищенный оператор classBlock (уведомитель RunNotifier) ​​{ вернуть childrenInvoker (уведомитель); } @Override Защищенный список computeTestMethods () { List ret = super.computeTestMethods (); for (Iterator i = ret.iterator (); i.hasNext ();) { FrameworkMethod frameworkMethod = (FrameworkMethod) i.next (); if (isParameterized () ^ ! FrameworkMethod.getMethod (). IsAnnotationPresent ( NonParameterized.class)) { i.remove (); } } возвратный ответ; } защищенный логический isParameterized () { вернуть истину; } } закрытый класс TestClassRunnerForNonParameterized extends TestClassRunnerForParameters { TestClassRunnerForNonParameterized (тип Class <?>, List parameterList, int i) throws InitializationError { супер (тип, parameterList, i); } защищенный логический isParameterized () { вернуть ложь; } } закрытый финал ArrayList runners = new ArrayList (); / ** * Только называется рефлексивно. Не используйте программно. * / public Parameterized (Class <?> klass) throws Throwable { супер (класс, Коллекции. emptyList ());СписокparametersList = getParametersList (getTestClass ());if (parametersList.size ()> 0) {try {runners.add (new TestClassRunnerForNonParameterized (getTestClass () .getJavaClass (), parametersList, 0));} catch (Exception e) {System.out.println («Нет непараметрических тестов.»);}} try {for (int i = 0; i getChildren () {возврат бегунов;} @SuppressWarnings ("unchecked") личный списокgetParametersList (TestClass klass) throws Throwable {return (Список)) getParametersMethod (klass) .invokeExplosively (null);} private FrameworkMethod getParametersMethod (TestClass testClass) генерирует исключение {List method = testClass .getAnnotatedMethods (Parameters.class);for (FrameworkMethod each: method) {int modifiers = each.getMethod (). getModifiers ();if (Modifier.isStatic (modifiers) && Modifier.isPublic (modifiers)) возвращает каждый;} генерировать новое исключение («Метод открытых статических параметров в классе» + testClass.getName ());}}

Обновление: Я пытаюсь добавить подобные вещи в junit.

...