Во время обучения TDD на основе медицинского программного обеспечения мы реализуем следующую историю: «Когда пользователь нажимает кнопку« Сохранить », система должна добавить пациента, добавить устройство и добавить записи данных устройства».
Окончательная реализация будет выглядеть примерно так:
if (_importDialog.Show() == ImportDialogResult.SaveButtonIsPressed)
{
AddPatient();
AddDevice();
AddDeviceDataRecords();
}
У нас есть два способа реализовать это:
- Три теста, где каждый проверяет один метод (AddPatient, AddDevice, AddDeviceDataRecords) был вызван
- Один тест, который проверяет, все три метода были вызваны
В первом случае, если что-то не так с условием условия if, все три теста не пройдут. Но во втором случае, если тест не пройден, мы не уверены, что именно не так. Какой способ вы бы предпочли.
источник
Кажется, что гранулярность в вашем примере - это разница между юнит-тестами и приемочными тестами.
Unittest тестирует одну функциональную единицу с минимальным количеством зависимостей. В вашем случае может быть 4 юниттеста
Юниттесты предназначены для разработчиков , поэтому они получают уверенность, что их код технически правильный
Приемочные испытания должны проверить комбинированную функциональность с точки зрения пользователя. Они должны быть смоделированы в соответствии с пользовательскими историями и должны быть как можно более высокого уровня. Таким образом, вам не нужно проверять, вызваны ли функции, но если достигается преимущество, видимое для пользователя :
когда пользователь вводит данные, нажимает ОК и ...
приемочные тесты предназначены для клиентов или для улучшения связи с ними.
Чтобы ответить на ваш вопрос «что бы вы предпочли»: что является для вас большей проблемой, ошибки и регрессия (=> больше юниттестов) или понимание и формализация общей картины (=> больше приемочных тестов)
источник
Это неверно
Вы должны сделать это, чтобы убедиться, что это работает.
Вы также должны сделать это, чтобы убедиться, что API работает.
Класс - как единое целое - должен быть полностью проверен. Каждый метод.
Вы можете начать с теста, который охватывает все три метода, но он мало о чем говорит.
Верный. Вот почему вы тестируете все методы.
Вы должны проверить открытый интерфейс. Поскольку этот класс выполняет три плюс одно (даже если они связаны одним методом из-за пользовательской истории), вы должны протестировать все четыре вещи. Три низкоуровневых и один пучок.
источник
Мы пишем наши модульные тесты для осмысленных предложений функциональности, которые много раз соответствуют методу (если вы хорошо написали свой код), но иногда становитесь больше, охватывая много методов.
Например, представьте, что добавление пациента в вашу систему требует вызова некоторых подпрограмм (дочерних функций):
Мы могли бы также написать модульный тест для каждой из этих функций.
источник
Одно простое правило, которому я следовал, - это назвать тест так, чтобы он точно описывал, что делает тест. Если название теста становится слишком сложным, это признак того, что тест, возможно, делает слишком много. Так, например, присвоение имени тесту того, что вы предлагаете в варианте 2, может выглядеть как PatientIsAddedDeviceIsAddedAndDeviceDataRecordsWhenSaved, который намного сложнее, чем три отдельных теста PatientIsAddedWhenSaved, DeviceIsAddedWhenSaved, DataRecordsWhenSaved. Я также думаю, что уроки, которые можно извлечь из BDD, довольно интересны, когда каждый тест действительно соответствует одному требованию, которое можно описать на естественном языке.
источник