Справедливо ли говорить, что высокое покрытие кода и высокая производительность не нужны для хорошо спроектированного модульного теста? - PullRequest
3 голосов
/ 15 июня 2009

При разработке юнит-тестов из того, что я прочитал, вы должны придерживаться следующих принципов:

  • Изолировать ваши тесты друг от друга
  • Проверка только одного поведения за раз
  • Убедитесь, что тест повторяется

С другой стороны, эти функции не всегда соответствуют хорошему тесту:

  • Высокий охват кода
  • Высокая производительность

Это честный подход?

Ответы [ 9 ]

1 голос
/ 16 июня 2009

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

Мы проводим тесты по многим причинам. Чем меньше барьеров для их написания и запуска, тем больше будет тестов - и тем лучше будет охват кода. Если мы не запускаем тесты, потому что это слишком много проблем - мы не запускаем тесты; мы не обнаруживаем наших ошибок; наша производительность страдает. Поэтому они должны быть автоматизированы (ноль проблем). Если мы не запускаем тесты, потому что это отнимает много времени от написания кода - или потому что время, которое они занимают, отвлекает нас от проблемы, раздражает нашу концентрацию: мы не запускаем тесты; мы не обнаруживаем наших ошибок; наша производительность страдает. Таким образом, они должны быть достаточно быстрыми, чтобы их не отвлекать. Если наши тесты сильно повлияют на файловую систему или базу данных, это замедлит их, и мы будем меньше их запускать. Так что избегайте этого; абстрагироваться от медленных битов. Тестируйте рано и часто. Тестовые лоты. Если они медленные, вы не будете. Так что держите их быстро.

1 голос
/ 16 июня 2009

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

Производительность не важна и важна.

Производительность не важна в том смысле, что не следует проводить микрооптимизацию. Вы должны прежде всего сосредоточиться на удобочитаемости тестов. Например, в книге «Чистый код» есть пример тестов, которые проверяли состояние температурного аварийного сигнала. Первоначально в каждом тесте было около пяти утверждений, проверяющих логические значения, такие как assertTrue(hw.heaterState()), но затем утверждения были реорганизованы для сравнения одной строки assertEquals("HBchL", hw.getState()), где верхний регистр означает включенный, а нижний регистр означает отключенный. Последний код имеет более низкую производительность из-за создания некоторых дополнительных строк и их сравнения, но его читаемость намного лучше, поэтому он лучше тестирует код.

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

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

1 голос
/ 15 июня 2009

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

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

1 голос
/ 15 июня 2009

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

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

1 голос
/ 15 июня 2009

Производительность, как правило, не касается модульных тестов. Высокий охват кода. Вы пишете отдельные тесты, чтобы узко протестировать одну функцию. Вы пишете достаточно (узкие) модульные тесты, чтобы охватить большинство ваших функций.

0 голосов
/ 16 июня 2009

Высокий охват кода: Для отдельного модульного теста он не должен покрывать 100% тестируемого метода или методов. В конце концов, набор модульных тестов должен охватывать столько тестируемого метода или методов, сколько вы считаете важным. Может быть 1%, может быть 100%, и это, вероятно, отличается для разных разделов кода.

Обычно я стараюсь охватить 70% -80%, а затем больше внимания уделяю тенденции покрытия, чем фактическому значению.

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

Нередко для системы, в которой я работаю, проходят сотни модульных тестов, и все же они запускаются через 2 минуты. Один действительно медленный тест, или несколько медленных тестов, может действительно замедлить цикл build-test-refactor.

0 голосов
/ 15 июня 2009

Производительность и охват - цели всего набора тестов. Каждый отдельный тест не должен пытаться «захватить» столько покрытия, сколько возможно, но и не должен касаться производительности.

Мы хотим, чтобы весь набор тестов работал в разумные сроки и должен охватывать большую часть функциональности кода, но не за счет написания модульных тестов "ba".

0 голосов
/ 15 июня 2009

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

0 голосов
/ 15 июня 2009

Перечитав вопрос:

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...