Автор оригинала: Dmytro Zaichenko.
Мы всеваемся писать спецификации, не мы? Причина в том, что эти сценарии действуют как часы собаки, делая рефакторинг безопаснее, а иногда и единственную функцию документации, существующей в кодовой базе.
Единственным недостатком является то, что иногда требуется века, чтобы иметь правильную настройку данных, разрешит зависимости классов CSS и постоянные изменения CSS/HTML. Читабельность и ремонтопригодность тоже не всегда идеальны. Ну, у нас есть несколько простых техник, которые могут помочь вам преодолеть большинство вопросов, описанных выше. Написано для сквозных спецификаций транспортировки, их можно легко использовать с предпочтительной системой тестирования.
Давайте проверим простой пример разметки
... I'm an awesome label ...
С соответствующими спецификациями
describe('Awesome page', () => { beforeAll(() => { browser.driver.get("http://mysite.com/awesome"); }); describe('Awesome block', () => { const block = element(by.css('.awesome-block')); const label = block.element(by.css('.utility-class')); it('has awesome label', () => { expect(label.getText()).toEqual("I'm an awesome label"); }); }); });
и попытаться улучшить их.
Отдельные тестовые специфические атрибуты
Если у вас есть инженеры, работающие отдельно с CSS/HTML и угловыми/js компонентами, вы, вероятно, столкнулись с проблемой, что изменения разметки не являются безопасными с точки зрения спецификаций.
Фронтальный инженер может случайно сломать спецификации, просто изменив имя класса утилиты или нанесение различного класса в соответствии с изменениями CSS. Хотя этот вопрос можно избежать, проверяя коннентные селекторы спецификаций всякий раз, когда применяется изменение разметки, это не очень удобно. Альтернативное решение будет иметь правильные устойчивые семантические классы на каждом тестированном элементе, но это слишком идеально
Другой вариант – иметь специальный атрибут, который используется Только путем тестирования рамок:
Я классный ярлык
Похоже, у нас есть устаревшие атрибуты вокруг нашей нашей разметки. Хотя использование этой техники мы получили ряд преимуществ:
Каждый протестированный элемент имеет отдельное значимое изменение разметки имени намного проще, а «безопасные» спецификации не зависят от изменений CSS
Страница/Компонентные объекты
При написании сквозных испытаний общий шаблон должен использовать Страница объектов Отказ Это облегчает поддерживать и повторно использовать спецификации. Давайте определим простой страницу объекты для наших спецификаций:
class PageObject { constructor(public finder: ElementFinder) { } protected get element() { return this.finder.element.bind(this.finder); } protected getChild(locator: string) { return this.element(by.css(locator)); } } class AwesomeBlock extends PageObject { get awesomeLabel() { return this.getChild('[data-test=awesome-label]'); } } class AwesomePage extends PageObject { visit() { browser.driver.get("http://mysite.com/awesome"); } get awesomeBlock() { return new AwesomeBlock(this.getChild('[data-test=awesome-block]')); } }
Тестовые примеры теперь будут выглядеть так:
const page = new AwesomePage(element(by.css("body"))); describe('Awesome page', () => { beforeAll(() => { page.visit(); }); describe('Awesome block', () => { const awesomeBlock = page.awesomeBlock; it('has awesome label', () => { expect(awesomeBlock.awesomeLabel.getText()).toEqual("I'm an awesome label"); }); }); });
Намного чище, нет селекторов CSS в примерах, но мы можем улучшить это еще больше? Конечно! С помощью общего атрибута, специфичного теста на каждом тестируемом элементе и типографии Декораторы Объекты страницы могут выглядеть немного Fancier:
class AwesomeBlock extends PageObject { @hasOne awesomeLabel; } class AwesomePage extends PageObject { visit() { browser.driver.get("http://mysite.com/awesome"); } @hasOne awesomeBlock: AwesomeBlock;
с декоратором, определенным как:
export const hasOne = (target: any, propertyKey: string) => { Object.defineProperty(target, propertyKey, { enumerable: true, configurable: true, get: function () { const child = this.getChild(`[data-test=${_.kebabCase(propertyKey)}]`); const PropertyClass = Reflect.getOwnMetadata("design:type", target, propertyKey); return new PropertyClass(child); }, }); };
Теперь мы имеем многоразовые примеры спецификации, которые не зависят от изменений CSS и хорошего DSL для определения классов компонентов/компонентов.
Образцы Insights и Code были сделаны Железнодорожный Инженерная команда