Зачем программисту 1С инструменты тестирования Web-приложений?

Опубликовал Александр Анисков (vandalsvq) в раздел Администрирование - Тестирование и исправление

В 21-м веке как-то странно говорить об отсутствии API интерфейса у web-приложений, но, увы, такое встречается. Особенно если это приложение - 1С, а данные надо туда вносить. Так как быть, если с человеческим ресурсом у нас напряг, а данные кто-то должен внести?

Каждую историю можно рассказать, разматывая каждое слово до предложения. А можно строго по делу. Я увы не умею ни того, ни другого. Надеюсь, получится нечто среднее. Начнем...

Не так давно, у моих хороших знакомых в организации случилась "автоматизация", навязанная головной компанией. Автоматизация, к слову, весьма посредственная, ибо на тот момент собственная разработка отвечала требованиям компании. Но увы, что пришло сверху, обратно не отправишь. На все уговоры дать интерфейсы загрузки данных ответа не последовало, ну точнее последовала рекомендация "внести данные вручную". А внести надо было около 2 тысяч документов, в каждом порядке 30 строк с 5-7 колонками. Итого мы имеем около 300 тысяч элементов данных.
Программа - 1С, тонкий или веб-клиент, не самое стабильное соединение и дневная нагрузка созданная другими подобными "труженниками". В общем, на один документ, человек должен был тратить порядка 15-20 минут, естественно перерывы "на чай", ошибки соединения и т.д. Вооружившись калькулятором и штатным расписанием было решено, что программу написать все таки выгоднее. Тем более были подозрения, что увы видов документов для внесения не один, а потенциально несколько, а значит и количество труда нужно будет больше. Хорошие знакомые рассказали мне проблему и за чашкой чая (да, да, именно чая) было решено, попробуем написать программу с рабочим названием "тыкалка".

Идея № 1: инъекция в веб-интерфейс

Идея была в том, что запускаем IExplorer application как COM объект, делаем инъекцию в сайт нужного нам скрипта и он начинает что-то тыкать и куда-то нажимать. Не буду долго останавливаться на этой идее, поскольку она быстро умерла. KeyEvent и MouseEvent реализованы в разных браузерах по разному, а в родном IE и вовсе отвратительно. В итоге, если click еще можно было добиться, то вот эмулировать ввод данных никак. А просто присваивать input.value = '125' не выходит, поскольку 1С не считает это значением и на сервере никак об этом не ведает. Однако на этом этапе было много изучено о том, как стороится html страница интерфейса, основные отличия такси от управляемого интерфейса. Но работа застопорилась чуть дальше входа в основное окно, переход по команде меню и попытке ввести значение отбора в форме списка.

Идея № 2: эмуляция событий клавиатуры через WScript.Shell

Собственно в заголовке все сказано. Начальный механизм такой-же, COM объект браузера, переход на сайт и попытка ввести данные в активированное поле. Собственно идея провалилась, события отправлялись в само 1С предприятие которое создало COM объект IE. Может я что-то курил не верно, но победить не смог. В итоге, идея была отметена.

Идея № 3: а что если инструменты тестирования web-приложений могут помочь

Вспомнилось мне время, когда я писал web-приложение. Это было SPA (single page application) приложение на Angular, я только изучал этот фреймворк и решил что надо делать все "по уму", сразу начал делать код тестирования приложения. Поскольку времени на этот проект было мало, умер он не родившись в готовый продукт, но я получил тогда большой опыт. И вот я вспомнил о том опыте и решил погуглить на тему "а что можно использовать". Тут как нельзя кстати статья 1С на Хабре о веб клиенте (тыц) и вдруг неожиданно "selenium" (ссылка на GitHub).
Поскольку на двух предыдущих этапах время было потеряно, сразу в омут с головой было решено не бросаться и взять пару дней на изучение. В итоге, я все больше склонялся к мысли что это то, та самая "серебрянная пуля". Был поднят node.js, с ним в комплекте npm, установлен selenium webdriver, проплачена лицензия на Webstorm (на мой взгляд один из наиболее удобных IDE) и за денек накидана маленький тест, который запуска клиент браузера, переходил на страницу опубликованного веб-клиента 1С и авторизовывался.

Настройка Selenium Webdriver

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

