Нужно ли проводить юнит-тесты на известные дефекты?

37

Если мой код содержит известный дефект, который должен быть исправлен, но еще не исправлен, и не будет исправлен в текущем выпуске, и, возможно, не будет исправлен в обозримом будущем, в случае неудачного модульного теста для этой ошибки в тестовый набор? Если я добавлю модульное тестирование, оно (очевидно) не будет выполнено, и привыкнуть к неудачным тестам кажется плохой идеей. С другой стороны, если это известный дефект, и есть известный сбойный случай, кажется странным не допускать его в набор тестов, так как в какой-то момент он должен быть исправлен, и тест уже доступен.

Мартейн
источник
6
Я так не думаю, я специально спрашиваю о модульном тесте
Мартейн
3
тесты на известные дефекты известны как регрессионные тесты , они не имеют ничего общего с модульными тестами ... если быть точным, то последний зависит от мнения разработчика - ваш вопрос, возможно, не дубликат, а скорее опрос мнений. Особенно примечательно, что в принятом вами ответе вообще не используется термин «модульные тесты», но вместо этого он довольно разумно называет их по-разному «известными ошибочными тестами»
gnat
3
Спасибо Майкл, что делает справку о том , как отметить такие тесты в JUnit, но на самом деле не на испытательной практике. Гнат, я до сих пор не понимаю, как вы видите проваленный юнит-тест в качестве регрессионного теста. Я также получаю отчетливо враждебную пассивную / агрессивную атмосферу от ваших комментариев. Если вы считаете, что мне следует задавать вопросы по-другому, скажите, пожалуйста, потому что я не могу ответить на ваши вопросы, если вы сформулируете их так.
Мартейн
3
@gnat: честно, ИМХО, не имеет значения, будем ли мы называть тесты здесь "модульными" или "регрессионными" тестами - вопрос, который вы связали, тоже имеет другую направленность, и ответы там не применимы здесь.
Док Браун

Ответы:

51

Ответ - да, вы должны написать их, и вы должны запустить их.

Ваша среда тестирования нуждается в категории «известных неудачных тестов», и вы должны пометить эти тесты как попадающие в эту категорию. Как вы это сделаете, зависит от структуры.

Любопытно, что неожиданно пройденный тест может быть таким же интересным, как и проходной тест, который неожиданно не проходит.

david.pfx
источник
7
Пример вышеупомянутой функции в инфраструктуре юнит-тестов Python: docs.python.org/3.3/library/…
Джейс Браунинг
5

Я думаю, что у вас должен быть модульный тест с текущим поведением и в комментариях, добавить правильный тест и правильное поведение. Пример:

@Test
public void test() {
  // this is wrong, it should be fixed some time
  Assert.assertEquals(2, new Calculator().plus(2,2));
  // this is the expected behaviour, replace the above test when the fix is available
  // Assert.assertEquals(4, new Calculator().plus(2, 2));
}

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

РЕДАКТИРОВАТЬ: Как сказал капитан Мэн, в больших проектах это не будет исправлено в ближайшее время, но ради документации, оригинальный ответ лучше, чем ничего.

Лучший способ сделать это - продублировать текущий тест, заставив клона подтвердить правильность, и @Ignoreэто с помощью сообщения, например

@Test
public void test() {
  Assert.assertEquals(2, new Calculator().plus(2,2));
}

@Ignore("fix me, Calculator is giving the wrong result, see ticket BUG-12345 and delete #test() when fixed")
@Test
public void fixMe() {
  Assert.assertEquals(4, new Calculator().plus(2, 2));
}

Это связано с тем, что в вашей команде принято сокращать количество @Ignored-тестов. Точно так же, как если бы вы вводили или изменяли тест для отражения ошибки, за исключением того, что вы не провалите сборку, если это критично для вашей команды, как, например, OP заявил, что исправление не будет включено в текущий выпуск ,

