thetalkingwalnut спрашивает:
Как можно убедить скептически настроенных разработчиков в ценности модульного тестирования?
Все здесь собираются на кучу разных причин, почему юнит-тестирование хорошо. Тем не менее, я считаю, что часто лучший способ убедить кого-то в чем-то - это выслушать его аргумент и рассмотреть его пункт за пунктом. Если вы слушаете их и помогаете им выразить свои проблемы, вы можете обратиться к каждому из них и, возможно, преобразовать их в свою точку зрения (или, по крайней мере, оставить их без ноги, чтобы стоять на них). Кто знает? Возможно, они убедят вас, почему юнит-тесты не подходят для вашей ситуации. Не вероятно, но возможно. Возможно, если вы опубликуете свои аргументы против юнит-тестов, мы поможем определить контраргументы.
Важно выслушать и понять обе стороны аргумента. Если вы попытаетесь слишком усердно применять юнит-тесты, не обращая внимания на проблемы людей, вы закончите религиозной войной (и, вероятно, действительно бесполезными юнит-тестами). Если вы примете его медленно и начнете применять его там, где вы увидите наибольшую выгоду при наименьших затратах, вы сможете продемонстрировать ценность модульных тестов и иметь больше шансов убедить людей. Я понимаю, что это не так просто, как кажется - обычно требуется некоторое время и тщательные метрики, чтобы создать убедительный аргумент.
Модульные тесты являются инструментом, как и любой другой, и должны применяться таким образом, чтобы выгоды (отлов ошибок) перевешивали затраты (усилия по их написанию). Не используйте их, если / где они не имеют смысла, и помните, что они являются лишь частью вашего арсенала инструментов (например, проверки, утверждения, анализаторы кода, формальные методы и т. Д.). Мои разработчики говорят следующее:
Они могут пропустить написание теста для метода, если у них есть хороший аргумент, почему это не нужно (например, слишком просто, чтобы стоить или слишком сложно, чтобы стоить) и как метод будет проверен иным способом (например, проверка, утверждения , формальные методы, интерактивные / интеграционные тесты). Им необходимо учитывать, что некоторые проверки, такие как проверки и формальные доказательства, выполняются в определенный момент времени, а затем их необходимо повторять каждый раз, когда изменяется производственный код, тогда как модульные тесты и утверждения можно использовать как регрессионные тесты (написанные один раз и впоследствии выполненные повторно). ). Иногда я с ними согласен, но чаще я буду спорить о том, действительно ли метод слишком прост или слишком сложен для модульного тестирования.
Если разработчик утверждает, что метод кажется слишком простым для сбоя, разве не стоит потратить 60 секунд, необходимых для написания простого 5-строчного модульного теста для него? Эти 5 строк кода будут запускаться каждую ночь (вы делаете ночные сборки, верно?) В течение следующего года или более и будут стоить усилий, даже если однажды случится обнаружение проблемы, для определения которой может потребоваться 15 минут или дольше и отладить. Кроме того, написание простых юнит-тестов увеличивает количество юнит-тестов, благодаря чему разработчик выглядит хорошо.
С другой стороны, если разработчик утверждает, что метод кажется слишком сложным для модульного тестирования (не стоящего значительных усилий), это может быть хорошим показателем того, что метод должен быть разделен или подвергнут рефакторингу для тестирования простых частей. Обычно это методы, которые используют необычные ресурсы, такие как синглтоны, текущее время, или внешние ресурсы, такие как набор результатов базы данных. Эти методы обычно должны быть реорганизованы в метод, который получает ресурс (например, вызывает getTime ()), и метод, который принимает ресурс в качестве аргумента (например, принимает метку времени в качестве параметра). Я позволил им пропустить тестирование метода, который извлекает ресурс, и вместо этого они написали модульный тест для метода, который теперь принимает ресурс в качестве аргумента. Обычно это значительно упрощает написание модульного теста и, следовательно, стоит писать.
Разработчик должен нарисовать «черту в песке» в том, насколько комплексными должны быть их модульные тесты. Позже, в процессе разработки, всякий раз, когда мы обнаруживаем ошибку, они должны определить, могут ли более комплексные модульные тесты решить проблему. Если это так, и если такие ошибки появляются многократно, им необходимо сдвинуть «линию» в направлении написания более комплексных модульных тестов в будущем (начиная с добавления или расширения модульного теста для текущей ошибки). Им нужно найти правильный баланс.
Его важно понимать юнит - тесты не являются панацеей и там есть такая вещь , как слишком много модульного тестирования. На моем рабочем месте, когда бы мы ни делали извлеченные уроки, я неизбежно слышу «нам нужно написать больше юнит-тестов». Менеджмент кивает в знак согласия, потому что его ударили по головам, что «модульные тесты» == «хорошо».
Тем не менее, нам нужно понять влияние «большего количества модульных тестов». Разработчик может писать только ~ N строк кода в неделю, и вам нужно выяснить, какой процент этого кода должен составлять код модульного теста по сравнению с рабочим кодом. На слабом рабочем месте может быть 10% кода в виде модульных тестов и 90% кода в качестве производственного кода, что приводит к продукту с большим количеством (хотя и очень глючных) функций (например, MS Word). С другой стороны, строгий магазин с 90% модульных тестов и 10% производственного кода будет иметь отличный продукт с очень небольшим количеством функций (подумайте «vi»). Вы, возможно, никогда не услышите сообщений о сбое последнего продукта, но это, скорее всего, связано с тем, что продукт не очень хорошо продается, а также с качеством кода.
Что еще хуже, возможно, единственная уверенность в разработке программного обеспечения состоит в том, что «изменения неизбежны». Предположим, что строгий магазин (90% модульных тестов / 10% производственного кода) создает продукт, имеющий ровно 2 функции (при условии, что 5% производственного кода == 1 функция). Если клиент приходит и изменяет одну из функций, то это изменение уничтожает 50% кода (45% модульных тестов и 5% производственного кода). У слабого магазина (10% модульных тестов / 90% производственного кода) есть продукт с 18 функциями, ни одна из которых не работает очень хорошо. Их клиент полностью обновляет требования для 4 своих функций. Несмотря на то, что это изменение в 4 раза больше, уничтожается только половина базы кода (~ 25% = ~ 4,4% модульных тестов + 20% производственного кода).
Я хочу сказать, что вы должны сообщить, что понимаете баланс между слишком маленьким и слишком большим количеством модульных тестов - по сути, что вы продумали обе стороны проблемы. Если вы сможете убедить своих сверстников и / или ваше руководство в этом, вы получите авторитет и, возможно, получите больше шансов победить их.