Подтвердить что ты не робот

Сколько единичных тестов следует писать для каждой функции/метода?

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

4b9b3361

Ответ 1

Один тест на проверку и супер описательные имена для каждого экземпляра:

@Test
public void userCannotVoteDownWhenScoreIsLessThanOneHundred() {
 ...
}

И только одно утверждение и использование хороших имен дает мне лучший отчет, когда тест терпит неудачу. Они кричат ​​мне: "Ты нарушил это правило!".

Ответ 2

BDD (разработка, управляемая поведением)

Хотя я все еще участвую, в основном TDD организовал/сосредоточил внимание на том, как будет использоваться ваше программное обеспечение... НЕ как он будет разработан/построен.

Wikipedia Общая информация

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

Ответ 3

У меня есть тест на возможность, которую предлагает функция. Однако каждый тест может иметь несколько утверждений. Имя тестового набора указывает на тестируемую способность.

Как правило, для одной функции у меня есть несколько тестов "солнечного дня" и один или несколько сценариев "дождливый день", в зависимости от его сложности.

Ответ 4

Тест для каждой проверки. Он более зернистый. Это значительно облегчает просмотр конкретного сценария.

Ответ 5

Я пишу по крайней мере один тест на метод, а иногда, если метод требует некоторого другого setUp для проверки хороших случаев и плохих случаев.

Но вы должны НИКОГДА тестировать более одного метода в одном unit test. Это уменьшает объем работы и ошибки при исправлении теста в случае изменения вашего API.

Ответ 6

Я думаю, что правило единственного утверждения немного слишком строгое. В моих модульных тестах я стараюсь следовать правилу одной группы утверждений - вы можете использовать несколько утверждений в одном методе тестирования, если вы выполняете проверки один за другим (вы не 'изменить состояние тестируемого класса между утверждениями.

Итак, в Python я считаю, что такой тест правильный:

def testGetCountReturnsCountAndEnd(self):
    count, endReached = self.handler.getCount()
    self.assertEqual(count, 0)
    self.assertTrue(endReached)

но этот должен быть split в два метода тестирования:

def testGetCountReturnsOneAfterPut(self):
    self.assertEqual(self.handler.getCount(), 0)
    self.handler.put('foo')
    self.assertEqual(self.handler.getCount(), 1)

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

Ответ 7

Я бы предложил тест для каждой проверки. Чем больше вы держите атом, тем лучше ваши результаты!

Сохранение нескольких проверок в одном тесте поможет вам создать отчет о том, сколько функций необходимо исправить.

Сохраняя атомный тест, вы увидите общее качество!

Ответ 8

Как правило, один тест за проверку. Когда тесты группируются вокруг определенной функции, это делает рефакторинг (например, удаление или разделение) более сложным, потому что тесты также нуждаются в большом количестве изменений. Гораздо лучше написать тесты для каждого типа поведения, которое вы хотите от класса. Иногда при тестировании определенного поведения имеет смысл иметь несколько проверок на случай проверки. Однако, поскольку тесты становятся более сложными, это затрудняет их изменение, если что-то в классе изменяется.

Ответ 9

В Java/Eclipse/JUnit я использую два исходных каталога (src и test) с тем же деревом. Если у меня есть src/com/mycompany/whatever/TestMePlease с проверенными методами (например, deleteAll (List <? > stuff) выбрасывает MyException), я создаю test/com/mycompany/whatever/TestMePleaseTest с методами тестирования вариантов использования/сценариев различного типа:

@Test
public void deleteAllWithNullInput() { ... }

@Test(expect="MyException.class") // not sure about actual syntax here :-P
public void deleteAllWithEmptyInput() { ... }

@Test
public void deleteAllWithSingleLineInput() { ... }

@Test
public void deleteAllWithMultipleLinesInput() { ... }

Для меня проще обрабатывать разные проверки.

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

@Test
public void insertAndDelete() { 
    assertTrue(/*stuff does not exist yet*/);
    createStuff();
    assertTrue(/*stuff does exist now*/);
    deleteStuff();
    assertTrue(/*stuff does not exist anymore*/);
}

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

Ответ 10

Мне нравится иметь тест за проверку в методе и иметь значащее имя для тестового метода. Например:

testAddUser_shouldThrowIllegalArgumentExceptionWhenUserIsNull

Ответ 11

Тест на проверку. Если вы назвали метод соответствующим образом, он может дать ценный намек на проблему, если один из этих тестов приведет к сбою регрессии.

Ответ 12

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

Там хороший подкаст-шоу с Энди Леонардом о том, что он включает и как это сделать, и если вы хотите получить немного больше информации, я написал сообщение в блоге по теме (бесстыдный плагин; o)