Всем привет.
Для начала представлюсь. Зовут меня Дмитрий Рак, я уже более 8 лет занимаюсь всем, что касается QA: тестирование, автоматизация и менеджмент. Ссылка на LinkedIn: https://www.linkedin.com/in/dmitry-rak-178b04b0/
Некоторое время назад ко мне в команду пришел запрос на автоматизацию тестированию проекта, построенного на платформе SalesForce. Я решил расписать задачи/идеи и проблемы с которыми мы сталкивались на проекте. Так как объем, полученных знаний и опыта довольно велик статью придется разбить на несколько частей. Первая часть скорее вводная и дающая общее представление о том из чего состоит автоматизация в SalesForce. Судьба очередности следующих частей зависит от комментариев и вопросов под первой частью.
Итак, скепсис по отношению к такой задаче сразу же был максимальным из-за следующих стереотипов в моей голове:
- SalesForce - это уже готовый продукт, который просто кастомизируется под ваш WorkFlow, зачем там тестирование?
- SalesForce спрятал свою базу данных настолько глубоко, что подготовка неких данных для тестирования будет целым кошмаром.
И вот спустя 9 месяцев на проекте я делюсь своими мыслями, идеями и болью насчет возможности и подходов к автоматизации тестирования SalesForce.
Когда-то SalesForce можно было назвать CRM-системой на основании SaaS-модели. С ходом времени платформа поглощала разного рода организации, начала предоставлять возможность разработки приложений на своей же базе используя модель PaaS. В последнее время платформа сильно углубилась в аналитику, BI и маркетинг, в основном за счет поглощения таких компаний как Buddy Media и Tableau (куплена, кстати, в этом году примерно за 16 млрд. долларов).
На данный момент у SalesForce кроме настройки тех самых WorkFlow есть свой язык программирования, называемый Apex. Язык строго типизированный, объектно-ориентированный, синтаксис сильно напоминает Java. Несколько крутых для автоматизаторов знаний об Apex и SalesForce приведу ниже:
- Синтаксис понятный, построен в сущности на триггерах, описании объектов и запросам к базам данных;
- На Apex можно писать Unit-тесты. SalesForce обязывает разработчиков иметь покрытие кода тестами на уровне не ниже 75% . Иначе билд не будет успешным (Восторг!!);
- JS и верстка все еще нужны, но большинство страниц могут быть собраны из предоставляемого самим SalesForce конструктора (т.е. UI тестировать, практически, не нужно так как одно поле не отличается от второго, имеющего просто другое название);
- Доступ к базе данных через JDBC не получить. Зато к каждому объекту в системе автоматически генерируется REST API с полным CRUD (Mama Mia!!!).
Теперь поговорим подробнее о подходах к тестированию. Итак, у нас есть покрытие кода по дефолту >75%. У нас есть UI, которые в большинстве случаев пишется не разработчиками, а составлен из стандартных компонентов. Тестирование необходимо по сути на уровне бизнес-логики и взаимодействий между разными компонентами UI и вызова триггеров. По сути для грамотного построения пирамиды тестирования нам осталось добавить ~20-25% тестов на REST API, и еще ~5-10% на UI. UI для практического любого объекта в SalesForce состоит из следующих страниц:
- Страница создания объекта ( BlablaDetailsPage.java )
- Страница деталей объекта ( BlablaCreationPage.java )
- Страница объектов связанных с другим объектом ( BlablaRelatedList.java )
В PageObjects, соответственно, описываются некоторые формы. В SalesForce разработчики могут создавать формы тремя способами, локаторы для полей, находящихся на них, соответственно, будут отличаться:
- Некогда актуальные Visualforce-формы: https://help.salesforce.com/articleView?id=pages_custom_components.htm&type=5
- Стандартные SalesForce-формы, накиданные через конструктор;
- Стильные, модные, молодежные Lightning-формы: https://developer.salesforce.com/docs/component-library/overview/components
Далее разберемся по типам полей, которые могут присутствовать на этих формах. Если разбирать наиболее часто используемые, то это:
- Input (VisualForceInput.java, SalesForceInput.java, LightningInput.java);
- TextArea (VisualForceTextArea.java, SalesForceTextArea.java, LightningTextArea.java);
- Select (VisualForceSelect.java, SalesForceSelect.java, LightningSelect.java);
- MultiSelect (VisualForceMultiSelect.java, SalesForceMultiSelect.java, LightningMultiSelect.java).
В теории локаторы могут иметь внутри себя логику “ИЛИ” и тогда можно уйти от 3 классов для разных технологий ( но делать мы этого, конечно, не будем).
В итоге каждый из 3 PageObjects, перечисленных выше, должен состоять из полей, соответствующих типов, которые отличаются только названием. Вся внутренняя кухня по поиску локатору находится внутри обертки под элемент. Имея такую базу из массы страниц и полей под них можно собирать любые тесты на CRUD-операции внутри SF. Из таких CRUD-операций и состоит наш Build Verification Test. Для проверки более сложной логики подготавливается масса исходных условий, все они по-максимуму готовятся через REST API. О том как взаимодействовать с SalesForce REST API поговорим в другой статье, а пока обсудим с какими проблемами в итоге пришлось столкнуться во время автоматизации:
- SalesForce позволяет пользователям работать в разных вкладках внутри приложения. В итоге локаторы - это сплошные XPATH, где в начале идет префикс для текущей активной вкладки, потом только сам локатор;
- SalesForce позволяет логиниться без двухфакторной аутентификации только с “Trusted IPs”. Как варианты обхода: отключить такую аутентификацию, получать сессионные куки и подставлять их в драйвер, добавить все IP как доверенные в Git-репозиторий, чтобы настройки не сбивались после каждого деплоя приложения. Либо использовать плагин для Chrome, которые за пару секунд добавит ручками все IP в конфиги вашей организации: https://chrome.google.com/webstore/detail/whitelist-all-ips-for-sal/nnlnikmkkbpgioojghgojoejgcheilic
- Зоопарк Roles/Profiles и Permission Sets внутри организации, а также невозможность создавать пользователей налету через, допустим, REST API приводит к довольно монотонной подготовке тестовых данных перед копированием данных с продакшн-сервера на сервер для автотестов (если, конечно, вам нужны prod-like данные).
В конце хочу сказать, что на просторах интернета так и не нашлось готового фреймворка под задачи, описанные выше. В итоге был создан свой собственный (ммм, свежие костыли): о нем речь и пойдет в последующих статьях. Ваши комментарии/замечания, как всегда, приветствуются.