asolntsev, andrei solntsev

Bullshit driven development

Сегодня я хочу поговорить о тестировании.

Недавно я съездил на конференцию Selenium Camp в Киеве. Это было зыбско, чо. Познакомился с разными интересными людьми, занимающимися тестированием, в том числе из таких компаний, как Odnoklassniki и Yandex. А главное, я многое понял о том, почему тестировщики такие непохожие на нас.

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



BDD в тренде


Так вот, оказалось, что в моде нынче BDD - Behaviour Driven Development. В контексте UI тестов и Selenium больше всего говорили про фреймвокр Thucydides. Если коротко, это мега-гипер-монстр (одно только оглавление документации занимает 33 страницы!!!), заставляющий бедных тестировщиков писать много-много лишнего кода.

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

@Test
public void userCanLoginByUsername() {
  open("/login");
  $(By.name("userName")).setValue("johny");
  $("#submit").click();
  $(".welcome").shouldHave(text("Hello, Johny!"));
}


Как реализовать его на Thucydides?
Тут нужно несколько шагов, начнём с малого.

Для начала нам понадобится написать Page Object:
  @FindBy(name="userName")
  private WebElement usernameInput;

  @FindBy(id="submit")
  private WebElement submitButton;

  public LoginPage(WebDriver driver) {
    super(driver);
  }

  public void enter_username(String username) {
    usernameInput.sendKeys(username);
  }

  public DashboardPage submit_login() {
    submitButton.click();
    return new DashboardPage(driver);
  }
}


Уже втрое больше кода. Но это только начало!

Идём дальше, теперь бедный тестировщик должен написать ещё Step Object:
  public EndUserSteps(Pages pages) {
    super(pages);
  }

  @Step
  public void logs_in_with(String usename) {
    enters_username(username);
    performs_login();
  }

  @Step
    public void enters_username(String username) {
    onLoginPage().enter_username(username);
  }

  @Step
  public void performs_login() {
    onLoginPage().submit_login();
  }

  private LoginPage onLoginPage() {
    return getPages().currentPageAt(LoginPage.class);
  }

  @Step
  public void should_see_welcome_message(String userFullName) {
    assertThat(onDashboardPage().getWelcomeMessage(), is(userFullName));
  }
}


Думаете, всё? Как бы не так, мы только на полпути.

Теперь надо ещё намонстрячить Story с описанием того, что делается, на "человеческом" языке:

  @Managed(uniqueSession = true)
  public WebDriver webdriver;

  @ManagedPages(defaultUrl = "http://localhost:8080/login")
  public Pages pages;

  @Steps
  public EndUserSteps endUser;

  @Issue("#WIKI-1")
  @Test
  public void logging_in_with_username_should_display_a_welcome_message() {
    endUser.is_the_login_page();
    endUser.logs_in_with("johny");
    endUser.should_see_welcome_message("Hello, Johny!");
  }
}


На этом месте я бы уже два раза сходил за кофе и всерьёз задумался об автоматизации написания этой хрени. Ну так вот, мы ещё не закончили! Остался ещё маленький шажок:
  @Feature
  public class Backend {
    public class ProcessSales {}
    public class ProcessSubscriptions {}
  }

  @Feature
  public class Contribute {
    public class AddNewArticle {}
    public class EditExistingArticle {}
  }
}


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

Зачем так сложно?


По-моему, очевидно, что такое написание тестов серьёзно подбрасывает работы тестировщикам. Шутка ли - написать 100 строк кода там, где можно обойтись четырьмя!
Я всё пытался понять, зачем такие сложности.

Ответ оказался простой: чтобы генерировать красивые отчёты. Шутка в том, что само название фреймворка "Thucydides" происходит от имени какого-то древнегреческого перца Фукидида, прославившегося не тем, что он что-то хорошо делал, а тем, что составлял красивые отчёты.

Ну так вот, вся эта хрень, описанная выше, нужна для того, чтобы сгенерировать примерно такой "красивый" отчёт:
In order to authenticate myself
As a user
I can log in by username


Конечно, этот отчёт будет весь такой цветастый и с картинками, типа такого.

Кому это нужно?


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

Почему это плохо?


Смотрите что получается. Допустим, что в компании X работает 1000 тестировщиков, и ими управляют 10 менеджеров. Так вот эти 1000 человек мучаются, генерируют эти сотни строк ненужных излишних тестов, ездят на конференции по Selenium, борятся с Thucydides - и всё это только для того, чтобы сгенерировать красивые отчёты с картинками для этих 10 человек. Так не проще ли послать этих десятерых один раз на нормальный тренинг, чтобы они научились читать код??? Хотя бы названия тестовых методов? Да что там, хотя бы понимать обычный отчёт о тестах, генерируемый обычным Jenkins или TeamCity?

