Если модульное тестирование настолько велико, почему не все компании делают это?
================================================================================

Первой реальной компанией, занимающейся программным обеспечением, над которой я работал, было все об модульном тестировании (NUnit). Я не знаю, что мы были настоящими приверженцами этого в то время - я понятия не имею, что такое наш код, и я пишу большую часть модульных тестов. С тех пор я столкнулся с некоторыми компаниями, которые много тестируют, но тестирует стул: полагается на человека, который там, имеет низкую повторяемость и небольшую вероятность заражения ошибками. Другое отношение: это было то, что они хотели получить с "в будущем"; в основном, когда деньги падают с неба.

Я пропускаю модульное тестирование - это просто облегчает жизнь. Но я нахожу, что, когда я ищу новую работу, модульное тестирование - это либо то, что компании хотели бы "начать с" в будущем, либо то, что они вообще не делают (ухх, это было какое-то время Теперь!). Я бы сказал, что 60-75% запросов на работу, на которые я смотрел последние 2 года, не включили модульное тестирование вообще. Я могу только подумать об одном или двух, у которых был опыт тестирования модулей как требование (для позиции разработчика на уровне среднего уровня).

Итак, вопрос:  **что отсутствует**? Я думаю, что это делает людей более продуктивными, но это только после того, как они потратили немало времени на это. Нет ли хороших исследований относительно экономии затрат на модульное тестирование? Это тип компании, на которую я смотрю?

Изменить: хотя название немного дьяволов-адвокатов, я считаю себя сторонником тестирования.

 

По моему опыту, в этом есть несколько факторов:

* Менеджмент на самом деле не понимает, что такое модульное тестирование, или почему у него есть реальная внутренняя ценность для них.
* Менеджмент, как правило, больше озабочен быстрой доставкой продукта, и (неправильно) видит, что модульное тестирование является контрпродуктивным для этой цели.
* Есть ошибочное представление о том, что тестирование принадлежит исключительно в рамках QA. Разработчики являются кодовыми и не могут писать тесты.
* Существует распространенное неправильное представление о том, что руководству придется тратить деньги на правильное тестирование устройства, несмотря на то, что инструменты доступны. (Разумеется, разработчик наращивает время, чтобы рассмотреть, но это не очень непомерно.)
* Ответ будет отвечать на этот ответ: очень сложно определить значение тестового кода (изменить jcollum)

Естественно, есть и другие факторы, но это то, к чему я столкнулся.

 

1) Это тяжело
2) Требуется время   

3) Очень сложно определить значение тестового кода

Точка 3 является липкой. Хорошие модульные тесты уменьшают количество ошибок. Но так же хороший код производства. Как вы определяете, сколько ошибок не существует из-за ваших модульных тестов? Вы не можете измерить то, чего не существует. Вы можете указать на исследования, но они не очень хорошо вписываются в таблицу бизнес-менеджеров.

 

Легко возложить всю ответственность на "управление". Но действительно ли руководство действительно говорит вам, что вы не проводите ни одного модульного тестирования?

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

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

Это легко, когда вы пишете собственный класс строк. Когда вы тестируете реальный продукт, вы сталкиваетесь с проблемами, о которых никто не говорил вам в слайдах powerpoint:

* Взаимодействие с пользователем. Половина вашего приложения - логика пользовательского интерфейса. Как вы проверите его автоматическим способом, который не сломается, если вы переместите кнопку?
* Взаимодействие с внешними API и структурами. Если вы пишете драйвер ядра Windows, как вы unit test его? Вы пишете заглушки для каждой используемой функции IRP и ядра, эффективно создавая симуляцию ядра ОС?
* Сетевые коммуникации - это дело 21-го века. Как вы координируете unit test, состоящий из нескольких распределенных компонентов?
* Как вы выбираете хорошие тестовые примеры? Обычно я вижу, как люди пробуют "делать случайные вещи в цикле из 1000 итераций и посмотреть, не ломаются ли они". Когда вы делаете это, усилие выше, чем возврат, важные ошибки пропущены, а модульное тестирование отменено.
* Как вы проверяете выполнение требований к производительности?
* Знание шаблонов при тестировании мало: окурки, консервированные ответы, регрессионное тестирование - это понятия, которые большинство людей не знает. Сколько на вашем рабочем месте действительно прочитало книгу об модульном тестировании?

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

В следующий раз, когда ваш босс попросит вас выполнить оценку времени, укажите время для записи unit test и посмотрите, что произойдет.

 

Большинство тестов ничего не тестируют.   

