Вопрос о том, а должны ли заказчики платить за модульные тесты и как им их продать, я слышу очень часто. Последний раз мы обсуждали его на тренинге “QA в Agile” в Днепропетровске. Вопрос очень интересный и существует немало мнений на этот счет. Я попытаюсь изложить свое в этой статье.
Начну с того, что уже некоторое время прослеживается очень положительная тенденция. Большинство разработчиков в Украине пишет модульные тесты или хотя бы хочет их писать. Я говорю об Украине, потому что в России дела обстоят на порядок хуже. Это действительно очень классная тенденция, которая говорит о заботе о качестве кода со стороны самих разработчиков. Разработчики начинают осознавать пользу от модульных тестов и использовать их в своей работе добровольно. Таким образом, тесты становятся неотъемлемой частью работы разработчика, без которой ему работается не так комфортно и не так быстро (по крайней мере в долгосрочной перспективе).
Теперь давайте разберемся кто за что должен платить. Выполнение задачи раскладывается на множество составляющих: обсуждение требований, дизайн сессия, модульные тесты (надеюсь, что с использованием TDD), реализация функциональности, рефакторинг решения, интеграция в общий код, прогон всех тестов, проверка задачи вручную, обновление документации (если она есть в каком-либо виде), закрытие задачи в task tracking системе (или на доске задач). Это далеко не полный список для некоторых команд и проектов. Заметьте как много тут активностей. И теперь давайте выкатим этот список заказчику (возможно с оценками по времени для каждого пункта), чтобы выяснить за что он должен платить. Если у него будет выбор, то он выберет один пункт – реализация функциональности. Остальное ему неважно, поэтому он и не хочет за это платить. Ведь вы сами дали ему выбор.
Нужно изменить подход. Не выкатывайте заказчику детали вашей работы (по крайней мере в контексте разговоров об оплате). Вы делаете задачи по устоявшемуся для вас процессу, который позволяет делать их быстро и качественно. И редактировать данный процесс вам нет смысла. Заказчик может его принять либо отказаться, но частичный прием может сделать только хуже, причем всем участникам. Почему? Все дело в мотивации. Я уже писал о том, что нас на самом деле мотивирует. В данном случае работа по устоявшейся и “правильной” схеме дает нам возможность делать работу на приемлемом для нас уровне качества. Это доставляет нам удовлетворение проделанной работой и радость за ее результаты. Что нас и мотивирует. Никто не любит работать с бешеной спешке, пытаться выковырять причину бага и исправить ее в коде без тестов, часами пытаться понять кусок кода без малейшей возможности его изменить (потому что неизвестно, к чему это приведет). Поэтому цикл работы над задачей определяется командой и ее членами. И он не должен приводить к демотивации.
Что же делать, если заказчик или остальная команда противостоит внедрению модульных тестов? Такие случаи тоже бывают. Для вас это отличный шанс поднять свой уровень. Ведь вам нужно преодолеть серьезную преграду. А открытый конфликт и правильная борьба (не руганью и силой) заставляют вас делать очень серьезный анализ, преподносить результаты с выгодных сторон, искать правильные аргументы, разобраться в проблематике досконально. Это здорово и дает очень хороший опыт.
Если же по истечение какого-то времени у вас не осталось сил и вы все перепробовали, то просто проверьте свой мотивационный список. Выпишите все факторы, которые мотивируют вас для дальнейшей работы в команде или компании. Добавьте туда демотивирующие факторы. Каждому из них проставьте вес. Посчитайте сумму. Если сумма получилась отрицательная, то задумайтесь о разговоре с менеджером или смене работы. Жизнь одна и не стоит тратить ее на ту работу, которая делает вас несчастным!
Конец сентября был очень загруженным и никак не успевали провести очередную встречу “Клуба анонимных разработчиков”. Поэтому следующая, шестая по счету, встреча состоится 11 октября. Темой встречи мы выбрали “NoSQL решения”. Тема навеяна недавней встречей сообщества Kiev ALT.NET, на которую мы были приглашены и с удовольствием посетили. Тема очень обширная и решений на рынке достаточно много. Поэтому мы решили углубиться и осветить эту тему с разных сторон. Мы ищем опытных разработчиков поделиться своим взглядом на данную тему, выступив с докладом на встрече. Это отличный шанс потренироваться в публичных выступлениях и глубже разобраться с темой доклада. Также будем рады видеть всех, кому интересна тематика встречи. Приходите и приводите друзей. Будет интересно! За время работы клуба его встречи посетили более 70 человек. Ниже вы найдете отчет о предыдущей встрече.
Детальная программа встречи будет опубликована в комментариях к новости. Мы будем сообщать об изменениях и планируемых выступлениях.
В очередной раз нас любезно приютит у себя Киевский офис компании DataArt. Этот офис полюбился членам клуба своей уютной обстановкой и наличием всего необходимого для продуктивного общения. Официальное начало в 19:00, завершение в 23:00. Адрес места проведения: Бехтеревский переулок, 14E. Смотрите карту перед выездом, потому что здание не так просто найти. Стоимость участия 80 гривен при оплате заранее, 120 гривен при оплате на месте. Пива, пиццы и кофе с печеньками хватит на всех. Регистрация обязательна. Все детали по оплате будут высланы вам после успешного прохождения регистрации. Количество мест ограничено 35 участниками.
Сегодня понедельник и вот пополнение арсенала полезных материалов за прошедшую неделю:
Это все на сегодня. Удачной вам рабочей недели!
Спорт объединяет людей разных профессий и возрастных групп. Мы начали активно заниматься спортивным направлением среди IT-шников. Скоро откроется отдельный портал, где можно будет узнавать о мероприятиях в этой сфере, общаться о спортивных увлечениях и находить новых знакомых, разделяющих ваши спортивные интересы. Первым мероприятием мы решили провести шахматный турнир. Ведь шахматы – это интеллектуальная игра, которая очень хорошо подходит под деятельность IT-шников.
Нам очень приятно, что среди специалистов IT есть действительно активные любители шахмат. Более 30 человек зарегистрировались на Первый шахматный турнир среди IT специалистов, который состоится в субботу 1 октября в 10-45. Участники приедут с разных городов Украины. Это люди совершенно разных профессий, которые так или иначе связаны с IT. Турнир будет проходить отдельно среди профессионалов и любителей, чтобы добиться более справедливых результатов. Регистрация уже закрыта и принимается теперь только в индивидуальном порядке. Если вы не успели зарегистрироваться, пишите нам по адресу anna.alimenkova@xpinjection.com.
Место проведения нам любезно предоставила компания Ciklum. В ее офисе по адресу ул. Амосова, 12 (карта проезда) на 20-ом этаже и состоится мероприятие.
Победителям мы заготовили настоящие кубки и грамоты. Также спонсором турнира стал магазин аксессуаров “AccessOpaйz”, который приготовил специальные призы для победителей. Мы приглашаем всех любителей шахмат и их болельщиков придти поддержать шахматистов! До встречи на турнире!
Я решил написать коротенькую статью на непривычную для этого блога тему. Тема касается интерфейсов, ролей и правил их именования. Дело в том, что современные подходы к написанию кода все больше склоняют нас к настоящему объектно-ориентированному подходу. Это делает и популярный шаблон дизайна Dependency Injection, и TDD, да и вообще модульное тестирование с использованием Mock Objects. Благодаря им дизайн приложения должен напоминать сеть объектов с определенными ролями, которые взаимодействуют между собой по определенным протоколам. Такие приложения относительно легко поддерживать благодаря модульности кода и заложенной тестируемости.
И вот тут появляется очень интересная “проблемка”. Вы создаете интерфейс A и делаете к нему реализацию B. Вам нужно выбрать имена для A и B. Долгое время под воздействием примеров кода для библиотеки Spring многие не задумывались и просто лепили к A суффикс Impl, получая AImpl. Данная практика очень вредна по нескольким причинам. Во-первых код становится “замусоренным” лишней информацией, которая абсолютно ничего в себе не несет. Во-вторых, данный подход позволяет не тратить время на выдумывание правильных доменных имен для классов, что затрудняет понимание дизайна приложения на высоком уровне. В-третьих, нарушается понимание модели “интерфейс -> роль -> реализации”. Ведь если будет еще одна реализация, то как ее выделить по названию? И как по названию понять чем она будет отличаться от AImpl? А что если объект будет играть сразу две роли в приложении (реализовывать два интерфейса)?
В действительности интерфейсов должно быть ровно столько, сколько ролей вы придумали в доменной модели. Причем сама роль не должна включать в себя ничего от возможных реализаций. Этот принцип очень легко проверить. Сделайте интерфейс и подумайте как будет называться реализация, которая видится вам на данный момент. Если вы не можете выдумать ей название и вас тянет приписать суффикс Impl, то это явный признак того, что вам не удалось придумать новую удачную роль. Вернитесь еще раз к интерфейсу и подумайте над ним. Или задумайтесь чем ваша реализация будет выделяться среди возможных других реализаций. Если возможна единственная реализация роли, то роль попросту надумана и вводится только с целью удобства тестирования. А это свидетельствует о плохом дизайне.
В завершение, приведу пример правильной роли. Возьмем InputStream. Представьте себе класс InputStreamImpl. Как он работает? Что от него ожидать? Вам придется каждый раз заглядывать в документацию (если вам повезло и она есть) или лезть в код класса, чтобы понять как он работает. Вместо этого существует множество реализаций с понятными вменяемыми именами: ByteArrayInputStream, ZipInputStream, TelnetInputStream, FixedLengthInputStream и т.д. Да и если посмотреть в код самой библиотеки Spring, то они очень редко пользуется “классическим” именованием с суффиксом Impl. Единственное место, где это использование хоть немного уместно – слой высокоуровневых API сервисов к вашей системе. Просто там по умолчанию c вероятностью 99% будет единственная реализация. Да и то не факт.
Думайте хорошенько при написании кода и ваши усилия многократно окупятся в будущем!
Я хочу рассказать о важности и необходимости обратной связи. Эта тема касается не только проектов и разработки в целом, она затрагивает любую коммуникацию с внешним миром. Обратная связь очень важна для успешности ваших действий. Успешности со стороны тех, для кого эти действия делаются, а не лично для вас. Без нее вы живете в замкнутом мире и не развиваетесь.
Давайте начнем с образования. Нам с детства ставят оценки. В школе, лицее, университете, на курсах, на экзаменах. Оценки играют роль обратной связи, которая толкает нас на дальнейшее совершенствование. Получил тройку – нужно еще работать над собой. Получил четверку – уже лучше, но немного не дотянул. Без оценок нам было бы тяжело понять делаем ли мы очередной правильный шаг на пути развития. Иногда подобная обратная связь может портиться. Например отличнику начинают ставить оценки не за знания, а за “выслугу”. Как это скажется на его стараниях и прилагаемых к учебе усилиях? Отрицательно. Вспомним обратный пример. Как обратная связь работает для двоечника? Да никак, он давно забил. Поэтому обратная связь должна быть адекватной и в меру критикующей.
В Agile подходах обратной связи уделяется очень большое значение. На митингах по планированию заказчик или Product Owner узнает, насколько хорошо он поработал над требованиями к проекту, какие моменты он не учел, где совершил ошибку. Это дает ему возможность на протяжении итерации уделить больше внимания требованиям и следующий раз подготовиться лучше. На ежедневном митинге команда делится наблюдениями по поводу прогресса в итерации, а также статусом собственной работы. Это дает возможность на раннем этапе выявить проблемы и исправить их до конца итерации. В конце итерации, на демонстрации, заказчик дает обратную связь по успешности итерации. Это дает команде возможность улучшить процесс разработки, планирования и постараться избежать проблем в будущем. И список примеров можно продолжать долго. В Agile очень ценят обратную связь и многие практики построены именно на ней.
Теперь давайте поговорим о видах обратной связи. Я разделяю ее на 3 вида: позитивная, негативная и троллинг. Позитивная обратная связь несет немного полезного. Она дает понять, что вроде как мы делаем все правильно. Но она не дает пищи для размышлений и улучшений. Когда после конференции или другого мероприятия мы разбираем формы обратной связи, то позитивным отзывам радуемся, но откладываем их в сторону. Приятно, но не очень полезно. Только позитивная обратная связь очень подозрительна. Никогда не бывает все идеально. Я знаю проекты, где заказчик после каждой итерации давал мега-позитивную обратную связь. Через несколько месяцев перед релизом продукта оказалось, что он делает совершенно не то. Просто заказчик относился к демонстрациям несерьезно и не пытался вникнуть с целью критики. Ведь для здравой критики нужно хорошо разобраться в происходящем, а значит потратить время.
Второй вид обратной связи – негативная. Вот она как раз и является самым главным источником знаний. Ведь тот, кто дал негативную обратную связь, потратил на это время. Легче всего сказать “Все было круто!” или “Класс!”. Описать негативную оценку гораздо сложнее, хотя бы по количеству написанного текста. А дать аргументированную негативную обратную связь еще сложнее. Это требует анализа и собственного опыта. Поэтому вы должны цепляться за каждую негативную обратную связь и высасывать из нее максимум. Разберите ее на кусочки, задайтесь вопросом насколько правомерно вас критикуют. Не торопитесь отнести негатив в категорию троллинга. Если есть такая возможность, поговорите с автором обратной связи и попытайтесь разузнать у него детали. При этом не спорьте, не оправдывайтесь и не ругайтесь. Впитывайте полезную информацию. Если не доверяете приведенным аргументам, то задайте вопрос кому-то другому (одному, нескольким, проведите опрос). Никогда не отвергайте негативный факт, попробуйте разобраться почему он произошел или почему он был так воспринят автором. Это даст вам возможность учиться на своих ошибках и не повторять их в будущем.
И, наконец, последний вид обратной связи. Это троллинг. Многие относят к этому виду любую негативную обратную связь. Но это не так. Троллинг своей целью зачастую преследует бесполезное, но долгое обсуждение. При этом тема либо сразу либо со временем перетекает в очередной “holy war”. Участвовать в троллинге бессмысленно, разве что для убивания времени. Распознать троллинг не всегда легко. Для меня есть ряд критериев, которыми я пользуюсь. Во-первых, спор не заканчивается. Тролль всегда старается быть автором последнего слова. Во-вторых, тролль склонен игнорировать ваши аргументы, даже если они подтверждены документально. В-третьих, тролли часто переводят тему в совершенно другое русло, часто сводя к общеизвестным “holy war”. Если вы поняли, что негативная обратная связь попахивает троллингом, то просто возьмите из нее максимум полезного и забейте. Заставьте себя, преодолейте желание спорить до бесконечности и забейте. Это сложно, я тоже не всегда могу с собой справиться.
В заключении хочу рассказать про еще одну точку зрения. На днях мне пришло очередной послание в одной из популярных рассылок. Там шла речь о “балаболах” и том, что нет смысла тратить на них время. В качестве критерия “балабола” приводился такой: “…у него нет по отношению к тебе благого намерения или он дурак, у которого много времени…”. Но, к сожалению, мир не крутится только вокруг вас. Не стоит верить в обратное. И не все люди стремятся сделать вам благо. Зато недовольных качеством вашей работы или сервиса может быть много. И они просто выражают свое недовольство. Не для того, чтобы вам помочь, а для того, чтобы носом вас ткнуть. А вы можете в этот момент витать в облаках восторга, думать какой вы классный и сколько вокруг вас “балаболов”.
Вспомните себя в момент крайнего недовольства сервисом ресторана. Вы пишете негативный отзыв (или обсуждаете с друзьями), где рассказываете, что вам не понравилось. Вы не идете домой, не анализируете работу ресторана и не выкатываете им предложение на 50 страниц по улучшению их деятельности. Вы не стремитесь сделать им благо. И это правильно! Это их работа, а не ваша!
Радуйтесь позитивным обратным связям, старайтесь избегать троллинга, прислушивайтесь ко всем негативным отзывам, анализируйте их и старайтесь делать свое дело лучше.
Сегодня понедельник, а это значит, что вас ждет новый список материалов для самостоятельного изучения. В этот раз статьи будут немного разбавлены видеороликами. Итак, вот что я могу вам предложить на эту неделю:
Отдельным списком выделю видео с пятой встречи “Клуба анонимных разработчиков”. Смотрите и присоединяйтесь к членам клуба:
Читайте и смотрите с удовольствием!
Начнем с неприятных новостей. По техническим причинам нам пришлось перенести тренинг “QA в Agile” на неделю вперед. Он состоится 24 сентября в Днепропетровске. Приносим извинения всем, кому доставили неудобства данным переносом. Желающие принять участие в тренинге могут регистрироваться. Регистрация продлится до четверга 22 сентября.
Наш “Клуб анонимных разработчиков” начинает сотрудничать с другими сообществами разработчиков. Коллеги из Kiev ALT.NET приглашают всех членов клуба принять участие в очередной встрече 23 сентября в Киеве. Эта встреча будет посвящена NoSql решениям. В программе анонсировано 3 доклада и афтепати, где все смогут в непринужденной атмосфере пообщаться на разные интересные темы. Приходите, будет классно!
Мы выбираем тему для следующей встречи клуба и ищем желающих подготовить выступление. Не стесняйтесь обращаться со своими предложениями. Это отличная возможность попробовать себя в качестве докладчика и лучше разобраться в какой-то теме. Как говорится, лучше всего можно понять что-то, если учишь этому других.
29 октября в Днепропетровске состоится конференция QADnepr Mini Conference. Я подал заявку на выступление с темой “Жизнь без тестировщиков: миф или реальность?”. Бытует противоречивое мнение, что на проекте обязательно должен быть тестировщик. Но тестировщик – это скорее роль, чем конкретный человек. И эта роль может быть распределена между всеми членами команды. Также необходима полная автоматизация тестирования на всех уровнях, что и позволяет заменить работу тестировщиков, а именно их работу по “проверке” работы приложения. Это дает возможность работать без тестировщиков или высвобождает время тестировщика для действительно важных дел (тестирование методом свободного поиска, помощь в критическом анализе требований, помощь в составлении приемочных тестов и т.д.). При этом качество продукта остается на высоком уровне. Для построения такого процесса качество должно стать целью всей команды: разработчиков, заказчиков, аналитиков и прочих. Вот тогда и начинается магия…
Модульные тесты имеют много полезных свойств: они позволяют запустить маленькую часть кода и убедиться в его работоспособности, они помогают осуществлять рефакторинг, служат “страховочной” сетью для любых изменений в коде и т.д. Существует противоречивое мнение, что модульные тесты могут являться документацией к модулю, классу, методу или просто части кода. Одни с ним соглашаются, другие твердят, что тесты невозможно читать и тяжело понять какая функциональность скрыта в самом коде. Я разделяю мнение обеих сторон. Если не уделять внимания тестам и писать их по принципу “для галочки”, то использовать их в качестве документации крайне сложно. Если же заранее вкладывать документирование кода в задачу модульных тестов, то это вполне реальная цель.
Эта статья будет не о том, как нужно писать тесты. Речь пойдет о именовании тестов. Примеры я буду приводить на Java, так как это мой “родной” язык (после русского и белорусского). Большая часть модульных тестов пишется с использованием JUnit или TestNG. Эти инструменты уже не накладывают на разработчика правил именования тестовых методов (в прошлом JUnit требовал, чтобы тесты начинались с префикса ‘test’). Достаточно лишь пометить метод тестового класса соответствующей аннотацией @Test. И это здорово, потому что вы можете выбирать любое имя, которое вам удобно.
Этой возможностью можно и нужно пользоваться. Название тестового метода должно отражать суть тестируемой функциональности. Например “if no signal groups with required type return empty set” может быть записано как “ifNoSignalGroupsWithRequiredTypeReturnEmptySet”. Вроде бы все логично, но воспринимать такое имя не так просто как кажется. Все дело в разделителях, к которым мы привыкли при чтении текста. К сожалению нельзя использовать пробелы в имени метода. Можно использовать другие разделители, например ‘_’. Приведенный выше пример превращается в “if_No_Signal_Groups_With_Required_Type_Return_Empty_Set”. Это уже лучше. Но есть еще одна проблема. Документацию хотелось бы видеть в более удобном формате, к примеру в виде списка возможностей.
И тут вам на помощь приходит IDE. Я обнаружил замечательный инструмент под названием TestDox (стыд мне и позор, что я обнаружил его только сейчас). Он решает все описанные выше проблемы и позволяет создавать, изменять и просматривать все тесты в виде обычного текста. Данный инструмент работает в виде плагина к IDE и может быть использован с разными языками программирования. Ниже приводится пару скриншотов его работы с комментариями:
Вы можете видеть все сценарии на обычном английском языке и переходить от описания к тесту или к описанию из теста. С этой же панели есть возможность создать новый тест. Панель сделана плавающей для того, чтобы скриншот был более крупным.
Вы можете редактировать любой тест и описание автоматически преобразуется в имя тестового метода. При таком подходе вы можете не задумываться над удобочитаемостью названия метода и писать реальное описание функциональности.
У данного инструмента есть еще настройки, но их изучение оставлю вам в качестве домашнего задания. Пишите свои тесты так, чтобы они приносили максимум прибыли в будущем. С помощью описанного инструмента ваши модульные тесты могут быть настоящей документацией, не хуже комментариев.
Вчера состоялась очередная, пятая по счету, встреча нашего “Клуба анонимных разработчиков”. Мы потихоньку растем и теперь на встречи приходит больше 30 человек. Данный факт не может не радовать. Тема встречи была «ORM. Добро или зло?».
Первым с докладом выступил Витя Полищук. Он рассказал о четырех проектах из личного опыта, которым помогло или навредило применение ORM. Проекты были разной направленности и Витя указывал на ошибки, допущенные в разработке и как бы он их исправил, имея второй шанс. Доклад получился достаточно живым и интересным. Вот презентация с доклада:
После Вити выступал я с докладом “За что я ненавижу Hibernate?”. Я использую Hibernate очень давно, начиная еще с первых версий. За это время я успел попробовать его в проектах совершенно разной направленности и с различными требованиями к управлению данными. Где-то Hibernate подходил лучше, где-то хуже. За время использования я изучил данный framework достаточно глубоко и нашел немало недостатков, багов и недоработок, которыми и поделился с участниками. Моя презентация уже доступна:
Закрывал встречу Виталий Тимчишин с теоретическим обзором имеющихся ORM решений и анализом их применимости в различных ситуациях. Участники смогли оценить ситуацию на рынке инструментов и возможно увидели новые вещи для изучения. Презентация этого выступления:
Мы снимали видео всех выступлений и постараемся в ближайшее время выложить их в открытый доступ. Пока же небольшой фотоотчет с места событий:
Следующая встреча пройдет в конце сентября – начале октября. Точная дата и тема встречи будет оглашена в ближайшее время. Следите за анонсами на нашем сайте!