Разделы портала

Онлайн-тренинги

.
Язык автотестов != язык приложения
15.08.2016 12:14

Автор: Джефф Найман

Оригинал статьи: http://testerstories.com/2015/12/automation-language-is-not-necessarily-your-development-language/

Перевод: Ольга Алифанова

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

Конечно, я преувеличиваю, и, возможно, это несправедливо по отношению к командам и компаниям, но я довольно часто сталкиваюсь с подобной точкой зрения, и она не перестает меня раздражать. Честно говоря, я и сам когда-то так считал – я спрашивал, должен ли язык разработки соответствовать языку автотестов. По тексту может показаться, что я склоняюсь к ответу "должен", но на самом деле я в тот момент экспериментировал со своими практиками. Большинство этих экспериментов крутились вокруг ответа на вопрос, который часто задают мне тестировщики: какой язык программирования осваивать?

Выбор языка

Обратите внимание: мы говорим о языке, который будет использоваться в автоматизации, а не о выборе конкретного инструмента. Выбор инструментов – это большая отдельная тема, которая не противоречит вопросу о выборе языка. Моя цель в этой статье – разобраться в том, должен ли язык программирования для тестирования соответствовать языку программирования для приложения.

Совместный труд тестировщиков и разработчиков

Алистер Скотт размышлял на эту тему в статье "Выбор языка для приемочных автотестов". Цитирую:

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

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

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

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

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

Тестировщики, исправляющие баги?

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

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

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

Тестировщики ревоплощают функциональность

Адам в своей статье "Но наше приложение написано на Х" тоже поднимает интересные вопросы, цитирую:

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

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

Приведу конкретный пример. У меня есть псевдоприложение Symbiote, на котором я проверяю свои собственные автоматизированные решения. В нем, в частности, есть калькулятор Stardate, который срабатывает через JavaScript и конвертирует звездную дату в календарную (тоже посредством JavaScript). Когда я тестирую его, я не обязан использовать JavaScript. Я могу ревоплотить конвертацию даты на другом языке не хуже, чем на JavaScript. Вот пример логики Java, описывающей конвертацию времени:


Ключевая строчка тут под номером 12 – convertTNGStardate вызывает модель расчетов. Метод modelTNGCalculation делает именно это: в целом он ревоплощает в Java алгоритм JavaScript, предоставляя специфическую дату, относительно которой можно тестировать. Другой подобный пример я приводил в статье "Модели, правила и особенности", где я внедрял специфический алгоритм для расчета силы притяжения поверхности планеты, чтобы определить, работает ли "Калькулятор веса планеты". В том случае расчеты веса планеты были также на JavaScript, а моделировал я их на Ruby.

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

Выбирайте язык, исходя из интересов ответственных лиц

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

Один из аргументов в споре о языке – это "Это все здорово, но Java/Python/C#/вписать нужное-разработчиков куда проще нанять". Да, возможно, это так. Возможно, на вашем рынке найти разработчика (включая разработчика тест-решений) куда проще для какого-то конкретного языка. Если это ваш случай, то в процессе создания своей команды вы логичным образом наймете тех, у кого есть опыт работы с желаемым языком. Если команда не возражает – нет проблем.

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

Вы также можете оказаться в ситуации, когда тестировщики прекрасно знают язык разработки (пусть это будет Python), но предпочитают полагаться на язык с более широкой и устойчивой экосистемой тестов (например, Ruby), или на экосистему, в которой можно использовать множество различных языков (например, JVM, позволяющую Java, Groovy, Scala).

Отвлечемся на минутку и поговорим о том, почему "языковая сегрегация" – это очень плохо. Вот пример автоматизированного скрипта на двух разных языках:

Python:


Ruby:


Допустим, в команду пришел новичок. Если он освоил Selenium API (в примере используется именно это), он может легко начать использовать Python или Ruby в работе. Тут не нужно быть мастером кун-фу Ruby или Python – достаточно знаний, позволяющих работать с Selenium API, а по этой теме полно исчерпывающей информации. Теперь давайте посмотрим на статические языки и тот же самый скрипт:

C#


Java


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

Автоматизация опирается на существующие API

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

Фактически Selenium – это и есть API. Это API, позволяющий создавать код, управляющий браузером. Это инструмент автоматизации браузера, но это не инструмент автоматизации тестирования, и даже не средство для проверок. Selenium даже не дает вам способа определить, прошел ваш тест или провалился. Для определения, добились ли ваши автотесты нужного результата, нужно явно указывать библиотеки правил или ожиданий.

Selenium API разговаривает с "родными" элементами и бинарниками через протокол связи – REST-вебсервис, использующий JSON через HTTP. Это сердце Selenium. Я расписываю все эти детали, потому что хочу лишний раз указать на то, что они не имеют никакого отношения к автоматизации действий, совершенных на вашем сайте или в вашем приложении.

Чтобы работать с Selenium, вам нужно выбрать язык, на котором вы будете писать ваши тесты. Как я уже говорил выше, это можно делать на любом современном языке – для этого подойдут и JavaScript, и Go, и PHP, Perl, Haskell.

Автоматизация зависит от экосистем

Выше я уже упоминал, что нужно также учитывать экосистему, в которой вы собираетесь действовать. Например, широко известно, что сообщество Ruby "заражено тестированием". Это означает, что оно уделяет тест-мышлению и разработке решений для тестирования большое внимание. В результате на Ruby доступно множество решений для автоматизации тестирования. У вас не только будет огромный выбор, но и возможность получить новые знания. Если вы выбираете эту экосистему, то вам будут доступны "оболочки", интегрирующие существующие инструменты и API и облегчающие жизнь вашей автоматизации.

Стоит также учесть и операционные аспекты. Я уже упоминал Java Virtual Machine – фантастическую платформу для создания решений, широко доступную и качественно поддерживаемую. Однако решения на Java обычно довольно запутанны и очень раздражают в связи, в основном, с ограничениями, с которыми придется мириться, если вы используете JVM. Но не Java единой жив человек. Вы можете использовать Groovy или Scala. Вы можете выбрать решения вроде JRuby (Ruby на JVM), JPython (Python на JVM), Nashorn (JavaScript на JVM). Более того, у языков вроде Java отличная поддержка IDE благодаря статической природе языка. С Ruby/Python IDE ситуация совсем иная.

Автоматизация должна смотреть в будущее

Не забудьте про то, что с автоматизацией вам жить и жить. Набор тестов/проверок будет расти, и вам понадобится пополнять функциональность, чтобы его можно было легко использовать, быстро прогонять, запускать в параллели, прогонять как часть виртуальных контейнеров, получать более подробную отчетность… Каждый раз, когда нечто подобное произойдет, вам нужно будет эффективно решить две задачи – создания, пересмотра и поддержки тест-фреймворка, и создания автотестов. Если вы добавите сюда что-нибудь вроде BDD, то появится дополнительный уровень сложности.

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

Обсудить в форуме