2010-10-27 2 views
46

В библиотеке JUnit4 есть метод fail(). Мне это нравится, но испытывает недостаток pass() метода, которого нет в библиотеке. Почему это так?JUnit4 fail() есть здесь, но где pass()?

Я выяснил, что вместо этого могу использовать assertTrue(true), но по-прежнему выглядит нелогичным.

@Test 
public void testSetterForeignWord(){ 
    try { 
    card.setForeignWord(""); 
    fail(); 
    } catch (IncorrectArgumentForSetter ex){ 
    } 

// assertTrue(true); 
} 
+7

Просто используйте оператор return - в большинстве случаев это будет проходить как pass(). – topchef

+0

@topchef, что единственный комментарий ударил молотком по голове, в то время как все остальные дебаты о том, что приемлемо, а что нет. – 2013-01-04 19:45:16

+0

Проверено несколько тестовых систем (perl Test :: Simple) и неудачных утверждений. Однако Junit подсчитывает количество методов _test_, которые проходят и терпят неудачу. Таким образом, Junit не имеет одинакового использования для метода pass. –

ответ

51

Пока тест не сгенерирует исключение, она проходит, если ваш @Test аннотации не указано ожидаемое исключение. Я полагаю, что pass() может вызвать особое исключение, которое JUnit всегда интерпретирует как передачу, чтобы коротко закоротить тест, но это противоречит обычному дизайну тестов (т. Е. Предполагает успех и только терпит неудачу, если утверждение терпит неудачу) и, если люди возникла идея, что было бы предпочтительнее использовать pass(), это значительно замедлит большой набор проходящих тестов (из-за накладных расходов на создание исключений). Неудачные тесты не должны быть нормой, поэтому это не имеет большого значения, если у них есть накладные расходы.

Обратите внимание, что ваш пример можно переписать так:

@Test(expected=IncorrectArgumentForSetter.class) 
public void testSetterForeignWord("") throws Exception { 
    card.setForeignWord(""); 
} 

Кроме того, вы должны способствовать использование стандартных исключений Java. Вероятно, ваш IncorrectArgumentForSetter должен быть IllegalArgumentException.

+4

Методы fail() и assertX() действительно просто бросают AssertionError, что приводит к тому, что метод тестирования выходит нечисто. Вот почему успешное возвращение указывает на успех ... –

+0

-1 - Метод pass() ничего не делает - он немедленно прекращает тестирование без исключений. Это было бы фактически эквивалентно оператору return в большинстве случаев (за исключением ожидаемых исключений, тайм-аутов и т. Д.). – topchef

+1

@grigory: Вы правы в том, что метод 'pass()' не мог просто ничего не делать, чтобы тест не завершился после его вызова. Поэтому я удалил это предложение. – ColinD

2

Нет необходимости в методе пропуска, потому что, если из тестового кода не будет выведено исключение AssertionFailedException, будет протестирован блок-тест.

Метод fail() на самом деле вызывает исключение AssertionFailedException, чтобы вывести из строя testCase, если элемент управления приходит к этой точке.

+0

Я думаю, что это на самом деле junit.framework.AssertionFailedError. – Kyle

+0

Как насчет ошибок. скажем, iam, получающий элемент не видимое исключение из webdriver.Should я поймаю исключение и возврат. – sasikumar

50

Вызов return заявление в любое время, когда ваш тест закончен и пройден.

+1

+1 должен быть правильный ответ (в большинстве случаев, за исключением ожидаемых, тайм-аутов и т. Д.). – topchef

3

Я думаю, что этот вопрос нуждается в обновленном ответе, так как большинство ответов здесь довольно устарели.

Во-первых, на вопрос ФП в:

Я думаю, что его довольно хорошо принят, что введение понятия «ожидается excepetion» в JUnit был плохой ход, так как это исключение может быть поднят в любом месте, и он будет проходить тест. Он работает, если вы бросаете (и утверждаете) очень специфичные для домена исключения, но я бросаю только те исключения, когда я работаю над кодом, который должен быть абсолютно безукоризненным, - почти APIS просто бросает встроенные исключения, такие как IllegalArgumentException или IllegalStateException. Если два вызова, которые вы делаете, могли бы потащить эти исключения, то аннотация @ExpectedException будет зеленой, если вы ошиблись, это исключает!

В этой ситуации я написал класс, который я уверен, что многие другие здесь написали, что это assertThrows метод:

public class Exceptions { 
    private Exceptions(){} 

    public static void assertThrows(Class<? extends Exception> expectedException, Runnable actionThatShouldThrow){ 
     try{ 
      actionThatShouldThrow.run(); 
      fail("expected action to throw " + expectedException.getSimpleName() + " but it did not."); 
     } 
     catch(Exception e){ 
      if (! expectedException.isInstance(e)) { 
       throw e; 
      } 
     } 
    } 
} 

этот метод просто возвращает, если исключение, что позволяет сделать дальнейшие утверждения/проверки в вашем тесте.

