Я - относительно новый разработчик программного обеспечения, и я думаю, что одна из вещей, которую я должен улучшить, - это моя способность тестировать свой собственный код. Всякий раз, когда я разрабатываю новую функциональность, мне действительно трудно следовать всем возможным путям, чтобы я мог находить ошибки. Я склонен следовать по пути, где все работает. Я знаю, что это хорошо известная проблема, с которой сталкиваются программисты, но у меня нет тестеров у моего нынешнего работодателя, и мои коллеги, похоже, в этом очень хороши.
В моей организации мы не занимаемся разработкой на основе тестирования или модульным тестированием. Это очень мне поможет, но вряд ли это изменится.
Что вы, ребята, думаете, я мог бы сделать, чтобы преодолеть это? Какой подход вы используете при тестировании собственного кода?
Ответы:
Работа программиста - создавать вещи.
Работа тестера - ломать вещи.
Самое сложное - это сломать вещи, которые ты только что построил. Вы добьетесь успеха, только преодолев этот психологический барьер.
источник
Франциско, я собираюсь сделать здесь некоторые предположения, основываясь на том, что вы сказали:
«Мы не занимаемся ни TDD, ни модульным тестированием. Это мне очень поможет, но вряд ли это изменится».
Исходя из этого, я подозреваю, что ваша команда не придает большого значения тестированию, или руководство не будет тратить время на то, чтобы команда попыталась привести в порядок существующий код и свести техническую задолженность к минимуму.
Во-первых, вам нужно убедить свою команду / руководство в ценности тестирования. Будьте дипломатичны. Если руководство заставляет вашу команду двигаться вперед, вам нужно показать им некоторые факты, такие как уровень дефектов для каждого выпуска. Время, потраченное на исправление дефектов, может быть лучше потрачено на другие вещи, такие как улучшение приложения и его адаптация к будущим требованиям.
Если команда и руководство в целом безразличны к исправлению кода, и вам это не нравится, вам, возможно, придется искать другое место для работы, если вы не можете убедить их, как я уже сказал. Я сталкивался с этой проблемой в разной степени во всех местах, где я работал. Это может быть что угодно: от отсутствия подходящей модели предметной области до плохого общения в команде.
Забота о вашем коде и качестве продукта, который вы разрабатываете, является хорошим атрибутом, который вы всегда хотите поощрять в других людях.
источник
Если вы пишете код на C, Objective-C или C ++, вы можете использовать CLang Static Analyzer, чтобы критиковать ваш источник, фактически не запуская его.
Доступны некоторые инструменты отладки памяти: ValGrind, Guard Malloc в Mac OS X, Electric Fence в * NIX.
Некоторые среды разработки предоставляют возможность использовать распределитель памяти для отладки, который выполняет такие вещи, как заполнение вновь выделенных страниц и недавно освобожденных страниц мусором, обнаружение освобождения нераспределенных указателей и запись некоторых данных до и после каждого блока кучи, причем отладчик является вызывается, если известный шаблон этих данных когда-либо меняется.
Какой-то парень из Slashdot сказал, что он получил большую выгоду от пошагового создания новой строки исходного кода в отладчике. «Вот и все», сказал он. Я не всегда следую его совету, но когда он у меня был, он мне очень помог. Даже если у вас нет тестового примера, который стимулирует необычный путь кода, вы можете вертеть переменную в своем отладчике, чтобы взять такие пути, скажем, выделив некоторую память, а затем с помощью отладчика установить новый указатель на NULL вместо адрес памяти, затем пошаговое выполнение обработчика ошибок выделения.
Используйте утверждения - макрос assert () в C, C ++ и Objective-C. Если ваш язык не предоставляет функцию assert, напишите ее самостоятельно.
Используйте утверждения свободно, а затем оставьте их в своем коде. Я вызываю assert () "Тест, который продолжает тестирование". Я использую их чаще всего для проверки предварительных условий в точке входа большинства моих функций. Это одна из частей «Программирование по контракту», которая встроена в язык программирования Eiffel. Другая часть - это постусловия, то есть использование assert () в точках возврата функции, но я обнаружил, что я не получаю от этого столько же пробега, сколько предварительные условия.
Вы также можете использовать assert для проверки инвариантов класса. Хотя ни один класс строго не должен иметь инварианта вообще, у наиболее разумно разработанных классов они есть. Инвариант класса - это некое условие, которое всегда истинно, кроме как внутри функций-членов, которые могут временно переводить ваш объект в противоречивое состояние. Такие функции всегда должны восстанавливать согласованность, прежде чем вернуться.
Таким образом, каждая функция-член может проверять инвариант при входе и выходе, а класс может определять функцию с именем CheckInvariant, которую любой другой код может вызывать в любое время.
Используйте инструмент покрытия кода, чтобы проверить, какие строки вашего источника на самом деле тестируются, а затем спроектируйте тесты, которые стимулируют непроверенные строки. Например, вы можете проверить обработчики нехватки памяти, запустив ваше приложение внутри виртуальной машины, которая настроена с небольшим количеством физической памяти, и без файла подкачки или очень маленького.
(По какой-то причине я никогда не был в курсе, хотя BeOS мог работать без файла подкачки, он был крайне нестабильным. Доминик Джампаоло, который писал файловую систему BFS, убеждал меня никогда не запускать BeOS без подкачки. понимаю, почему это должно иметь значение, но это должен быть какой-то артефакт реализации.)
Вам также следует проверить реакцию своего кода на ошибки ввода-вывода. Попробуйте сохранить все свои файлы в общем сетевом ресурсе, а затем отсоедините сетевой кабель, когда приложение загружено. Аналогичным образом отсоедините кабель - или выключите беспроводную связь - если вы общаетесь по сети.
Одна вещь, которую я нахожу особенно раздражающей, это сайты, которые не имеют надежного кода Javascript. Страницы Facebook загружают десятки маленьких файлов Javascript, но если какой-либо из них не удается загрузить, вся страница разрывается. Просто должен быть какой-то способ либо обеспечить некоторую отказоустойчивость, скажем, путем повторной загрузки, либо предоставить какой-то разумный запасной вариант, когда некоторые из ваших сценариев не загружались.
Попробуйте убить ваше приложение с помощью отладчика или с помощью команды "kill -9" в * NIX, пока оно находится в середине написания большого, важного файла. Если ваше приложение хорошо спроектировано, весь файл будет записан или не будет записан вообще, или, может быть, если он будет записан только частично, то, что записывается, не будет повреждено, а сохраненные данные будут полностью использованы приложение после перечитывания файла.
базы данных всегда имеют отказоустойчивый дисковый ввод-вывод, но вряд ли какое-либо другое приложение имеет. Хотя журнализированные файловые системы предотвращают повреждение файловой системы в случае сбоя питания или сбоев, они вообще ничего не делают для предотвращения повреждения или потери данных конечного пользователя. За это отвечают пользовательские приложения, но вряд ли кто-либо, кроме баз данных, реализует отказоустойчивость.
источник
Когда я смотрю на тестирование своего кода, я обычно прохожу серию мыслительных процессов:
Самый простой способ, который я нашел, это разработать свои тесты вместе с моим кодом. Как только я написал хотя бы фрагмент кода, мне нравится писать тест для него. Попытка выполнить все тестирование после кодирования нескольких тысяч строк кода с нетривиальной цикломатической сложностью кода - это кошмар. Добавить еще один или два теста после добавления нескольких строк кода очень просто.
Кстати, только потому, что компания, в которой вы работаете, и / или ваши коллеги не проводят модульное тестирование или TDD, не означает, что вы не можете попробовать их, если они специально не запрещены. Возможно, использование их для создания надежного кода будет хорошим примером для других.
источник
В дополнение к советам, приведенным в других ответах, я бы предложил использовать инструменты статического анализа (в Википедии есть список ряда инструментов статического анализа для разных языков ) для поиска потенциальных дефектов до начала тестирования, а также для мониторинга некоторых показателей, которые относятся к тестируемость кода, такая как цикломатическая сложность , меры сложности Холстеда , а также сплоченность и связь (их можно измерить с разветвлением и разветвлением ).
Поиск трудного для тестирования кода и упрощение его тестирования, в свою очередь, облегчит вам написание тестовых примеров. Кроме того, раннее обнаружение дефектов повысит ценность всей вашей практики обеспечения качества (включая тестирование). Отсюда знакомство с инструментами модульного тестирования и инструментами насмешки облегчит вам проведение тестирования.
источник
Вы можете изучить возможное использование таблиц правды, чтобы помочь вам определить все возможные пути в вашем коде. Невозможно учесть все возможности в сложных функциях, но как только вы установили обработку для всех известных путей, вы можете установить обработку для другого случая.
Большая часть этой специфической способности изучена, хотя. После того, как вы использовали определенную среду в течение значительного периода времени, вы начинаете видеть шаблоны и признаки поведения, которые позволят вам взглянуть на фрагмент кода и увидеть, где небольшое изменение может вызвать серьезную ошибку. Единственный способ увеличить ваши способности в этом - это практика.
источник
Если, как вы сказали, вам не нужно модульное тестирование, я не вижу лучшего способа, чем пытаться взломать ваш собственный код вручную.
Попробуйте раздвинуть свой код до предела . Например, попробуйте передать переменные в функцию, выходящую за пределы границ. У вас есть функция, которая должна фильтровать пользовательский ввод? Попробуйте ввести разные комбинации символов.
Учитывайте точку зрения пользователя . Попробуйте стать одним из пользователей, которые будут использовать ваше приложение или библиотеку функций.
источник
Ваши коллеги должны быть действительно исключительными, чтобы не следить за TDD или модульным тестированием и никогда не генерировать ошибки, поэтому на каком-то уровне я сомневаюсь, что они не проводят никакого модульного тестирования самостоятельно.
Я предполагаю, что ваши коллеги проводят больше тестов, чем разрешают, но поскольку этот факт не известен руководству, то в результате у организации возникает впечатление, что у руководства создается впечатление, что настоящее тестирование не проводится, и поэтому количество ошибок низкое тестирование неважно и время для него не запланировано.
Поговорите со своими коллегами и попытайтесь выяснить, какой тип модульного тестирования они проводят, и подражайте этому. Позже вы сможете создать прототипы лучших способов для модульного тестирования и атрибутов TDD и постепенно представить эти концепции группе для более удобного принятия.
источник
Вы должны иметь возможность получить покрытие того, что вы пишете, даже если ваша организация не имеет полного покрытия. Подобно многим вещам в программировании, опыт повторения этого снова и снова - один из лучших способов быть эффективным в этом.
источник
В дополнение ко всем другим комментариям, так как вы говорите, что ваши коллеги хорошо умеют писать тесты с несоответствующим пути, почему бы не попросить их присоединиться к вам при написании некоторых тестов.
Лучший способ учиться - это видеть, как это делается, и извлекать уроки из этого.
источник
Тестирование черного ящика! Вы должны создавать свои классы / методы с учетом тестирования. Ваши тесты должны быть основаны на спецификации программного обеспечения и должны быть четко определены на вашей диаграмме последовательности (через варианты использования).
Теперь, так как вы можете не захотеть заниматься разработкой на основе тестов ...
Поставьте подтверждение ввода для всех входящих данных; не доверяй никому .NET Framework имеет множество исключений, основанных на недопустимых аргументах, нулевых ссылках и недопустимых состояниях. Вы уже должны подумать об использовании проверки входных данных на уровне пользовательского интерфейса, так что это тот же прием в промежуточном программном обеспечении.
Но вы действительно должны проводить какое-то автоматическое тестирование; этот материал спасает жизни.
источник
По моему опыту
Тестовый блок, если он не полностью автоматический, он бесполезен. Это больше похоже на то, что босс с заостренными волосами мог купить. Почему ?, потому что Test Unit обещал вам сэкономить время (и деньги), автоматизируя некоторые процессы тестирования. Но некоторые инструменты тестового модуля делают наоборот: это заставляет программистов работать странным образом и заставляет других создавать чрезмерные тесты. В большинстве случаев это не сэкономит рабочий час, но увеличит время перехода от QA к разработчику.
UML - это еще одна трата времени. одна доска + ручка может сделать то же самое, дешевле и быстрее.
Кстати, как быть хорошим в кодировании (и избежать ошибок)?
а) атомарность. Одна функция, которая выполняет одну простую (или несколько отдельных задач). Поскольку его легко понять, его легко отследить и легко решить.
б) гомология. Если, например, вы вызываете базу данных с помощью процедуры сохранения, выполните остальную часть кода.
в) Определить, уменьшить и изолировать «творческий код». Большая часть кода в значительной степени копируется и вставляется. Творческий код - это наоборот, код, который является новым и действует как прототип, он может потерпеть неудачу. Этот код подвержен ошибкам логики, поэтому важно его сократить, изолировать и идентифицировать.
d) код «Тонкий лед» - это код, который, как вы знаете, является «неправильным» (или потенциально опасным), но все еще нуждается, например, в небезопасном коде для многозадачного процесса. Избегайте, если можете.
e) Избегайте кода черного ящика, включая код, который вы не сделали (например, фреймворк) и регулярное выражение. С таким кодом легко пропустить ошибку. Например, я работал в проекте, используя Jboss, и обнаружил не одну, а 10 ошибок в Jboss (используя последнюю стабильную версию), это была PITA, чтобы найти их. Избегайте специально Hibernate, он скрывает реализацию, отсюда и ошибки.
е) добавить комментарии в свой код.
г) пользовательский ввод как источник ошибок. определить это. Например, SQL-инъекция вызвана пользовательским вводом.
h) Определить плохой элемент команды и отделить поставленную задачу. Некоторые программисты склонны испортить код.
я) Избегайте ненужного кода. Если, например, классу нужен интерфейс, используйте его, иначе не добавляйте нерелевантный код.
а) и б) являются ключевыми. Например, у меня была проблема с системой, когда я нажимал кнопку (сохранить), она не сохраняла форму. Затем я сделал контрольный список:
И sidenote
источник
Тестер и программист сталкиваются с проблемой с разных сторон, но обе роли должны полностью тестировать функциональность и находить ошибки. Где роли отличаются, в центре внимания. Классический тестер видит приложение только снаружи (т.е. черный ящик). Они являются экспертами по функциональным требованиям приложения. Предполагается, что программист будет экспертом как по функциональным требованиям, так и по коду (но имеет тенденцию уделять больше внимания коду).
(От организации зависит, ожидается ли, что программисты явно будут экспертами по требованиям. Несмотря на это, существует неявное ожидание - если вы спроектируете что-то не так, вы - не специалист по требованиям - получите вину.)
Эта двойная роль эксперта накладывает отпечаток на ум программиста и, за исключением самых опытных, может снизить уровень требований. Я считаю, что я должен мысленно переключать передачи, чтобы рассмотреть пользователей приложения. Вот что мне помогает:
источник
Я думаю, что вы хотите работать по двум направлениям. Один из них - политический: заставить вашу организацию принять тестирование на каком-то уровне (с надеждой, что со временем они примут больше). Поговорите с инженерами QA за пределами вашего рабочего места. Найти списки книг QA . Покопайтесь в соответствующих статьях Википедии . Ознакомьтесь с принципами и методами обеспечения качества. Изучение этого материала подготовит вас к тому, чтобы сделать наиболее убедительные аргументы в своей организации. Хорошие отделы контроля качества существуют, и они вносят значительный вклад в свои организации.
Как индивидуальный разработчик, примите стратегии для использования в своей работе. Используйте TDD самостоятельно, совместно разрабатывая код и тесты. Держите тесты чистыми и в хорошем состоянии. Если вас спросят, почему вы это делаете, вы можете сказать, что предотвращаете регрессию, и это помогает лучше организовать ваш мыслительный процесс (оба из них будут правдой). Есть искусство писать тестируемый код , изучать его. Будьте хорошим примером для ваших коллег-разработчиков.
Частично я здесь проповедую самому себе, потому что я делаю намного меньше всего этого, чем я знаю, что должен.
источник