Сильвиу Бурча
источник
1
Это плохой совет. Никто никогда не будет пытаться это исправить. Люди будут открывать старые модульные тесты только в случае проблем с компиляцией или сбоев тестов.
Капитан Мэн
@CaptainMan Я согласен, я обновил свой ответ, чтобы обеспечить лучшую возможность, чтобы команда разработчиков знала об ошибке без сбоев сборки. Ваш отрицательный ответ был оправдан за первоначальный ответ, который я опубликовал 3 года назад, я считаю, что текущий ответ более уместен. Вы бы сделали это по-другому?
Сильвиу Бурча
Это почти то же самое, что я делаю в тех редких случаях, когда по какой-то причине я не могу исправить ошибку сейчас. Я хотел бы услышать, как вы справляетесь с ситуацией @CaptainMan
RubberDuck
@RubberDuck Здесь на самом деле нет идеальной ситуации (кроме исправления ошибки, ха-ха). Для меня, по крайней мере, видеть в результатах теста «10 пройдено, 0 не пройдено, 1 пропущено» - это хоть какой-то признак того, что что-то подозрительно для людей, не знакомых с ним. Я предпочитаю @Ignoreподход. Причина, по которой использование только комментария не кажется мне хорошей идеей, заключается в том, что я не думаю, что люди часто открывают модульные тесты, чтобы проверить их (если они не дают ошибок, или (надеюсь), когда они задаются вопросом, почему что-то игнорируется ).
Капитан Мэн
@RubberDuck Здесь на самом деле нет идеальной ситуации (кроме исправления ошибки, ха-ха). Для меня, по крайней мере, видеть в результатах теста «10 пройдено, 0 не пройдено, 1 пропущено» - это хоть какой-то признак того, что что-то подозрительно для людей, не знакомых с ним. Я предпочитаю @Ignoreподход. Причина, по которой использование только комментария не кажется мне хорошей идеей, заключается в том, что я не думаю, что люди часто открывают модульные тесты, чтобы проверить их (если они не дают ошибок, или (надеюсь), когда они задаются вопросом, почему что-то пропускается ).
Капитан Мэн
3

В зависимости от инструмента тестирования вы можете использовать omitилиpend .

Пример в рубине:

gem 'test-unit', '>= 2.1.1'
require 'test/unit'

MYVERSION = '0.9.0' #Version of the class you test 


class Test_omit < Test::Unit::TestCase
  def test_omit
    omit('The following assertion fails - it will be corrected in the next release')
    assert_equal(1,2)
  end

  def test_omit_if
    omit_if(MYVERSION < '1.0.0', "Test skipped for version #{MYVERSION}")
    assert_equal(1,2)
  end

end

Команда omitпропускает тест,omit_if объединяет его с тестом - в моем примере я тестирую номер версии и выполняю тест только для версий, в которых, как я ожидаю, ошибка устранена.

Вывод моего примера:

Loaded suite test
Started
O
===============================================================================
The following assertion fails - it will be corrected in the next release [test_omit(Test_omit)]
test.rb:10:in `test_omit'
===============================================================================
O
===============================================================================
Test skipped for version 0.9.0 [test_omit_if(Test_omit)]
test.rb:15:in `test_omit_if'
===============================================================================


Finished in 0.0 seconds.

2 tests, 0 assertions, 0 failures, 0 errors, 0 pendings, 2 omissions, 0 notifications
0% passed

Итак, мой ответ: Да, провести тест. Но не путайте тестер с ошибками, когда вы знаете, что он потерпит неудачу.

Кнут
источник
2

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

kaared
источник
1

Ответ НЕТ ИМХО. Не следует добавлять модульный тест для ошибки до тех пор, пока вы не начнете работать над исправлением ошибки, после чего вы напишете тест (ы), который подтверждает ошибку, и когда этот тест (тесты) не проходит в соответствии с отчетом об ошибке ( s) вы пойдете и исправите фактический код, чтобы выполнить тест (ы), и ошибка будет решена, и она будет устранена после этого.

В моем мире у нас был бы ручной тестовый случай, в котором QE терпели неудачу, пока ошибка не будет исправлена. И мы, как разработчики, узнаем об этом через руководство по сбою TC и через трекер ошибок.

Причина не добавления неисправных UT проста. UT предназначены для прямой обратной связи и проверки того, над чем я, как разработчик, сейчас работаю. И UT используются в системе CI, чтобы убедиться, что я не случайно что-то сломал в какой-то другой области кода для этого модуля. ИМХО, если намеренно проваливать UT на преднамеренную ошибку, было бы контрпродуктивно и просто неправильно.

grenangen
источник
0

Я полагаю, что ответ на самом деле, это зависит. Будьте прагматичны в этом. Что вы пишете сейчас? Может быть, это свежо в вашем уме?

Исправляя ошибку, имеет смысл доказать, что она существует, написав модульный тест, который обнаруживает ошибку. Затем вы исправляете ошибку, и юнит-тест должен пройти.

У вас есть время, чтобы написать провальный модульный тест только сейчас? Есть ли более актуальные функции или ошибка, которую нужно написать / исправить.

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

Возможно, вы можете ввести в заблуждение, если введете неуспешный модульный тест перед выпуском, который происходит без исправления ошибки.

Ozz
источник
0

Я обычно чувствую себя неловко из-за известных сбоев в наборах тестов, потому что слишком легко увеличивать список со временем или несвязанные сбои в тех же тестах, которые можно отклонить как «ожидаемые». То же самое касается случайных сбоев - в коде может быть что-то злое. Я бы проголосовал за написание теста для кода, как он есть сейчас, и как это должно быть, как только он будет исправлен, но закомментирован или отключен каким-то образом.

Рори Хантер
источник