пятница, 3 марта 2017 г.

Как начать планирование релиза?

Попался на глаза этот старый драфт поста, уже несколько лет ждет публикации и все еще выглядит актуальным.
Вот, наконец, дождался....

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

Имхо, вполне нормальная ситуация: всегда есть недоделки. Количество недоделок на конкретную дату зависит от "качества" работы в предыдущие полгода. Наделали много долгов - будет много недоделок. Наваяли код, обложили тестами, сделали документацию, наклепали примеров, подготовили презентации, провели тестирование всего этого на "тестовых клиентах", внесли исправления по выявленным проблемам - и долгов будет мало. Трение на старте нового релиза зависит только от этого.
С увеличением размера продукта такое трение становится более разнообразным: 10 человек наделали разное количество долгов и кто-то сидит допоздна каждый день, а кто-то дергает за рукав со словами "ну когда уже релиз планировать будем?" Такая ситуация тоже вполне нормальна и нет смысла откладывать работу только для того, что бы "начать работать над новым релизом одновременно" и именно такой подход мне кажется наилучшим.
Это отличный вариант, но с ним вполне можно "бежать впереди паровоза" и действовать неадекватно "мировой ситуации":
  • В целом по команде не должно быть явных перекосов по долгам, когда у кого-то пусто, а у кого-то полные штаны этих долгов.
  • Установленные критерии качества соблюдаются (ошибки быстро исправляются, вопросы быстро отвечаются).
  • В целом по продукту усилия должны быть приложены по направлениям, которые все признают важными (цели на год-два).

Поэтому я же таким энтузиастам начинаю "вставлять палки в колеса" в соответствии с этими пунктами:
  • "У тебя баги кончились? Фиксить нечего? Вопросы по твоим фичам не задают?"
  • Почему бы тебе вместо нового кода не помочь поправить известные ошибки в новом коде фичи Х? Ах не ты делал... А какая разница? Все равно эти ошибки придется исправлять и чем раньше начнем, тем быстрее получим хорошее качество. Перераспределим ресурсы адекватно реальности.
  • Почему бы тебе вместо твоей идеи "а давайте сделаем Х!" не заняться моей идеей "сделать У"?
  • Вот у нас трафик вопросов большой и специалисты поддержки почти по ночам уже сидят - помоги им раз уж закончил со своей работой по выпущенному релизу. Посмотри почему у них такой завал и как улучшить ситуацию?
К счастью энтузиастов, у меня количество таких палок весьма ограничено и можно заранее подготовиться к попыткам "вставлять их в колеса" и начать таки работать на новый релиз:
  • Да кончились. Да, нет багов. И вопросов тоже нет.
  • Либо фичам готова к выпуску в релизе, либо нет. В новом релизе могу помогать, а сейчас лучше выпилить сырую фичу из релиза.
  • Вон опрос провели и выходит, что нафиг не нужен твой "У", все голосовали за мой "Х". И вопросы я еще посмотрел - то же самое выходит, список вопросов в приложении 1.
  • Вот кто выпустил то, из-за чего специалисты сидят - тот пусть и помогает. Опять же премиями можно мотивировать. А я прошлом релизе начал и закончил так, что никто нигде не засиживается. И могу еще что-нибудь сделать с таким же результатом.
Если есть понятные ответы на эти вопросы, то нет причин откладывать работу. Можно "прям щас" составить план на себя в новом релизе и сразу же начать по нему работать.

"Unit тесты" или "Функциональные тесты"

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

Например, тест из первой группы мог бы проверять результат работы метода, который должен посчитать новое значение в зависимости от переданного значения масштабирования экрана ("Make texts larger" в Windows для HighDpi мониторов): передали в него исходную цифру и несколько масштабов - проверили цифру под каждый масштаб.

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

Что же мне выбрать для эффективной работы?

Зачем автор вписал тут буквы "protected virtual" ?

public partial class MyForm : Form {
  private MyForm() {
   protected virtual void Setup(string caption) {
    ...
  }
  public static void ShowMessage(string caption) {
    MyForm form = new MyForm();
    form.Setup(caption);
    form.ShowDialog();
  }

Зачем автор вписал тут буквы "virtual" ? Ведь этот метод вызывается только из статического метода и никакие "override" в это место не добавить.

Одноглазые тесты

Возникла у меня в приложении проблемка: при смене фильтра в моем гриде пропадало "выделение" строки, т.е. строка есть, ее видно, но она просто не "выделена". А выделение строки очень важно: кнопки Delete/Print и многие другие работают с выделенными записями, т.е. нет выделенных записей - кнопки недоступны.
И в результате поведение моего приложения выглядело ужасно: сменил пользователь фильтр, видит в гриде нужную запись, а удалить ее не может, потому что кнопка Delete недоступна. Кто виноват? Конечно же программист!

Я для этого сценария сделал костылик и написал тест с проверкой выделенных записей в этом сценарии: