пятница, 15 апреля 2011 г.

Почему программисты не тестируют?

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

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

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

Почему тестирование программистами не так эффективно, как тестировщиками? Вы когда-нибудь видели, как программисты тестируют собственный продукт? Выглядит это примерно так: программист проходится по написанному функционалу и вдруг находит ошибку. После естественного недоумения: "Как в моем функционале может быть бага?!" на все помещение звучит: "Ребята, я нашел багу, вот тут слово с ошибкой написано!!". Тут же собирается консилиум из еще 2-3 программистов. Они рассматривают эту ошибку (потому что ее нашел ПРОГРАММИСТ!!), пытаются осмыслить как эта ошибка появилась, кто где налажал. Смотрят логи. Ищут виноватого. После детального анализа начинают фиксить. Работа стоит. Они нашли одну ошибку, они заняты.
Тестировщик находит ошибку, фиксирует ее, идет дальше, находит еще, опять фиксирует. Находит третью. Понимает, что тут возможно еще какое-то интересное поведение, начинает копать глубже. При этом он может выдавать эти баги программисту по одной, может - сразу ворохом "счастья". Работа не останавливается из-за того, что тестер находит багу. Чтобы добиться консилиума программистов, нужно найти что-нибудь ну очень серьезное: show-stopper, например.

Программисты очень умные ребята. Они пишут те программы, которые нам потом достаются на растерзание (что бы мы без них делали?). Они замечательно пишут юнит-тесты. Некоторые из них отлично автоматизируют на уровне API. Это, несомненно, помогает сразу же после выкладки новой версии или слияния веток, или какого-нибудь рефакторинга. Но вот тестирование все же лучше им не доверять. ))))

Берегите программистов!



