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

Про "моргающие" тесты

Goblin Game: Перезапуск тестов - хорошо про опасность моргающих тестов.
Одна из причин того, что на "красные" письма никто внимание не обращает.

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

А ведь в каком то докладе на SQA Days'12 даже бредовую формулу с экономией времени давали.

"Либо ты хочешь сохранить рассудок, либо остаешься менеджером" О.Павлова

В название поста я вынес цитату, которая на мой взгляд лучше всего описывает тему второй конференции "План Б" в питерском офисе Яндекса: "История факапов".

Несмотря на субботний день, да еще и 23 февраля, желающих послушать истории чужих факапов и рассказать про свои, собралось очень много, всем даже мест не хватило:



Сразу оговорюсь, что Миша Карпов обещал видео всех докладов в течении 2-х недель. Воспользовавшись формулой Леши Авдея можно предположить, что в течении месяца точно будут :) Update: уложились в 2 недели :) Видео уже есть.
Рекомендую посмотреть: доклады все были интересные и динамичные (те что до обеда - точно). Следите за анонсами, например в twitter'e Яндекс.Events.

Ниже будут мои впечатления и мысли, которые я для себя отметил.

Первым выступал Леша Авдей из "Яндекс-Маркета" с интересным рассказом-инсайд "Как мы делали Яндекс-Одежда"  (название мое). Немного оффтопа: надо сказать, что до этого доклада я не знал об этом сервисе, уже польза :)
Из отмеченного:
  • Прочитать книжку "Общаться с ребенком. Как?" Оказывается в работе менеджера тоже помогает.
  • При делегировании важно убедиться, что вторая сторона приняла задачу
  • Контроль за сроками: "сколько было запланировано" vs "сколько потратили на самом деле". Используем в дальнейшем для оценки сроков - Леша это не сказал, но я бы так использовал.
  • "В чем обманывают - в том и ошибаются". Интересная формула: говорят срок в неделях -  ошибаются в неделях, говорят в месяцах - ошибаются в месяцах.
  • Вас не должно покидать ощущение безупречности - ибо все равно облажаемся, не надо сильно заморачиваться... Мда... может быть, может быть.
  • Прозрачность отношений - не надо додумывать за остальных. Спрашивайте.
  • Не забывать про стоимость интеграции. Должен быть ответственный за стыки.
  • Мотивируем разработчиков ближайшим сроком: конечную дату им не называют. Вопрос из зала "Сколько раз удавалось так провести разработчиков?". Ответ: 3 раза. Видимо потом уже не велись :)
Доклад Михаила Болдова про проблемы в стартапах. В двух фразах: "делай меньше, думай о пользователях". Нового для меня ничего.

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

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

Ребята из "Яндекс-Деньги" рассказывали о своем опыте внедрения Scrum. Позабавило... :)
Цитаты из доклада ярко отражают суть:

  • "мы шли по граблям и земли под граблями не было видно..."
  • Scrum таблетка возможно и волшебная, но инструкцию никто не читал
  • Взялись за работу еще до того, как поняли, что хотим получить
  • Scrum для 1 разработчика и 3х менеджеров - дорого (по этому поводу докладчиков знатно трольнули из зала)

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

Фото с конференции

Интересные диалоги звучали иногда за спиной:

"Зачем Яндексу организовывать такие конференции? - Да они просто народ к себе заманивают, офис показать :)"
Надо отметить, что по тегу #pbconf действительно проскакивала реклама менеджерских вакансий в Яндексе. Кому интересно - вам сюда. Там много информационного шума, но вакансии тоже есть :)

От этого вопроса за спиной я оторопел "А ты знаешь, что такое Scrum?" Ответ правда порадовал: "Да, мы уже его используем".
А вообще соглашусь с одним из твитов, что последнее время слово "scrum" стало синонимом "не waterfall". И это грустно.

Яндексу спасибо. Конференция удалась, в коридорах правда было тесновато :).
Кстати, следующая будет уже в декабре. Следите за анонсами.

среда, 20 февраля 2013 г.

Тестируем с помощью Fitnesse+PowerSlim. Часть 2. База.

Часть 1. Введение 
Часть 2. База (эта статья)
Часть 3. Интересные возможности
Часть 4. Демо FitNesse + Jenkins
Часть 5. Пример трансформации PowerShell скрипта в тест
Плагин для sublime, который подсвечивает синтаксис теста на Fitnesse+PowerSlim