с синтаксисом java 8 ваш тест выглядит очень хорошо.Ниже один из самых простых тестов на нашей модели, которая использует метод:

@Test 
public void when_input_lower_bound_is_greater_than_upper_bound_axis_should_throw_illegal_arg() { 
    //setup 
    AxisRange range = new AxisRange(0,100); 

    //act 
    Runnable act =() -> range.setLowerBound(200); 

    //assert 
    assertThrows(IllegalArgumentException.class, act); 
} 

эти тесты немного шаткий, так как «действовать» шаг фактически не выполняет никаких действий, но я думаю, что смысл все еще довольно Чисто.

есть также небольшая библиотека на maven под названием catch-exception, которая использует синтаксис стиля mockito для проверки того, что выбраны исключения. Это выглядит красиво, но я не поклонник динамических прокси. Тем не менее, синтаксис там так гладко остается заманчивыми:

// given: an empty list 
List myList = new ArrayList(); 

// when: we try to get the first element of the list 
// then: catch the exception if any is thrown 
catchException(myList).get(1); 

// then: we expect an IndexOutOfBoundsException 
assert caughtException() instanceof IndexOutOfBoundsException; 

И, наконец, в ситуации, что я столкнулся, чтобы добраться до этой темы, есть способ игнорировать тестов, если некоторый conidition удовлетворяются.

В настоящее время я работаю над получением некоторых DLL, вызванных через библиотеку-библиотеку java-библиотеки, называемую JNA, но наш сервер сборки находится в ubuntu. Мне нравится пытаться управлять этим развитием с помощью тестов JUnit - даже если они далеки от «единиц» на этом этапе. То, что я хочу сделать, это запустить тест, если я нахожусь на локальной машине, но проигнорируйте тест, если мы на ubuntu. JUnit 4 имеет положение для этого, называемого Assume:

@Test 
public void when_asking_JNA_to_load_a_dll() throws URISyntaxException { 
    //this line will cause the test to be branded as "ignored" when "isCircleCI" 
    //(the machine running ubuntu is running this test) is true. 
    Assume.assumeFalse(BootstrappingUtilities.isCircleCI()); 
    //an ignored test will typically result in some qualifier being put on the results, 
    //but will also not typically prevent a green-ton most platforms. 

    //setup 
    URL url = DLLTestFixture.class.getResource("USERDLL.dll"); 
    String path = url.toURI().getPath(); 
    path = path.substring(0, path.lastIndexOf("/")); 

    //act 
    NativeLibrary.addSearchPath("USERDLL", path); 
    Object dll = Native.loadLibrary("USERDLL", NativeCallbacks.EmptyInterface.class); 

    //assert 
    assertThat(dll).isNotNull(); 
} 
1

Я думаю, что этот вопрос является результатом небольшого недопонимания процесса выполнения теста. В JUnit (и других инструментах тестирования) результаты подсчитываются по методу, а не по запросу. Нет счетчика, который отслеживает, сколько прошло/неудачно выполнено assertX.

JUnit выполняет каждый метод испытаний отдельно. Если метод возвращается успешно, то тест регистрируется как «пройденный». Если возникает исключение, тогда тест регистрируется как «сбой». В последнем случае возможны два подзаголовка: 1) исключение утверждения JUnit, 2) любые другие исключения. В первом случае статус будет «неудачным», а во втором случае «ошибка».

В классе Assert многие сокращенные методы доступны для исключения исключений для утверждения. Другими словами, Assert является абстракционным слоем по исключениям Юнита.

Например, это исходный код assertEquals на GitHub:

/** 
* Asserts that two Strings are equal. 
*/ 
static public void assertEquals(String message, String expected, String actual) { 
    if (expected == null && actual == null) { 
     return; 
    } 
    if (expected != null && expected.equals(actual)) { 
     return; 
    } 
    String cleanMessage = message == null ? "" : message; 
    throw new ComparisonFailure(cleanMessage, expected, actual); 
} 

Как вы можете видеть, в случае равенства ничего не происходит, в противном случае excepion будет отброшена.

Итак:

assertEqual("Oh!", "Some string", "Another string!"); 

просто бросает ComparisonFailure исключение, которое будет пойманной на JUnit и

assertEqual("Oh?", "Same string", "Same string"); 

НИЧЕГО не делает.

В целом, что-то вроде pass() не имело никакого смысла, потому что ничего не делало.

0

Я искал метод для JUnit, так что я мог бы закоротить некоторые тесты, которые не применимы в некоторых сценариях (есть тесты интеграции, а не чистые модульные тесты). Так плохо, что его там нет.

К счастью, есть способ, чтобы пройти тест игнорировали условно, что на самом деле подходит даже лучше в моем случае, используя метод assumeTrue:

Assume.assumeTrue (isTestApplicable);

Таким образом, тест будет выполнен только в том случае,

Смежные вопросы