10 комментариев:

  1. Честно говоря для меня несколько дико звучит. У нас один трекер и все туда пишут баги. Какая разница кто нашел баг - тестер или программист?

    ОтветитьУдалить
  2. Ну, если один отдельно взятый баг, то конечно какая разница? Я тут за весь процесс тестирования в целом: можно ли повесить на программиста еще и тестирование. )))
    Хотя у меня был печальный опыт работы с кодерами, которые находя баг, тактично о нем молчали и отслеживали: найдет тестировщик этот баг или нет. ))))

    ОтветитьУдалить
  3. Моя в шоке, моя не понимать...
    И так, с точки зрения тестирования как программист у нас в проекте я вижу следующие аспекты.
    1. Unit, оно же модульное тестирование. В самом названии кроется проблема. Эти тесты проверяют модуль оторванный, так сказать, от реальности, проверяют контракты и зачастую используются mock/stub объекты, которые подменяют другие модули системы.
    Рассмотрим следующую ситуацию. У нас есть два модуля A и B. A использует B. При модульном тестировании допустим вместо B мы используем его простой заменитель mB. Т.о. если кто-то изменит модуль B (в случае правильно написанных тестах и низменности интерфейса модуля) упадут только тесты на модуль B, этот человек подправит эти тесты, они отработают и мы считаем, что система работает правильно. Но на самом деле, mB в тестах на модуль A будет работать по старым правилам. Т.е. хоть тесты на модуль A не будут падать, конечное приложение в котором будет использоваться A вместе с B (а не mB) с высокой долей вероятности будет работать не правильно.
    Этот проблема решается несколькими способами. Например на daily митинге, где обсуждаются текущие задачи, следовательно человеку меняющему модуль B могут подсказать обратить внимание на A.
    2. Но так же можно использовать вторую ступень. Автоматические интеграционные тесты. Они сложные, более долгие в написании, часто требуют разработки или модификации специального движка для их работы. Но у них очень важная цель, они запускают полностью собранное конечно приложение, т.е. если говорить о примере выше, то тут тест будет проверять уже работу модулей A и B вместе. Плюс проверяются уже не какие-то внутренние контракты модулей, а именно поведение приложения.
    Фактически, это же и делает тестировщик. Только он умнее робота и смотри так сказать по сторонам. Но автоматизировать эти тесты надо, кровь из носа. Так как растёт функциональность и у тестировщиков зачастую просто не остаётся времени на регрессию.
    Вообще мой сугубо личный взгляд, нельзя тестировщиков заставлять прокликивать тест кейсы, они должны их составлять, а дальше отдавать роботу. А так же заниматься исследовательским тестированием, то бишь смотреть по сторонам.

    ОтветитьУдалить
  4. Но что-то я отдалился от вашего текста. Вот, что меня поразило. На самом деле, по моим ощущения, фактически 90% багов находят именно программисты. Когда я пишу тесты и даже, когда пишу код, понимаю, что тут баг и сразу переделываю или добавляю в todo и, как только доделаю текущую задачу, фикшу эту проблему. Это всё зачатую маленькие и незначительные проблемки, которые как раз и находятся unit тестами. А если что-то большое или не относится к моей текущей задаче, заношу в баг трекер. Именно поэтому я был шокирован вашим рассказом. Я никогда не видел таких бурных обсуждений... За исключением редких случаев сложных или смешных багов, но уж очень редко.
    Честно говоря, я считаю, что большую часть тестирования должны делать именно программисты. Отдельные тестировщики нужны исключительно для приёмочного тестирования. Можно это сделать как я сказал двух этапно, модульными и интеграционными тестами. И тест кейсы для обоих случаев должен писать программист. Если он не способен этого сделать, то как он пишет код? Как можно написать код, если у тебя нет чёткого представления, когда и как он должен работать? Если какие-то тест кейсы ты пропустил, значит был плохо проведён анализ.
    Да, кстати, насчёт этого есть ещё одна мысль. Понятие замыленого взгляда. Когда долго работаешь с задачей и можешь пропустить очивидную проблему. И тут просто любой другой человек посмотревший на код или программу в действии - её находит. И это не обязательно, а лучше совсем не обязательно, чтобы это был тестировщик. Поэтому так важно правильное code review, а лучше парное программирование.
    Ну и последний момент насчёт TDD. Помоему это больше архитектурны подход. Но вся соль в вашем случае в том, что я выше написал. Если программист не способен составить правильные тест кейсы, то ни чего не поможет, код будет с багами. В случае TDD он просте не напишет таких тестов. Поэтому да, надо учится и тратить время на граммотный анализ задачи, перед тем как бросаться её писать.
    --
    Извините, пришлось разбить комментарий на два, потому что блоггер не захотел принимать комментарий такой длины :(

    ОтветитьУдалить
  5. Огогошеньки какое приятное чтиво мне было приготовлено на утро! )))
    Павел, а Вы, собственно, подтверждаете то, что я написала. Программисты прекрасно пишут юнит-тесты! И большинство ошибок фиксят еще на ранних этапах непосредственно в коде. И функционал отдают на тестирование больше надеясь на верификацию, а не на нахождение багов. И с автотестами нам помогают.
    Только вот сам процесс тестирования им лучше не отдавать. Потому что это более дорого и менее полезно.
    Кстати, процесс анализа задачи у нас включает не только программиста, но и тестировщика, и Product Owner. А уже на этапе проектирования - только несколько девелоперов. ))

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

    ОтветитьУдалить
  7. Да, согласна. Особенно тяжело если такой тестировщик один на проекте и некому его подстраховать. )))

    ОтветитьУдалить
  8. Я так и не понял почему программисты не тестируют :)

    ОтветитьУдалить
  9. @Сергей Олейников
    Потому что тестировщики считают, что программисты не умеют тестировать ;)

    ОтветитьУдалить
  10. ну и потому что если бы они еще и тестировать умели, то нас бы вообще не было ))))
    Отличный обмен мнениями получился, обязательно упомяну в своем докладе )))

    ОтветитьУдалить