Надеюсь, что вы нашли время (или желание?) посмотреть примеры, которые можно найти в пакете PowerSlim. Если вы их не видели, ничего страшного: все равно с нуля там ничего не понятно. Ну или почти ничего (да, Костя?) :)

Давайте попробуем разобраться, как использовать PowerSlim с пользой. Но тут нам придется углубиться чуток в теорию и разбираться на примерах.

Начнем, пожалуй, с организации тестов.

В Fitnesse есть три типа страниц: статические, сюиты и тестовые. Статические служат просто для размещения нужной информации и, например, страницы с набором ссылок с описанием фичей запланированных на релиз или примеров использования API библиотеки:


Страницы-сюиты.
Позволяют запустить тесты со всех тестовые страницы, расположенные под сюитой. Тесты при этом выполняются последовательно. Тесты с ошибками не останавливают выполнение сюиты. Отчет по результатам выполнения позволяет "ходить" по странице и смотреть подробности. Это вы могли видеть при первом запуске тестовой сюиты PowerSlim (см. первый пост). Кроме этого, есть возможность посмотреть историю выполнения тестов (Tools -> Test History):



Тестовые страницы вы уже видели и даже редактировали (если читали предыдущий пост).

Имена страниц должны содержать как минимум 2 заглавные буквы расположенные не рядом (не знаю как это описать понятней :) ). В любом случае Fitnesse (кстати правильнее FitNesse) не разрешит вам создать страницу с неправильным названием.

Как вы уже могли заметить, дерево веб-страниц на Fitnesse портале дублирует собой структуру папок под FitNesseRoot на файловой системе: папка - это имя страницы, внутри хранится ее контент (content.txt), история изменений (в *.zip файлах) и файл properties.xml со свойствами страницы, определяющими, например, ее тип. Поэтому при перемещении папок структура в web-view также меняется (по нажатию F5).



Редактировать страницы (content.txt) можно (и чаще даже проще) в удобном вам текстовом редакторе.
Страницы можно включать в другие страницы, подробнее об этом в следующем посте.

В Fitnesse есть переменные. Значение переменной наследуется всем страницами расположенным в иерархии под той, в которой она объявлена. На каждой странице переменная может быть переопределена и тогда уже новое значение будет наследоваться ниже по структуре.

Для чего они нужны? Самое простое применение, это задание имен стендов, где нужно запускать тесты, пути на файловой системе, URL и тп. Все то, что может быть определено и изменено в одном месте, а использоваться во многих.

Как же писать тесты? Для следованию правилу "трех А" (Arrange-Act-Assert) нам могут понадобиться такие операции:
  • настроить тест
  • выполнить действие, например создать, запустить, удалить что-нибудь и тп
  • проверить результат