Собственно, чтобы установить свой экземпляр вам понадобится выполнить несколько шагов:
  1. Установить selenium-webdriver (npm)
  2. В каталог "PATH" (что это) положить необходимый вам драйвер для браузера. Chrome и Firefox наименее капризные. IE x86 в принципе тоже не сильно вредный, но вот с IE x64 нужны отдельные танцы с бубном. Об этом читайте ниже.
  3. Объявляете 'selenium-webdriver'
var wd = require('selenium-webdriver');

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

Подключили, молодцы. Что дальше?

Поскольку нам необходимо было данные брать из подготовленных пользователями Excel файлов, было решено следующее. Файлов много, они требуют предварительной обработки перед внесением в формы веб-клиента. Значит нужно написать загрузку данных в максимально простые и удобные формы конфигурации пустышки, опубликовать http-сервисы и данные "подсасывать" из нее, отдавая туда всю информацию о результатах загрузки. В итоге написано два интерфейса  с одним адресом, но разными способами обращения и параметрами.

  • GET. localhost/test/hs/data/doc?user=name. Принимал параметром пользователя от имени которого загружаются данные. В итоге отдавал JSON пакет с данными максимально удобными для внесения
  • POST. localhost/test/hs/data/doc?user=name&result=str. Параметром уже принимает имя пользователя и результат выполнения. Если результат = error, тогда в теле передавался полный лог, от момента авторизации, до момента ошибки.

Поскольку все взаимодействие с клиентом браузера у Selenium построено на promise-ах (это что-то вроде ОбработчикОповещения в 1С, подробнее лучше почитать тут) вести лог достаточно просто.

Как проверить данные в веб-клиенте.

Большинство данных в поля можно вносить несколькими способами: либо Код, либо Наименование, либо значение другого реквизита. Поскольку мы не имели доступа к конфигурации, это было выяснено опытным путем. Большинство справочников было выгружено стандартными "Вывести список" или загружено через единственный интерфейс загрузки НСИ. В итоге, мы решили что данные будут вводиться кодами или другими реквизитами (не представлениями), а результат подбора будет проверяться на соответствие представления. Т.е. кратко это выглядит так:

client.findElement(by.id('userName'))
    .sendKeys('username')
    .then(check_UserName)
    .then(function() {
        console.log('OK');
    })
    .catch(function() {
        console.log('error', 'Значение не равно userName');
    });

function check_UserName() {
    return new Promise(checkInputValue_promise);
    
    function checkInputValue_promise(resolve, reject) {
        var element = client.findElement(by.id('userName'));
        element.getAttribute('value')
            .then(function (attrText) {
                var i = attrText.trim();
                if (i !== 'username') {
                    reject(false);
                }
                else {
                    resolve(true);
                }
            });
    }
}

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

Некоторые нюансы работы веб-клиента:

  • Когда редактируете строку табличной части, на самом деле все input-ы под каждую ячейку уже существуют, поэтому после нажатия sednkeys-Enter можно проверять доступность следующего поля. Имена полей как правило выглядят следующим образом: Form[N]_ИмяПоля_i0, где N - порядковый номер созданной формы, ИмяПоля - имя поля как оно задано в конфигураторе (можно изучить Profiler-ом). i0 - существует всегда, как я понял
  • С нумерацией форм все совсем весело. Дело в том, что если форма полностью перестраивается, то старый контейнер <div id='formN_container'> очищается, создается новый, со следующим номером и в него добавляются все вложенные элементы. Я лечил достаточно просто, когда я понял как изменяется форма после редактирования полей, я просто добавил проверку на изменения номера формы. Сделать это не сложно. Можно пойти путем поиска по следующему пути (нотация xpath) //div[@id='VW_page1formContent']/div[@class='IWebForm']. Собственно последний div и будет вашей формой. А номер "pageN" можно получить по заголовку окна. Впрочем если вы создаете объекты последовательно, то можно просто отследить порядок создания элементов платформой.
  • После окончания редактирования, всегда следует проверять следующий элемент на доступность и видимость, при необходимости отправлять туда Click для активации.
  • Не забывайте о штатном поведении форм 1С, при вводе данных происходит переход на следующее поле. Окончание редактирования последней ячейки приводит к автометическому созданию новой строки. Так что лучше не делать в последнем поле Enter, а либо переходить в следующий элемент, либо вызывать Click на кнопке Добавить.
  • Диалоги вопросов о записи (или закрытии) формы могут быть в отдельном iFrame, следует это учитывать и подключаться к нему соответствующими методами webdriver-а.

