Как стать автором
Обновить

Комментарии 20

Ext.Js с его асинхронными запросами на любой клик устроен так, что для многих вызовов нам нужно ждать сообщение об ошибке секунд 10 и если мы его не получали, то считали, что поиск отработал нормально.
10 секунд здесь, 10 там и в итоге сам тест на 90% времени состоит из ожидания.


А эта проблема в итоге была решена или нет?
Да, в каждом конкретном случае в API selmaril нашел детерминированный способ определить, нужно ждать ответа дальше или нет. Как раз была проблема в том, что при внешне похожих условиях нужно было применять различные алгоритмы разрешения. Если сами тестируете, можно его поспрашивать.
Да, решил! Правда потребовался сдвиг мышления.

Все же мы тестируем высокоуровневый функционал, то, как компоненты ведут себя вместе, как они реализуют системный функционл. А ещё тестируем сложные цепочки вызовов, которые не из интерфейса сложно проверить. Ну и гарантируем то, что версия продукта не будет иметь очевидных проблем с точки зрения конечного пользователя (на покрытых участках, естественно).

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

Так вот, тесты во время выполнения делают инъекции в тестируемый код *увернулся от помидорки*. Правда очень ограниченные, и эти инъекции не должны изменить логику тестируемого стенда.

В частности для AJAX, перед вызовом добавляется подписчик, который регистрирует этот вызов в глобальной коллекции. А по выполнению (или на отказ) вешается другой подписчик, который во первых изменяет состояние глобальной коллекции, а во вторых зачищает за собой весь мусор.

Таким образом мы пуляем событие на выполнение AJAX (жмем кнопку, обновляем список и т.п.), и после этого начинаем долбить Selenium-ом браузер на предмет завершенности запроса в данной глобальной коллекции. Выходит что нам не важно что должно будет прийти на AJAX запрос (а там такой адЪ приходит порой), нам важно чтоб в принципе запрос завершился. И нам не надо ждать больше положенного. Соответственно пока Selenium не убедился что запрос закончен, он не передает управление прикладному коду теста. Это упрощает тест. Разработчику теста даже не надо думать что его кнопочка что-то там куда-то услала, он просто проверяет что после того, как нажал кнопочку появилось окошко с надписью «Учапу»! И это прекрасно ^_^ А ещё мы вместо тестера перехватываем все технические ошибки (запрос не прошел, вернулся не тот формат, требуется аутендификация и т.п.).

Вот как-то так.
Удивило, кстати, в ваших демках, что вы приложения не минифицируете. 200+ http-запросов как с куста :-)
Ага, при первой загрузке довольно много запросов. Тут у нас основная идея в том, чтобы статические ресурсы запрашивались (и кэшировались) отдельными запросами, что позволит отдельно управлять таким кэшем. Соответственно, при повторном запуске запросов должно быть меньше
www.webpagetest.org/result/130603_0R_PZ1/ (в этом примере 167 и 11)

Но частично проблема и в том, что все наши текущие клиенты — корпоративные. Приложения на нашем ядре работают во внутренних сетях или на широкополосном доступе, и поводов ТЩАТЕЛЬНО оптимизировать количество запросов у нас меньше, чем могло бы быть :)
Но частично проблема и в том, что все наши текущие клиенты — корпоративные. Приложения на нашем ядре работают во внутренних сетях или на широкополосном доступе, и поводов ТЩАТЕЛЬНО оптимизировать количество запросов у нас меньше, чем могло бы быть :)


у нас в компании тоже есть такое корпоративное приложение — только оно расположено в штатах, а наш офис через VPN туда подключается. Без мата работать не возможно.

Ааа, есть еще одно «корпоративное» приложение — salesforce называется, тоже не летает.
Кстати, а действительно, по сравнению с этими двумя приложениями по скорости работы наше скорее тупит или скорее летает? Какое Ваше мнение?
Ух ты, а вот и первое упоминание Salesforce, встреченное без специального гугления на просторах интернетов :)
Первый твой комментарий, не то что без специального гугления, без каких либо ожиданий встретить его в такой теме!
API над Selenium и NUnit, которое само состояло бы из очень простых элементов, но позволяющих оперировать не мышкой и DOM моделью, а с объектами интерфейса Ext.Js

Есть надежда, что это надстройка появится в виде opensource-проекта?
Я бы поучаствовал в идее и каркасе OpenSource ядра тестирования, но не уверен что смогу найти время чтоб поднять такой проект самому. Все же текущее ядро достаточно специализированно, и оно тем лучше, чем лучше отражает бизнесс объекты тестируемой системы. Цель универсальности не ложится в постановку на эту работу увы :\ Но если готовы поучаствовать, то можно замутить что-то :) Я бы объяснил в деталях как оно работает. В общем велкам, в ЛС.
В одиночку, конечно, сложно, но ведь в том и смысл opensource, чтобы найти помощников, которые тоже заинтересованы в появлении такой библиотеки-надстройки. У меня в настоящий момент коммерческих проектов с использованием ext.js не имеется, так что мой интерес не непосредственно практический, а общее развитие экосистемы вокруг Selenium — больше надстроек хороших и разных!
Я вот не понял немного на счет реализации тестирования API, так сейчас тесты иду через браузер путем выполнения JavaScript кода из C#, или тестируются внутренние .NET компоненты ExtJS или тестируются HTTP запросы?
Все напоминает простой юнит тест, только с селениумом.
Сперва вы пишите свой АПИ. Например для формочки логина пишете класс форма_логина, у неё два инпута — тоже классы. У каждого есть свои методы, например у инпутов — ввести текст, у формы — сделать сабмит.