Arrange
Откройте страницу (http://localhost:8080/PowerSlim.OriginalMode.SuiteRemoting.TestQuery) из сюиты PowerSlim


Обратите внимание на влинкованные SuiteSetUp, SetUp вверху страницы  и TearDown, SuiteTearDown внизу.
Если посмотреть исходники тестовой страницы (через "Edit"), то вы не увидите никаких намеков на включение дополнительных страниц. Их код автоматически подставляется движком Fitnesse в каждую тестовую страницу при ее выполнении. При этом запуск сюиты вызовет SuiteSetUp и SuiteTearDown только один раз на всю сюиту.
Эти специальные страницы предназначены для включения кода выполняющего общую настройку тестового окружения и зачистку после выполнения. Такая возможность помогает реализовывать изолированные и независимые друг от друга тесты.
Естественно, индивидуальную настройку среды выполнения теста все равно придется делать, но не следует забывать о выносе похожего кода в одно место (удаление дупликации).

Act
Код выполняемый для настройки (Arrange) и запуска (Act) использует одни и те же функции PowerSlim. Чаще всего используется eval. Много примеров в тестовой сюите PowerSlim.

Assert
Для проверки результатов используются вариации Query. Одиночный вызов Query ожидает, что результат будет содержать тот и только тот массив данных, который описан в тесте строчками под командой. Порядок возвращения по строчкам не важен. При использовании перед Query служебного слова subset проверяется наличие вхождения заданного тестом в итоговом массиве данных.
Интересный момент связан с тем, как определить, какие свойства-колонки мы должны задать тестом. Проще всего, для этого запустить тот PowerShell скрипт, который вы хотите использовать в PowerShell консоли (или ISE) с командой get-member (gm) через pipe '|'


Результатом будет являться набор свойств и методов, которыми обладает тип данных объектов, которые будут возвращены скриптом (жесть - но сейчас будет понятней)
PowerSlim возвращает только Property иNoteProperty объектов сложных типов.

Соответственно в тесте, мы будем использовать одно из этих свойств.


Если результат скрипта это массив строчек, то PowerSlim на его базе сгенерирует и вернет массив PSObject со свойствами Value и COMPUTERNAME. В Value будет положено значение строчки, а в COMPUTERNAME имя стенд-машины, на которой выполнялся запрос.
Смотри пример в PowerSlim.OriginalMode.SuiteRemoting.TestRemoting.

Похожим образом конвертируются массивы hashtable и dictionary. Подробнее можно посмотреть  в тестах PowerSlim:TestArrayInQueryTable, TestArrayOfNumbers, TestGenericDictionary, TestPowerShellHashTableNotation.

Кроме проверки Query, для assert'ов может использоваться команда check, которая сравнивает значение полученное во время запуска теста с ожидаемым. При этом в качестве параметров может выступать выражение. Смотри пример в PowerSlim.OriginalMode.SuiteCommon.TestScript.

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

Да, важно. Для того чтобы Fitnesse не воспринимал PowerShell pipe символ '|' как разделитель таблицы, весь запрос надо заключать между символов !- ... -! Если при этом внутри запроса используется переменная, то ее надо вынести из этого "забора":


Я добавил немного примеров из жизни в ExampleS. Теперь, если взять свежий PowerSlim, то там это уже будет.
Также можно обратить внимание на обсуждения (1 и 2) из первого поста, там уже advanced technics обсуждаются :) Подробней о них в следующем посте.

Удачи в изучении. Главное не пугаться :)

Продолжение

четверг, 14 февраля 2013 г.

Тестируем с помощью Fitnesse+PowerSlim. Часть 1. Введение.

Часть 1. Введение (эта статья)
Часть 2. База
Часть 3. Интересные возможности
Часть 4. Демо FitNesse + Jenkins
Часть 5. Пример трансформации PowerShell скрипта в тест
Плагин для sublime, который подсвечивает синтаксис теста на Fitnesse+PowerSlim

С Fitnesse я познакомился в 2007 году. Начинали мы его использовать совместно с .Net. Потом был Python. После некоторого перерыва, решил посмотреть, как он поживает сейчас.
Товарищи с прошлой работы познакомили с расширением, которое позволяет использовать всю мощь Fitnesse в полной мере. Время на развертывание минимально. Если вы еще и знакомы с PowerShell, то проблем и того меньше.

Итак, разговор пойдет о Fitnesse и расширении к нему PowerSlim.  Название расширения намекает на использование PowerShell и технологии Slim, которая появилась в Fitnesse сравнительно недавно.

Я не буду углубляться в теоретические дебри Fitnesse'a. И не буду пытаться вас уговорить его использовать. Вместо этого, мы постараемся на простых примерах понять, как его можно использовать для проверки функционала ваших продуктов. Вдруг вам подойдет?

Jump-start :)

Для запуска Fitnesse + PowerSlim вам потребуется:
Первый запуск "java -jar fitnesse-standalone.jar" распакует содержимое архива в текущую директорию, повторный запускает сервис. Для второго запуска лучше использовать "java -jar fitnesse-standalone.jar -p 8080", где 8080 - порт, по которому сервис будет доступен. Обратите внимание: текущей директорией должна быть папка, где живет запускаемый вам fitnesse-standalone.jar.

Заходим по URL http://localhost:8080 (естественно можно открыть и удаленно, если настройки firewall'а позволяют) и видим такой FrontPage
Теперь cкачиваем PowerSlim. Внутри архива вы найдете набор PowerShell скриптов и тесты-примеры использования PowerSlim. Лучше сразу разблокировать все файлы *.ps1 (они, как запускаемые, могут быть заблокированы из-за политики безопасности Windows), иначе тесты не будут запускаться.