Выводы

Веб-клиент 1С вполне пригоден для тестирования, очень даже понятен и хорошо написан. Конечно, есть вопросы к строению дерева HTML страницы, но им виднее. Все необходимые программные компоненты (js, конфигурации, веб-сервисы) были реализованы примерно за одну неделю. Даже сделана попытка реализовать работу в автоматическом режиме, с перезапуском, логированием и прочими плюшками для анализа результата.

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

Причины в основном были кстати следующие:

  • Код не соответствовал наименованию. Лечилось корректировкой данных в исходниках;
  • Программа не дождалась перехода следующего поля в видимость и/или доступность. Лечилось попытками с подсчетом, в случае превышения лимита - завершение клиента, создание нового и повторный ввод данных. Край перезапуск.
  • Клиент отвалился. Не лечилось. Перезапуск.
  • Была добавлена попытка закрыть текущую форму, чтобы не записывать некорректные данные. Перезапуск.
  • Очистка поля иногда приводит к появлению символа 'a' перед вводимым значением. Не лечилось. Перезапуск.

По логам потом отслеживали какие данные не внесены, проверяли и отправляли повторно. На 2000 документов было около 50 ошибочных доков. Проверились за 20 минут вручную и были перезапущены повторно, после чего все село корректно.

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

Бонус. Настройка IE x64

Практически все тонкости настройки описаны тут, но некоторые нюансы опущены. Сразу говорю, у меня IE 11, win 10, x64.

  1. Копируем в PATH драйвер для x64 (тыц)
  2. Вносим изменения в реестр (подробнее в этом разделе)
  3. Настраиваем параметры безопасности (Свойства браузера - Безопасность). Для всех зон ставим "Включить защищенный режим"
  4. Включаем 64-х разрядные процессы для браузера (Свойства браузера - Дополнительно). Ставим галочку "Включить 64-разрядные процессы для расширенного защищенного режима". Попутно проверяем что "Включить расширенный защищенный режим" выключен

На этом в принципе все, после этого IE должен быть более стабильным, а скорость печати будет выше, чем у 100летней бабушки. НО: если не поможет, ставите 32-х битный драйвер, отключаете 64-разрядные процессы (п.4) и работать тоже будет. Возможно даже разницы не заметите.

Послесловие

Во вложении небольшой файлик, который умеет авторизовываться в приложении при наличии драйвера chrome, установленного node.js и npm-пакета selenium-webdriver. Команда для cmd
node "путь к файлу"/setdata_wsors.js

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

P.S. прошу также не пинать за платность файла. Будем считать это скромным "спасибо" за данную статью если она оказалась полезной. Если тема будет интересна, работу с Selenium можно осветить подробнее.

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

Скачать файлы

Наименование Файл Версия Размер
setData_wsors
.js 14,89Kb
08.01.17
1
.js 14,89Kb 1 Скачать

См. также

Комментарии
1. Решитко Дмитрий (grumagargler) 157 08.01.17 23:33 Сейчас в теме
Добрый день! А почему не использовали уже существующий интерфейс доступа к 1С через менеджер тестирования?
2. Александр Анисков (vandalsvq) 696 09.01.17 05:32 Сейчас в теме
(1) стыдно признаться, но я просто про него не вспомнил. Мы не ищем легкий путей. Сейчас попробовал и посыпаю голову пеплом. Спасибо за подсказку. Но с другой стороны, опыт есть опыт иногда он не бывает лишним )))))
3. Александр Анисков (vandalsvq) 696 09.01.17 08:07 Сейчас в теме
(1) а с другой стороны, в принципе путь одинаков, при отсутствии доступа к конфигуратору исследование html нагляднее. Сейчас ради интереса часть перевел на работу через менеджер, ну приятнее, чем работать с веб-клиентом и стабильнее.