На самом нижнем уровне (например сделать сабмит формы) вылезает силениум. Примерно так:
SubmitForm(idOfSubmitButton)
{
webDriver.SelectById( idOfSubmitButton ).Click(); // вызвать кнопку на форме по ID и нажать на неё произведя сабмит
}
И тест состоит из последовательности таким методов типа SubmitForm()
И всё. Запустив тест вы видите как всё само тестируется. Фиксяться тесты также быстро. Самое долгое — написать API для всех UI элементов.
Скорость тестирования некоторых тестов в сравнении с людьми сокращается с 2х часов до 30 минут (пример из жизни). Количество манки-тестировщиков можно уменьшить до 1 (проверять вёрстку и т.п.)

Фактически это эмуляция поведения человека (перетаскивание мышки, клики, ожидание, проверка текста)
Тест идет через браузер (с помощью специального драйвера Selenium). Собственно, в этом суть Selenium.
API (которое посылает команды драйверу на клики в браузер) и сам тест написан на C#.
А как же вы решили проблему с автогенерироваными ID?
На этом примере я вижу элементы с айди ext-gen-#### которые генерируются при каждом обновлении страницы.

dev.sencha.com/deploy/ext-4.0.0/examples/desktop/desktop.html
Если в кратце, то наберите в отладчике на указанной вами странице это:

Ext.ComponentManager.each(function (id, item){console.log(id, item.getXTypes(), item.initialConfig)})

В консоль выведется весь список компонентов. Из них уже можно вытянуть Id DOM узла, или ссылку на него (Ext.getCmp('id').body.dom — например). Далее этот Id или ссылку (да, да, именно ссылку на DOM) можно передать в Selenium.

Тут все более менее понятно. Вопрос как найти нужный компонент.

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

Получается мы можем восстановить иерархию компонентов с одной стороны, и с другой стороны выцепить нужный компонент. А самому Selenium не нужен именно Id, ему нужна ссылка на DOM узел. Да но можно передавать и Id, дело вкуса.

Кстати, ExtJS так устроен, что идентификатор компонента соответствует идентификатору корневого DOM узла из верстки этого компонента. Т.е. можно по Id найти контейнер и по нему кликнуть, а по контейнеру можно найти компонент, и выцепить информацию о его конфигурации, где могут быть определяющие назначение этого компонента зарубки.

+ Можно в некоторых случаях и DOM шаблон компонента переопределить. Но это трудозатратно и нудно, я так делать перестал, от идеи отказался.
Спасибо. Это действительно интересный подход.
Вопрос немного не по теме:
1. Если у вас старый проект, то как вы мигрируете между ключевыми версиями extjs или остались на старой версии?
2. Перешли ли на сборку проекта средствами Sencha CMD?
3. Если используете rest store, то как избавились от генерации уймы запросов при изменении нескольких сотен записей в store за один проход?
4. Как реализуете первоначальную загрузку данных с сервера при инициализации приложения — генерируете десяток запросов к бекенду через стандартные store.load(); или реализовали собственный загрузчик?
5. Как обстоят дела с синхронизацией записей в store, если одновременно с программой работают десятки людей?
Вы исходите из предположения, что клиент на ExtJS у нас толстый, но это не так. Он очень тоненький и не является источником, либо хранилищем данных (за исключением редактируемой в данный момент формы). Клиент — это лишь отображение данных.

А ещё мы используем Ext.NET, так что необходимости собирать ExtJS у нас нет.

Теперь по вопросам:
1. Текущий проект был переписан на ExtJS 3 с нуля. На ExtJS 4 происходит миграция, с болью конечно, но за пару месяцев управлюсь. У нас очень много изменений в компонентах.
2. Нет необходимости. Ресурсами управляет Ext.NET, он сам собирает скрипты.
3. Редактируемые GridPanel у нас есть, но REST store мы не использовали. Самостоятельно обходим набор данных хранилища, формируем в один запрос все изменения и шлем на сервер. Это обусловлено сложной структурой данных, отображаемых в редактируемом списке, и их не полной транзитивностью.
4. Такой необходимости нет, клиент оооочень тонкий. Все что он загружает при старте — дерево навигации, да пяток компонентов-виджетов (асинхронно по событиям).
5. Одновременно с программой работают десятки людей. Проблемы с синхронизацией не возникают. В принципе сервер управляет этим, отправляя команды обновления наборов данных в некоторых случаях. Конкретная запись данных версионна и это проверяется на сервере. Так что с синхронизацией проблемы решать не пришлось.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.