Скрипты PowerSlim после распаковки должны лежать на одном уровне с папкой FitNesseRoot, которая создается после распаковки Fitnesse'a. Содержимое "PowerSlim-master\FitnesseRoot"  (папки ExampleS и PowerSlim) переносим в основной FitNesseRoot.
Должно получиться как то так:


Заходим по URL http://localhost:8080/PowerSlim.OriginalMode.
Если все сделано правильно, то видим такую картинку


Жмем "Suite". Поздравляю, вы только что запустили тесты на Fitnesse :) и настроили машину-сервер.

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

На стенд-машине ставим (или активируем) PowerShell. Лучше 3.0, но можно и 2.0, если вам нужно тестировать на OS, которая не поддерживает 3-ю версию. Копируем на стенд slim.ps1 (из пакета PowerSlim) и создаем рядом с ним startRemote.cmd файл с таким содержимым:

PowerShell -ExecutionPolicy unrestricted -file .\slim.ps1 35 server

Запускаем startRemote.cmd. Это запустит tcp-сервер, который будет слушать и обрабатывать запросы с машины, на которой установлен Fitnesse.
Если на стенд-машине стоит firewall, то нужно разрешить TCP подключения с машины-сервера (или any) по 35 порту (35 из строчки в cmd это порт, по которому будет работать сервис). Порт можно поменять, но пока лучше оставить так. Для чего можно использовать возможность менять порты я расскажу в следующих постах.

Открываем страницу http://localhost:8080/ExampleS.GetService. В оригинале этот тест проверяет статус всех сервисов, у которых DisplayName есть слово "Time". Делается это локально на машине-сервере. Давайте переделаем его для проверки статусов сервисов на стенд-машине.

Жмем "Edit", видим внутреннее устройство страницы со специфичной разметкой. Меняем редактор на "plain text" (с красивым RTF-редактором у меня были проблемы с итоговым форматированием страницы).


Заменяем Query:Local на Query:Remote. Добавляем адрес или имя стенд-машины (обратите внимание на разделители '|' на картинке). Теперь "Save" и "Test".
Bingo - мы видим результат нашего первого теста на стенд-машине :)


У меня тест "красный" потому, что, кроме ожидаемого мной "Windows Time", обнаружился еще и "Hyper-V Time Synchronization Service" из-за активированной роли Hyper-V. Поправляем тест (через "Edit") и делаем его зеленым. Как? Ну или меняем запрос в получении сервисов, или добавляем новый сервис в список ожидаемых, новой строчкой. Зависит от того, что правильнее с точки зрения сценария.Чем не TDD? :)

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

Для начала, я думаю хватит. Что нам может дать этот инструмент? PowerShell можно использовать для получения состояния вашего продукта, состояния среды в которой он работает, и с которой взаимодействует.
Начинаем с проверки того, что сетап установил нужные файлы, создал ключи реестра, зарегистрировал сервисы. Все это доступно через PowerShell. Дальше, например, можно запускать и настраивать ваш продукт, проверять результаты его работы.
Мы у себя, к примеру, проверяем воздействие (полезное воздействие :)  на виртуальную инфраструктуру, которое оказывает наш продукт. PowerShell cmdlet позволяют работать с Microsoft Hyper-V, VMware vSphere серверами и виртуальными машинами. Кроме этого, вы можете работать с Sharepoint, Exchange и AD инфраструктурами.
Все (ну или почти все) что доступно в PowerShell - доступно в Fitnesse+PowerSlim.

При этом вы получаете историю запуска тестов, возможность писать user stories/features привязанные к тестам. Тесты можно запускать руками, но это неправильно. Можно запускать автоматически и использовать cmdline - уже лучше. А можно использовать Fitnesse плагин к TeamCity и увязать ваши тесты с хорошей CI системой.

В следующих постах я расскажу про то, как писать первые тесты. Приведу примеры то, как можно проверить распространенные сценарии.