Вы пишете функцию fileopen() и unittest, которая терпит неудачу, если файл не существует и преуспевает, если файл существует.
Большой! Теперь вы проверили, работает ли он с именем файла в BIG5? на долю NFS? на Vista с файлом на USB-ключ и UAC включен?

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

В модульных тестах проверяются ошибки в коде отдельных функций. Они могут работать для слоев доступа к данным, библиотек математики и т.д., Где входы/выходы хорошо известны, а внутренняя структура сложна, но во многих случаях это всего лишь пустая трата времени.
Они терпят неудачу, когда ошибки связаны с взаимодействием между различными частями кода или с ОС и пользователем. Такие проблемы, как высокие/низкие настройки DPI, испортили диалоговое окно или настройку на иностранном языке, заменив ".". и ',' обычно не встречаются.

 

Проведено исследование ROI модульных тестов - см. [этот вопрос](/questions/53829/is-there-hard-evidence-of-the-roi-of-unit-testing).

 

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

 

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

У блочных тестов есть затраты (создание, обслуживание и работа), и они имеют смысл только в том случае, если они обеспечивают большую выгоду, чем эти затраты. Создание теста - это умение, как и любое другое, для достижения успеха требуется определенный опыт и знания. Без достаточного опыта очень легко даже другим опытным разработчикам создавать низкокачественные, недорогие и/или дорогостоящие модульные тесты, которые не стоят. Тем более, учитывая, насколько сложно судить о значении a unit test.

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

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

 

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

Возьмите это как возможность заставить их использовать платформу Continuous Integration и разработать модульные тесты! Легкий способ произвести впечатление на силы, которые будут одновременно повышать качество и стабильность вашего кода.

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

 

Ну, моя компания не пошла с TDD или Unit Testing. Честно говоря, мы не знаем, как это сделать. Очевидно, мы можем сделать это для глупых функций, таких как CapitalizeString() и т.д., Но мы не знаем, как это сделать для сложных систем со сложными объектами. Более того, большинство опрошенных людей имеют либо нулевой опыт, либо ограниченный опыт. Похоже, что Unit Testing является большим от толпы SO, но не особенно большой в доступной рабочей области.

TDD - отдельная тема. Мы морально против TDD. Мы не ковбойские кодеры, но мы считаем, что это трюки в творчестве и гибкость в проекте. Более того, наличие кодера, написавшего модульную функцию тестирования, не имеет смысла. Когда я что-то делаю, я кодирую все крайние случаи, о которых я могу думать. Мне нужен другой мозг, чтобы искать вещи, которые я, возможно, пропустил. У нас этого нет. Команды небольшие и автономные.

Короче говоря, мы не верим в TDD, но мы хотели бы Unit Test. У нас просто нет опыта для этого, и мы не можем найти его легко.

 

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

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

Я считаю, что это ответ на ваш вопрос  **", что не хватает и почему не больше компаний, выполняющих модульное тестирование"** .: -)

 

Вероятно, это комбинация из нескольких вещей, о которых вы уже упоминали. Его трудно измерить экономию средств TDD. Если вы хотите передать свои ИТ-ресурсы на аутсорсинг, вы можете показать, сколько вы платите в год за ребят, которых у вас есть, по сравнению с расходами на его контракт; это очень конкретный. Как вы говорите: "О, этот тест поймал ошибку, которая потребовала бы меня 4 часа для отладки и исправления..."?

 

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

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

