среда, 5 июня 2019 г.

Как писать тесты на поведение с разными конфигурациями настроек?

или "Как писать тесты на расширение поведения контролов?"

Например, у меня есть контрол MyTextEdit и у него сейчас есть свойство "repaintChangesOnly {false, true}". В моем текущем проекте много таких свойств: сначала сделали одну реализацию (и кучу тестов на нее), потом один из клиентов сообщил о ее недостатках и мы придумали другую (и добавили новое свойство). Обычное дело в долгоиграющем проекте на несколько лет.

Внимание!!! Разыкивается Новый Клиент!!!

Как увеличить количество новых клиентов "за неделю"? Не в смысле "как похудеть за неделю", а как увеличить их количество так, что бы через год каждую неделю новых клиентов приходило на 10% больше чем сейчас? Или не через год, а через полгода. А может быть через два года...

На какие цели можно ориентироваться при планировании следующих релизов?

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

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

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

3. есть явные преимущества Win приложений по сравнению с Web/Mobile/Multy и конечным пользователям они необходимы
 - клиент будет продлевать лицензии ради изменений в новых версиях, которых нет в старых
 - клиент будет продлевать лицензии потому что привык/знает или просто наловчился все делать быстро с этим средством разработки
 - клиент будет покупать новые лицензии что бы начать делать такие заказы на нашем продукте

4. для клиента разработка Win приложения выглядит дешевле/интереснее, он раньше делал прилаги на win и теперь жалко опыт или трудно учиться - выбирают наш продукт потому что можно и дальше делать на win, но в дополнение к нему он дешево получает web/mobile
 - клиент будет продлевать лицензии ради изменений в новых версиях, которых нет в старых
 - клиент будет продлевать лицензии потому что привык к этому средству разработки
 - клиент будет покупать новые лицензии что бы начать делать такие заказы на нашем продукте

+ комбинации факторов

Наши доходы:
- продление лицензий
- новые лицензии

Наши неявные доходы:
- завлечение новых клиентов своими впечатлениями

Наши расходы:
- небольшие исправления в нашем коде для получения нужного поведения (баги)
- помощь в разработке нужного функционала (поддержка)
- реализация сложного функционала (новые фичи)

Много багов!!! Что делать?

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

  1. желания записать именно баг
  2. большого количества кода
  3. код используется в очень разнообразных сценариях/вариантах окружения + команда часто вносит изменения и нет фиксации результатов работы кода во многих сценариях/конфигурациях

Javascript: поиск по селектору может работать неправильно с вложенными элементами

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

<div class="toolbar">
      <div class="toolbar-items">
          <div class="toolbar">
              <div class="toolbar-items">
                  <div>some text</div>

(GDPR: конфигурация конечно упрощенная, в таком виде выглядит как "дурацкая" и "это никто никогда не будет настраивать", но вот кто-то настроил, и для сценария автора я и сам настроил бы именно такую конфигурацию).

Покопался как все работает и оказалось, что элементы в toolbox добавляет такой код:

    container = this.find(".toolbar-items");
    item.appendTo(container);

Этот код ищет элемент DOM, в который будет добавлен очередной toolbar item.
Такое использование $.find() для поиска дочернего элемента будет неправильно работать на элементах, которые вложены друг в друга как в этой конфигурации: $.find для внешнего элемента возвращает 2 элемента (свой и еще один из вложенного toolbox) и с jQuery кнопка добавляется во второй (где-то там внутри append есть for(..), который добавит item в каждый container, в результате item останется в последнем).

Покопался еще и оказалось что без jQuery ничего не разъезжается... Оказалось, что jQuery может быть заменен на другую реализацию и в ней выполняется примерно такой код:

    insertElement(container[0], element);

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

В этой конфигурации вместо find можно использовать прямую ссылку на нужный элемент, например так:

    container = this.this[".toolbar-items"];
    item.appendTo(container);

Так я и сделал.

Javascript: как можно усложнить сопровождение

Какие варианты мне попадались:


  • Переставить переменные в математическом выражении:

    var timestamp = Date.now();
    setTimeout(
            function() {...},
            Math.max(0, 300 - Date.now() + timestamp)
        )
Порядок переменных "timestamp - Date.now() + 300" легче понять как "300" с момента начала, чем первый вариант.
Еще лучше будет читаться "setTimeout(function() {...}, 300)" и по контексту вокруг этого кода (запуск браузера ожидание ответа) уменьшение этих 300мс выглядит экономией на копейках.


  • To be continued...