А знаете, что самое весёлое? Этим менеджерам тоже эти отчёты нафиг не нужны. Милые мои хорошие тестировщики, у меня для вас плохая новость: этим менеджерам отчёты нужны для галочки. У них в голове есть такой чекбокс: "Отчёты!" И им нужно мысленно поставить туда галочку. Мол, отчёты есть - всё, можно спать спокойно. А внутрь самих отчётов заглядывать не обязательно. Ну, иногда надо, конечно, заглянуть - для проформы. Показать подчинённым, что всевидящее око не дремлет, давайте генерируйте, не расслабляйтесь!

И что же делать?


Все, с кем мы обсуждали эту ситуацию на конференции, сходятся в одном: Украина - аутсорсинговая страна, внешние компании заказывают в Украине разработку (в т.ч. тестирование), потому что дёшево. А украинским компаниям выгодно заставлять своих работников монстрячить мегатесты с красивыми репортами, потому что это всё часы, выливающиеся в деньги. Очевидно, что такая ситуация характерна не только для Украины, но и для всего постсоветского пространства. Да и вообще для почти всего IT-сектора. Так что ничего не поделаешь, такая система.

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

Эгегей, украинские смельчаки!

Выбросьте тонны мусора из своего кода.

Пишите эффективные тесты.


Метки:
(Анонимно)
Мрак,
видно, что человек пытается что-то делать без опыта.
Как эти 4 строки которые потом превратятся в 600 тестов, ты будешь сапортить если например изменится кнопка сабмит?
будеш проходить 4*600 строк и ctrl+f замена?
ваш пример не читабелен, будет источником дублирования кода и головной боли при изменениях в проекте...
Да, это типичные страхи.
Конечно, повторяющийся код можно и нужно выносить в отдельные методы и даже классы, но суть от этого не меняется, они останутся такими же короткими.

public void loginAs(String username) {
$(By.name("userName")).setValue(username);
}

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

P.S. Кстати, в современных IDE очень легко заменить одну строку на другую в 600 файлах одним нажатием кнопки. Проходить все файлы вручную не требуется.
(Анонимно)
Зачем путать понятия? "методология"!="инструмент".
+Page Object - не обязательно использовать и к бдд он отношения не имеет.
JBehave - инструмент для написания BDD-историй, а thucydides - инструмент для отчетов.

Ваш пост больше похож на "ООП vs процедурный подход"
(Анонимно)
Интересно было почитать альтернативное мнение про BDD :)
Действительно есть команды, которым нужно "что бы было много кода и красивые отчеты с радугами и единорогами".
Но вот ситуация из жизни: пришел в продуктовую компанию, в которой никогда не было ни тестировщика, ни документации (кроме 6 небольших .pdf мануалов). После нахождения сотни багов работы стало меньше, но появилась рутина из-за регрессионных багов. Узнал про BDD и очень заинтересовался в нем: решил убить сразу двух зайцев - вот тебе и спецификация по бизнес-логике и автотесты.
100 строк кода для "тестирования" лог ина - это бред конечно, нужно только функциональные тести делать в стиле BDD.
Вы лучше покажите пример функционального теста на Selenide
Вообще-то концепция BDD в том, чтобы спецификацию писали не только девелоперы/тестеровщики, но и клиенты вместе с ними. Только на практике я ещё нигде не видел, чтобы это работало. Это утопия. Требует много усилий, а пользы не приносит.

А так да, действительно заманчиво было бы иметь и спецификацию, и автотесты в одном. Только для этого не нужно BDD, степы и всё такое. Например, обычные юнит-тесты тоже являются спецификацией. Обычный отчёт, генерируемый Jenkins - ничем не хуже спецификация.

Что такое "пример функционального теста на Selenide"? Это подходит?

https://github.com/asolntsev/hangman/blob/master/test/uitest/selenide/HangmanSpec.java
(Анонимно)
Э-э-э ...

А ПМИ тоже не нужны ??? Как сдавать проект ???

Thucydides создан для автоматизации приемо-сдаточных испытаний.
Не надо путать это с юнит-тестированием.

BDD для мануального етстирования
Конечно пост старый, но возник вопрос. Нормально ли то, что мануального тестировщика заставляют писать тесты аля BDD типа:
Re: BDD для мануального етстирования
Ну, нормально или ненормально - это в каждой фирме решается по-своему.
У нас вот считается ненормальным само по себе наличие мануального тестировщика. У нас все пишут автоматические тесты.
Если вас заставляют писать тесты - РАДУЙТЕСЬ! Это отличная возможность получить новый опыт и строчку в CV. Как говорил дедушка Ленин, автотесты, автотесты и ещё раз автотесты.
thucydides
(Анонимно)
open("/login");
$(By.name("userName")).setValue("johny");
$("#submit").click();
$(".welcome").shouldHave(text("Hello, Johny!"));

без обид, но такие тесты пишут только джуны, которых за это потом бьют по пальцам.
Реюзабельность? -Нет, не слышал
Читаемось? - Нет, не слышал
Чистота кода? - Нет, не слышал

