понедельник, 15 апреля 2013 г.

Тестирование глазами молодого специалиста

Написал мой коллега:


Тестирование глазами молодого специалиста.

К процессу тестирования, зачастую, относятся довольно пренебрежительно, не видя необходимости прибегать к разработке отдельных программных средств нахождения ошибок. Максимум, что может своевременно найти ошибку – это проверка самим разработчиком измененного кода, ревью кода других разработчиков или специальный человек (или коллектив), который контролирует работоспособность конечного продукта. Так мне казалось, когда закончив ВУЗ, поступило предложение заняться тестированием. Казалось бы, что может быть проще, чем проверить работоспособность программы, когда в твоем распоряжении находится актуальное ТЗ, архив с уже созданными и, в большинстве своем, исправленными ошибками, огромное количество обсуждений, в которых можно найти ответ практически на любой вопрос. Но ожидания оказались не совсем верными. И дело даже не в не умении найти нужный материал, а в разнице между текущим поведением программы и неясностями (двояким толкованием, пробелами) в текущих требованиях. И самый надежны способ определить единственно верное поведение – обратиться к людям, это поведение реализовывающим. К разработчикам. Но, естественно, с течением времени, с ростом количества реализованных и назначенных задач знания об определенных объектах и методах их реализации подзабываются. Это человеческое естество и с ним ничего не сделать. И на первый план выходят выходят автоматические тесты – минипрограммы, в которых четко зафиксировано ТЕКУЩЕЕ поведении системы, особенности ее работы. И чем больше этих программ – тем лучше, т.к. они будут охватывать всю систему (в идеале). Любое отклонение от нормы будет зафиксировано и человек вынесет решение – новая ли это ошибка или требования изменились и нужно изменить тест (эталон). Эту систему невозможно обмануть, новую ошибку нельзя пропустить (при наличии работоспособного теста), как это мог бы сделать, например, не вовремя отвлекшийся человек, ищущий ошибку. Но сильно забегаю вперед, перенесемся в самое начало пути – к тестированию системы вручную.
Моя работа тестировщиком началась со знакомства с системой. И сразу же появились первые вопросы – “Почему это работает так?”, ”Верно ли это?”. Вообще говоря, именно первые недели наиболее благоприятны для поиска ошибок, т.к. новый человек может заметить то, что большинство уже и за ошибку не считают. Новый сотрудник обращает внимание на каждый клик, каждое новое открывающееся окно, к любому событию он относится с подозрением - “А верно ли это?”. Далее, ответ на спорное поведение ищется в описании прецедентов в требованиях. Конечно, всегда можно спросить у знающих людей, но самостоятельный поиск информации ведет к гораздо более глубокому пониманию системы. Со временем, эти знания накапливаются, и новую ошибку уже можно найти не только в результате выполнения тесткейсов, но и проанализировав текущие изменения в системе. Приходит понимание возможных причин появления ошибок. С другой стороны, ежедневный поиск ошибок по четко зафиксированным алгоритмам интересен и разнообразен лишь первые 2-3 прогона всех заданий. Далее, внимание притупляется, тесткейсы уже вызывают меньше вопросов, становится очень трудно проверять задания не механически. Выходом стало тестирование другого проекта. И пусть задания похожи, но нужно вновь разбираться, активно работать с ТЗ, учиться новому. Далее следует возврат к первому проекту, затем опять на новый. Только такой подход, на мой взгляд, позволяет эффективно находить всё новые и новые ошибки. Но рано или поздно, сам процесс такого тестирования начинает казаться неэффективным. И я стал присматриваться к работе с автоматическими тестами, благо все условия были для этого созданы. Но жизнь вносит свои правки, и не успев даже поверхностно познакомится с автоматизированным тестированием, меня выбрали основным человеком, который этими тестами и занимается.
Переход от ручного тестирования к автоматизированному прошел на удивление гладко. Конечно, большая заслуга в этом людей, которые мне помогали и в простоте языка FORTH. Он идеально подошел для тестирования системы. Создавая простейший по реализации код, самостоятельно заводя новые функции и переменные, используя в качестве имен терминологию, принятую в системе, можно с легкостью проверить практически всё.

: Кликаем_на_кнопку_ДАЛЕЕ
 : Действия
  “Переместить курсор мыши на кнопку ДАЛЕЕ”
  “Кликнуть левой кнопкой мыши”
  “Определить, был ли переход по Далее”
 ; \\ Действия
 “Запомнить позицию курсора мыши и выполнить {(@ Действия)}”
; \\ Кликаем_на_кнопку_ДАЛЕЕ