А пока вы можете посмотреть на реализацию тестов PowerSlim (http://localhost:8080/PowerSlim). Да, на сам фреймворк есть тесты! И их можно использовать как примеры. Кроме этого, есть еще тесты по URL http://localhost:8080/ExampleS (они, кстати не будут "зелеными" на вашем сервере, потому что это примеры использования).

PowerSlim - это развиваемый в настоящее время opensource проект и я думаю, что Константин будет рад ответить на ваши вопросы. Задавайте свои вопросы и здесь. Это поможет определиться с тематикой следующих постов.

Ссылки:
Fitnesse
PowerSlim
Для желающих подключить Python или C++:
плагины к фитнесу

Продолжение

суббота, 9 февраля 2013 г.

Группировка С++ юнит-тестов в Visual Studio 2012 Test Explorer

Я уже писал про использование нового фреймворка для C++ unit-тестов в Visual Studio 2012.
Продолжаем изучать новшества.

На работе обсуждали, зачем ввели атрибуты (модуля, класса, метода). Точного ответа пока не нашел, но обнаружил, что группировка тестов Traits отлично с ними работает. Update: тут есть немного подробностей про использование Traits.

И зачем нам теперь группировка по классам в Update 2? ;)


Правда и здесь не обошлось без косяков. Куда же без них? :)

Документация в MSDN утверждает что макросы объявления группы атрибутов модуля и класса имеют параметр. На самом деле они без параметров. И если с атрибутами классов из-за этого проблем не возникает (макрос объявляется внутри класса), то с модулем дела обстоят хуже. Макрос создания атрибутов модуля объявляет (и определяет) глобальную функцию __GetModuleMetadata, что при его использовании в нескольких файлах вызывает проблемы с линковкой.
Проблему можно решить использованием namespace'ов, своего на каждый модуль. Я также проверил и сделал другой макрос, с параметром - тоже работает и уже без namespace.

Итого: использовать можно. Группировка может быть полезной, если вы сейчас работаете с группой тестов и хотите запускать только их.

Осталось только неясным, где же ошибка: в MSDN или в CppUnitTest.h .

На самом деле, если честно, то группировка по классам из Update2 все равно нужна. Она отлично работает с Google C++ Test Framework тестами. Метод описанный выше тут не поможет.

Lean по Дорофееву

Интересный слайдкаст от Макса Дорофеева "Intro2Lean"



"Баги - это потери. Их не надо записывать - их надо исправлять...Но багов же много, как их сразу чинить? Их потому и много, потому что их не чинят, а записывают."

Классно - я тоже не люблю багтрекер.

IKIWISI - "I'll known it When I see it"
В переводе на понятный: "Никто сразу не скажет того, чего именно ему хочется. А если заставить это сделать - то возникает сильный соблазн запихать туда ВСЕ"

Как обычно: "Все ТЗ сразу, а потом частями реализуем", поэтому мы постоянно меняем ТЗ. А это снова потери.
Как правильно: ТЗ1+его реализация ТЗ2+его реализация и тд

"Субоптимизация" - плохо, оптимизировать надо "целое"

"45% процентов функционала никогда не используется" - сделали самое важное, выпустили, посмотрели реакцию и только потом продолжаем дальше.

Интересное обоснование полезности обычной доски в сравнении с электронной версией: информационный холодильник vs радиатор. Чтобы оценить состояние, электронную версию надо сначала открыть (как холодильник), а доску видно сразу и постоянно - работает как радиатор.

пятница, 1 февраля 2013 г.

Станислав Протасов "90 минут о карьере менеджера"


Очень интересная запись презентации Станислава Протасова (старший вице-президент Parallels) от клуба "Стратоплан"

Интересные мысли
Откуда берутся менеджеры? - из хороших и амбициозных инженеров.
Почему? Потому что задача менеджеров - решать проблемы инженеров, в том числе технические.

Но нужны не только технические знания. Станислав рекомендует развивать то, что сейчас называется "soft skills"

3 качества хороших менеджеров

  • Толковость
  • Ответственность (нацеленность на результат)
  • Коммуникабельность

При этом желание работать способно компенсировать недостаток остальных качеств. Станислав считает, что толковость - неразвиваемое качество. Я не согласен, по этим критериям остальные качества тоже неразвиваемые.

Хороший менеджер должен

  • "проигрывать" со своими людьми 60-80% споров
  • давать "выигрывать" разным людям
  • играть роль судьи на поле
Рекомендую посмотреть, Станислав рассуждает о карьере менеджера, анализируя свои ошибки на этом нелегком пути длиною почти в 20 лет.

ЗЫ Немного монотонно. Лучше скачать видео и смотреть через VLC. Клавиша "]" вам в помощь: 1.5 часовой монолог превращается в бодрый доклад на 1 час.