Thucydides отличный фреймворк,и ваш Selenide и близко к нему не стоит. Так что поменьше брызг и кирпичей и больше вдумчивости и чистого реюзаемого кода
Пис.
Re: thucydides
Отличный наброс!
Неужели у вас никогда не было так, что хотелось кого-то ударить по пальцам, а потом оказалось, что чувак-то был умный и знал, что делает?

Мы не случайно пишем тесты именно так. Это не от незнания или неумения. Это осознанный выбор, за которым стоит своя философия. Вот тут я рассказывал, почему хороший тест = простой тест.

Мы заботимся о чистоте и читаемости кода. У приведённого теста читаемость и чистота на максимуме.

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

Вот тут я рассказывал, почему нельзя покрывать UI-тестами все комбинации (а значит, переиспользовать код в тестах).

P.S. Я горжусь тем, что Selenide и близко не стоит к Thucydides. Так что спасибо на добром слове.
Просто у вас другие клиенты
Российские клиенты достаточно дикие.
Вообще все клиенты по своему дикие...
Просто некоторым клиентам важен инжинерный процесс и предсказуемый результат. А кому-то просто чтобы приложение было, у них и самый дешёный фрилансер справится.
Так вот тем клиентам, которым нужен процесс - им нужны отчёты. Тем у кого большая и сложная структура - им нужны отчёты. Тем у кого долгоидущие проекты - им нужны отчёты и документация (в том числе и тестами), и реализация самих тестов тоже должны быть прозрачна и само-документирующая. Тем кто подчиняются требованиям регуляторов - им ооочень нужны отчёты.

Тем кто не понимает что такое разработка ПО и в чём разница между фрилансером и серьёзным подрядчиком - им отчёты не нужны.

Edited at 2015-06-25 10:16 (UTC)
Re: Просто у вас другие клиенты
Отличный вброс!
Не, правда, набросил отлично.

Только всё наоборот.
Прозрачность и документируемость нужны тогда, когда нет доверия между заказчиком и исполнителем. А это как раз бывает тогда, когда большие конторы снаряжают студентов делать и тестировать серьёзные проекты. И все эти тесты и BDD на самом деле СОЗДАЮТ ВИДИМОСТЬ, что процесс прозрачен и контролируем. А студенты остаются студентами.

Да, для госструктур, возможно, это и нужно. Я и не спорю. Я это и сказал: BDD решает не реальные проблемы бизнеса, а проблемы "госструктур". Ну, если вам хочется на это положить жизнь - пожалуйста, занимайтесь BDD.
Re: Просто у вас другие клиенты
BDD ещё как решает пролемы, а неумелое использование инструмента без определённой цели ведёт к травмам :)
Доверие это не про защиту от ошибок, а что-то из области застольных разговоров "ты что мне не доверяешь?". Подробней в другом топике - где начали :) http://automation-remarks.com/cucumber/
Re: Просто у вас другие клиенты
Не, при чём тут застольные разговоры.
Клиенты заказывают отчёты, потому что не доверяют.
А другие клиенты, у которых сложились доверительные отношения с исполнителем, клали на отчёты. И не тратят на это деньги.

Ну расскажите, как BDD реально на практике решает проблемы. С удовольствием послушаю.
подмена понятий
Интересная статья, а коменты еще интересней.
Посмотрел ваши демо и решил поучаствовать в дискуссии.
"Девелоперы, которые тестят свой продукт" - это уже тянет как минимум на уникальность и исключительность чем на закономерность.
Начинать ваши тренинги и демо нужно с фразы "Мы уникальны, поэтому нам подходит ВОТ ЭТО, но большенству ЭТО не подходит!", а не в ключе "все дебилы, а мы молодцы".

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

Посему выглядит это так: тема интересная, но не приоритетная.

Р.S. Фраза что приведенный выше код выглядит намного проще - это просто субъективное мнение одного программиста озвученное многим тестировщикам.
Осталось задать себе вопрос: а кому проще?
Re: подмена понятий
Привет!
Спасибо за участие.

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

Во-вторых, мы не уникальные. Extreme programming и TDD придумали уже скоро как 20 лет назад, и немало компаний по миру их практикуют. Но пока гораздо меньше, чем стоило бы.

В-третьих, я категорически не согласен с тем, что большинству это не подходит. Я уверен, что большинству как раз подходит. Тут как со спортом: да, есть люди, которым спорт не подходит. Но их 5%. А остальные 95% просто используют это как отмазку.

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

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

P.S. Конечно, это моё субъективное мнение. Вообще, всё, что кто-либо где-либо говорит - это всегда чьё-либо субъективное мнение. Так что спасибо, кэп. :) Но справедливости ради надо отметить, что приведённый код выглядит проще для всех. Я не знаю ни одного человека, который считал бы иначе.