И как [Алан](/questions/60059/if-unit-testing-is-so-great-why-arent-more-companies-doing-it/416207#416207) говорит, что многие места просто не используют лучшие практики - они просто хотят увидеть что-то осязаемое.

 

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

 

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

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

Документируйте тест в своем коде. Просто поставьте комментарий, объясняющий, где находится тест и как его запустить. Будущие программисты увидят это и, надеюсь, тестирование будет распространяться!

 

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

 

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

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

 

Я большой поклонник модульных тестов, и я также являюсь партнером в компании, занимающейся проектами разработки контрактов для разных типов клиентов. Через месяц мы коснемся 3-4 различных проектов разного размера.

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

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

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

 

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

 

>  Я пропускаю модульное тестирование - это просто облегчает жизнь.
> 
> 
> 

Это не является достаточным основанием для принятия компанией единичного тестирования.

Достаточная причина может быть "дешевле" (и/или "лучше" ): это не так просто доказать об модульном тестировании.

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

Есть много разработчиков, которые не считают мир модульными тестами: в том числе те, кто считает, что другие формы тестирования (например, автоматическая интеграция/функциональные тесты) могут быть дешевле и ценнее, например [Я единственный разработчик, которому не нравятся модульные тесты?](http://discuss.joelonsoftware.com/default.asp?joel.3.725817.37)

 

Конечно, в идеальном мире вы не можете возражать против наличия unit test.

Однако, пишите ли вы unit test, зависит от нескольких вещей:

* Как будет использоваться программное обеспечение. Если бы вы писали программное обеспечение только для себя, вы бы записали модульные тесты? Возможно нет. Если вы пишете предварительно упакованное программное обеспечение для коммерческого использования, возможно, да.
* Сколько человек поддерживает код.... если он только вы, то вы можете знать его достаточно хорошо, чтобы быть достаточно уверенным после внесения изменений, что быстрый прогон кода достаточен, чтобы ничто не сломана. Если другие люди, которые не изначально пишут код, теперь должны его поддерживать, то unit test поможет им уверенно в том, что когда они обновляют код, чтобы исправить большой (который, очевидно, не был зафиксирован в unit test!), Они не имеют сломал что-нибудь.
* сложность кода: только тестовый код, который требует теста. Метод выделения одной строки не требует тестирования. Вероятно, существует 50-строчный метод с несколькими путями выполнения.
* Практические коммерческие коммерческие соображения: факт написания модульных тестов занимает больше времени, чем это не делается. Если вы пишете прототип программного обеспечения, у которого есть неопределенное коммерческое будущее, тогда есть оговорка, заключающаяся в том, что между быстрым и быстрым кодом теперь работает достаточно хорошо, чем с проверенным модулем кода за 2 недели, который работает лучше. Иногда стоит быстро узнать (потребительский аппетит), если программное обеспечение будет иметь короткую полку и перейти к следующему проекту.

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

 

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

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

Третья причина - ленивость и/или дешевизна.

 

Люди ленивы и только принимают изменения, когда вынуждены.

 

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

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

Команда QA вряд ли напишет код unit test, потому что компания обычно не обслуживает команду QA с помощью своих тяжелых кодеров.

Команда разработчиков неохотно пишет тестовый код, поскольку создает конфликт с командой QA.

Я проявляю больше интереса и принятия Unit Testing в группах, где QA не выделяется в отдельную функцию работы

 

Я думаю, что часть проблемы заключается в том, что разработчики ожидают, что деловые люди будут иметь одинаковый набор ценностей и действительно будут заботиться о ответе на вопрос "должны ли мы unit test или нет?". Мы не получаем официального одобрения от бизнеса, чтобы использовать язык высокого уровня, а не язык ассемблера - обычно это разумный способ получить работу.

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

Истина заключается в том, что мы не можем действительно доказать ROI на большинстве вещей, которые мы делаем с слишком тонкой детализацией. Почему модульное тестирование выдерживается до этого необоснованного/нестандартного стандарта доказательства, выходит за рамки меня...

 

Если вы хотите продать всех на тестирование, выполните следующие действия:

* Напишите кучу тестов.
* Сообщите другим разработчикам, которые меняют код и не выполняют свои тесты.
* Они исправит свой код.
* Теперь вы можете выпускать без особых ошибок.

Даже менеджер мог понять это.

 

Мои 2 цента:

* Это требует некоторого образования и дисциплины, но новые выпускники уже приходят с надлежащими знаниями.
* Накладные расходы тестов могут быть уменьшены с помощью лучших инструментов, и это также происходит (рефакторинг и т.д.).

  **Итак, это всего лишь вопрос времени.**

Там дебаты Мартина-Коплиена, в которых Боб Мартин утверждает, что:

>   "в настоящее время безответственно, чтобы разработчик отправил строку кода, которую он не выполнил в unit test." 
> 
> 
> 

[[http://www.infoq.com/interviews/coplien-martin-tdd]](http://www.infoq.com/interviews/coplien-martin-tdd%5D)

 

Компании не выполняют модульное тестирование по той же причине, что многие сайты написаны плохо - невежество, а люди придерживаются старых привычек.
В моей компании, так как мы начали модульное тестирование (с Nunit и [Typemock](http://www.typemock.com)), мы получаем более высокий охват кода и выпускаем программное обеспечение в более короткое время выхода на рынок.

 

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

 

Большинство компаний бесполезны. Не тот, с которым вы (или я) работаем, очевидно.

 

Две вещи - препятствия для модульного тестирования

* Все новое сложно сделать
* Все, что не имеет измеримой прибыли, плохо.
* Люди ленивы. Разработчики действительно.

В моей компании ( > 5.000 emp) модульные тесты "есть", но нет возможности сделать TDD или получить большой охват кода. Это трудно выполнить.