Это кажется очень простым. Но это работает и позволяет держать руку на пульсе системы, практически мгновенно определяя появление неполадок.
Поначалу, небольшие сложности вызывала обратная польская запись кода, а также обилие форм, контролов и классов. Но это объяснимо: последний раз самостоятельно программировать пришлось в далеком 2005 году в колледже (если не ошибаюсь, последней работой стала программа “Определение уровня безопасности помещения” на Delphi). Программированием это назвать сложно – все в рамках учебных курсов. Но тем не менее, основы, заложенные тогда, помогают разбираться и теперь с тестами. Когда приходит понимание, как найти контрол на форме, как передать ему фокус – настроение сразу поднимается. Это увлекательно, здесь нет однообразия: нужно успевать фиксировать результаты прогона тестов, писать новые, править старые, распределять тесты по пресетам, разбираться в старых ошибках, чужом коде и думать (последнее самое ценное). Поэтому, мое отношение к автотестам – очень позитивное и положительное. Да, можно проверить уже исправленные ошибки вручную, но здесь главную роль играет время – его уйдет неимоверно много на повторение старой ошибки, по сравнению со временем прохождения теста.
Помимо всего прочего, довольно интересно наблюдать за работой автоматических тестов со стороны – кажется удивительной “самостоятельная жизнь” системы, часто вижу заинтересованные взгляды коллег.
В чем же главные преимущества автоматизированного тестирования от ручного? В быстроте проверки, в точности полученных результатов, в однозначном полученном результате, в том, что для эффективного нахождения ошибок достаточно всего одного человека. К минусам можно отнести огромное количество тестов (десятки тысяч), которыми нужно покрыть все прецеденты, сложность обработки результатов (для этого требуются специальные знания).
Но плюсов, безусловно, больше, ведь главное – не пропустить ошибку. А если есть тест, который проверяет исправленную ошибку, то в случае ее возврата, она будет найдена.
На мой взгляд, в перспективе – мало покрыть все ошибки тестами, т.к. они охватывают не всю систему. Всю систему охватывает ТЗ – и нужно каждое его предложение покрыть тестом. Или двумя, или тремя. Чтобы они полностью и однозначно следили за текущим поведением системы, и в случае отклонения от ТЗ – сразу сообщали об этом. Они должны быть изолированы от тестов, работающих с ошибками (запускаться отдельно). В этом случае, напрямую идет проверка основного описанного функционала системы. И чем подробнее будет ТЗ, тем тщательнее будет проходить проверка системы.

Прим.: Мнение автора может не совпадать с мнением коллег.

Трофимов Андрей

4 комментария:

  1. >>Прим.: Мнение автора может не совпадать с мнением коллег.
    Мнение автора НЕ должно совпадать с мнение коллег. На противоречиях и основан процесс развития. Философия - тезис - анти-тезис - синтез. "Другое" мнение - показатель профессионализма, а не повод писать disclaimer.

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

    Но проблематику можно посмотреть шире в контексте построения сценариев взаимодействия. Либо мы жёстко фиксируем сценарии (в интерфейсе), либо мы просто экспонируем тонну активируемого контролами функционала.

    В первом случае сценарии будут жёстко тащить пользователя за уши, зато покрытие будет почти 100%.
    Либо мы получим бесконечное множество возможных вариантов воздействия на программу.

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

    Тогда люди начинают страдать от комплекса неполноценности (ай-йяй, у нас тестеров нету), но по факту им тестера просто не найти по природе задачи.

    И поять же. Есть множество тестов (кейсов). Но не все они равновероятны. По нормальному закону в "три-сигма" вообще все не войдут (а достаточно просто 1-ой сигмы). Может, тогда стоит разумно жертвовать?

    ОтветитьУдалить
  2. Маленькая ремарка. Про покрытие и "сигму". Надеюсь я когда-нибудь найду силы и напишу развёрнутый пост на эту тему (я и так уж очень много чего обещал и так мало по делу написал).

    Мы пишем тесты в первую очередь по:
    1. Ошибкам. Которые стабильно повторялись.
    2. Пользовательским сценариям (UseCase) описанным в ТЗ.
    3. Аспектам поведения системы (опять же из ТЗ) типа - "контекстное меню тут должно выглядеть так, а тут вот так".
    4. Граничным условиям.
    5. Нефункциональным требованиям - "кнопка должна быть красной, а не зелёной".

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

    ОтветитьУдалить
  3. А "жертвовать" - конечно разумно, что мы собственно и делаем.

    ОтветитьУдалить
  4. И потом (про это я тоже отдельно напишу):

    У нас есть как минимум два рода тестов:
    1. GUI-Тесты конечных пользовательских приложений.
    2. "unit"-тесты библиотек проектных классов. Тестирующие проектные классы на соответствие спецификации.

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