Пы.сы. я прям как чувствовал что сообщество ткнет меня носом в очевидный и простой путь. Чувствую себя дураком, что не подумал ранее )))))
4. Решитко Дмитрий (grumagargler) 157 09.01.17 15:23 Сейчас в теме
(3) для написания кода загрузки данных может быть пригодится такой вот бесплатный инструмент, там есть возможность анализа оконной структуры: https://github.com/grumagargler/tester
5. Александр Анисков (vandalsvq) 696 09.01.17 18:40 Сейчас в теме
(4) я все никак до тестера не доберусь. Но практически уверен что руки дойдут. Пора уже рукоблудие в тестировании на автоматы переводить ))))
6. Иван Коротеев (kiv1c) 319 10.01.17 10:54 Сейчас в теме
(5) то есть по сути доступа к конфигуратору у вас не было, и вам пришлось заполнять формы в веб-клиенте яваскриптом? хитро)
а вот подробнее по поводу " Однако на этом этапе было много изучено о том, как стороится html страница интерфейса, основные отличия такси от управляемого интерфейса" можно? вы же не просто смотрели html код веб-клиента а наверное какие-то статьи читали?
7. Александр Анисков (vandalsvq) 696 10.01.17 16:13 Сейчас в теме
(6) на самом деле мне хватило знаний полученных по spa приложениям, статьи на хабре, заметок из Зазеркалья и профайлера в хроме и ie. Были неожиданности вроде уничтожения ветки с контентом форм при перестроении, но это мелочи. Как например реализована таб часть я и ранее догадывался (по собственному опыту знаю недостатки тега table). Использование фреймов конечно не обрадовало, имхо без них можно было обойтись, но им виднее почему так.
А если бы был доступ к конфигуратору или запуск обработок в клиенте, все было бы значительно проще.
8. ivanov660 ivanov660 (ivanov660) 330 10.01.17 17:35 Сейчас в теме
Из заголовка статьи не понятна поставленная задача. Если требовалось создать кучу документов, то почему бы не написать обработку, которую запустить на сервере в фоновом задании - быстрее и проще, а нагрузка через веб сервис более серьезная.
Пробовал тестировать веб интерфейс под селениумом не очень понравилось по сравнению с встроенным механизмом автоматизированного тестирования - сложнее, больший объем правок при записи сценария,
зато у 1Сного больше багов в реализации.
9. Александр Анисков (vandalsvq) 696 10.01.17 18:19 Сейчас в теме
(8) как и писал, доступа к конфигуратору не было и не дадут. Обработки тоже под запретом. Даже через штатные БСП-шные механизмы тоже никак. Тогда бы не придумывали. У селениума в 3-й версии все весьма стабильно, особых претензий к багам не было. Сценарии писать, это да, но руку я набил быстро и даже новые сценарии попробовал, максимум 4-6 часов и готово. Что касается 1С, я перевел один сценарий, в принципе по затратам не сильно большая разница. Удобнее, поскольку на 1С я больше работаю и переключаться между языками иногда не хочется.
10. Антон Стеклов (asved.ru) 33 11.01.17 06:34 Сейчас в теме
11. Александр Анисков (vandalsvq) 696 11.01.17 09:42 Сейчас в теме
(10) о каком rest api может идти речь интересно.
1. Если о стандартном api веб-клиента, то я думаю это закрытая информация и вряд ли ее можно найти, да и применимо ли оно в отрыве от интерфейса большой вопрос.
2. Если про OData - то не думаю что кто-то в здравом уме и трезвом рассудке в рабочие базы будет публиковать OData, вот и тут его тоже нет.
3. Ну, а про самописные http-сервисы (и веб-сервисы) мне ничего не известно. Т.е. считаем что их нет. Доступа то к конфигуратору нет, как писал выше неоднократно.

Прошу пояснить вопрос если я на него не ответил.
12. Артур Аюханов (artbear) 859 16.01.17 12:25 Сейчас в теме
(0) Саша, для тестирования еще порекомендую наши давно известные и проверенные инструменты xUnitFor1C и vanessa-behavior.
работают в разных режимах, ОФ, УФ, веб-клиент, тестирование в 8.3 и т.п.
13. Александр Анисков (vandalsvq) 696 16.01.17 12:37 Сейчас в теме
(12) блин, Артур да я бы, да только двумя руками. Вот только беда, между молотом и наковальней места и времени мало. Иногда бы остановится, да процесс разработки поменять, но паровоз едет и тебя тащит ))))))
14. Артур Аюханов (artbear) 859 16.01.17 13:03 Сейчас в теме
(13) а ты потихонечку, начни с кочегаров хотя бы, а не сразу с машинистов или замены паровоза :)
Оставьте свое сообщение