E2E тестирование на C#. Как настроить порядок запуска тесто

csharp
bdd
specflow
execution
webdriver
visual-studio
e2e
Теги: #<Tag:0x00007fedb9ec8570> #<Tag:0x00007fedb9ec8390> #<Tag:0x00007fedb9ec8188> #<Tag:0x00007fedb9ecff50> #<Tag:0x00007fedb9ecfd70> #<Tag:0x00007fedb9ecfb18> #<Tag:0x00007fedb9ecf988>

(Alexandr D ) #23

В 99% случаях зависимости можно избежать.
Причина необходимости порядка - не флоу сайта или ещё что-то, а исключительно зависимость тестов, которую надо убирать.
А если вы тестируете Е2Е сценарий, зачем его разбивать на разные тесты? Это уже не Е2Е.


(Юрий Аксютин) #24
  1. Если необходимо запускать сценарии в строгом порядке, то есть смысл объеденить их в один сценарий
  2. Существует слово Background
  3. В файле *.srprofile
    <Execution
    testSchedulingMode=“Random”
    />

Но, если ваши тесты зависят друг от друга - это неправильно спроектированные тесты. Это АКСИОМА


(Максим) #25

У меня сделано так:

  1. Слелал каждый шаг и определил их в мета шаги.
  2. Вынес все техническое в отдельный файл.
  3. В тесте вызываю примерно так

Login();
Setupuser(
name.a,
dob.20,
bla.bla,
набор строк передаю параметрами);
Q&A(
Q.a
A.s
набор вопросов и ответов передано параметрами);

В каждом меташаге стоит мини асерт для отслеживания что мета шаг не упал и выдал нужные данные. В конце уже проверяется на все.

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


(Никита Масловский) #26

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

Да-да, многие скажут, что тесты должны быть независимы и они будут правы до того момента, когда поймут, что речь идёт не об обычных автотестах, в которых зависимость тестов - грех, а о E2E-тестах в BDD процессе. В таком случае мы имеем дело с естественной зависимостью между тестами, т.к. сам пользователь выполняет их именно в таком порядке. За нужно литературой отправлять не буду. Гуглите что такое BDD, User Stories, Story Mapping и тогда все встанет на свои места.

По итогу, если мы имеем дело с SpecFlow, к сожалению, он очень кривой как по мне(с оригинальным Cucumber таких проблем не возникало), а также с NUnit, то единственным быстрым решением проблемы является добавления в каждую “прослойку” между Gherkin и Step Definitoins(тот самый файлик с тем же названием feature-файлом, но с расширением .cs) атрибута:

[NUnit.Framework.Order(‘порядок теста’)]

И выглядеть будет это примерно так:

[System.CodeDom.Compiler.GeneratedCodeAttribute("TechTalk.SpecFlow", "2.3.2.0")]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[NUnit.Framework.TestFixtureAttribute()]
[NUnit.Framework.DescriptionAttribute("Переход на форму входа")]
[NUnit.Framework.Order(1)]
public partial class ПереходНаФормуВходаFeature
{
   ...
} 

Для того, чтобы сделать это более адекватным образом и долгосрочным нужно добавлять список всех сценариев в БД вида [id_теста, название_теста] и связывать это с группами тестов(для различных версий прогона(к сожалению тэги в SpecFlow просто бесполезны и несут лишь атрибутивный характер, с ними работать нормально нельзя) вида [id_группы, название_группы] и запускать тесты путём выгрузки списка тестов и запуска их через командную строку.

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

Всем спасибо, удачи и зелёных билдов!


(Alexandr D ) #27

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

Правильнее делать так - создаём вторую часть класса в том же namespace, что находится первая часть (можно в отдельном файле, для наглядности, файл можно назвать как угодно):

[NUnit.Framework.Order(1)]
public partial class ПереходНаФормуВходаFeature
{
} 

В таком случае у вас всегда атрибут будет на месте.

Это костыль. А если БД будет лежать, что будете делать?

Я бы посмотрел на вас, когда хотя бы 50-100 E2E тестов будет запускаться не параллельно, и сколько вы на это потратите времени :slight_smile:

Хотя, конечно, если на time2market плевать - можно не заморачиваться и всем доказывать, что Е2Е не должны быть независимыми.

Хотя исходя из самого названия E2E, оно уже подразумевает, что это пройденный от начала до конца сценарий тестирования.
А у вас E2E делится на какие-то зависимые друг от друга тесты - это уже не E2E-тесты, называйте это тогда по-другому.


(Никита Масловский) #28

В чём проблема запускать параллельно разные Е2Е тесты? Просто один Е2Е будет состоять из нескольких, которые будут запускаться последовательно.


(Никита Масловский) #29

И какой вариант тогда будет не костылём? Если не использовать БД.


(Alexandr D ) #30

Мы наверное с вами о каких-то разных E2E говорим…

Давайте я приведу всем, наверное, известный пример E2E-теста.
Вот он:

Открытие сайта в браузере и поиск определенных элементов.
Затем заполнить несколько форм регистрации.
Затем убедитесь, что пользователь успешно создан.

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

Е2Е НЕ МОЖЕТ БЫТЬ ЗАВИСИМЫМ ОТ ДРУГИХ ТЕСТОВ, он проверяет весь сценарий от запуска приложения до конечного результата, который требуется получить.
E2E зависит от других факторов - от работоспособности интеграции модулей системы, например.


(Никита Масловский) #31

Я тоже приведу пример. Есть сайт, на котором есть анкета клиента и пользователь должен заполнить все поля в этой анкете. Сам сценарий будет выглядеть следующим образом:
Это один из примеров сценария.

Сценарий: 05_Заполнение_блока_Паспортные_данные
		Если я указываю "Паспорт" в поле "Тип документа"
		То в поле "Гражданство" должно быть указано "БЕЛАРУСЬ"
		Если я ввожу "" в поле "Орган, выдавший документ"
		И я ввожу "" в поле "Серия и номер паспорта"
		И я ввожу "" в поле "Дата выдачи"
		И я ввожу "" в поле "Срок действия"
		И я ввожу "" в поле "Фамилия латинскими буквами"
		И я ввожу "" в поле "Имя латинскими буквами" 
		И я выбираю "Нет" в поле "Менялось ли ФИО?"
		И я ввожу "" в поле "Место рождения" 
		То в поле "" должно быть указано "Г. МИНСК" 
		Если я ввожу "" в поле "Адрес регистрации"
		То в поле "" должно быть указано "Г. МИНСК" 
		Если я указываю "" в поле "Тип улицы"
		И я ввожу "" в поле "Улица"
		И я ввожу "" в поле "Дом"
		И я ввожу "" в поле "Квартира"
		И я ввожу "" в поле "Индекс"
		И я ввожу "" в поле "Дата регистрации"
		И я ввожу "" в поле "Телефон по месту регистрации"
		И я выбираю "Нет" в поле "Отличается ли адрес проживания от адреса регистрации?"
		И я указываю "В собственной квартире" в поле "Условия проживания"
		И я открываю блок "Персональные данные"
		То рядом с заголовком группы полей "Адрес проживания" должна появиться галочка
		И должен закрыться блок "Паспортные данные"
		И должен открыться блок "Персональные данные"
		И должны отобразиться следующие группы полей:
		| группа_полей                               |
		| Данные о семье                             |
		| Образование                                |
		| Контактные данные                          |
		| Контактное лицо                            |
		| Уголовная\Административная ответственность |

(Никита Масловский) #32

Весь мой E2E состоит из 11 таких сценариев. Что вы предлагаете сделать мне?


(Alexandr D ) #33

Запихать всё в один сценарий, в противном случае это будет не Е2Е.

Сценарии по типу как этот Сценарий: 05_Заполнение_блока_Паспортные_данные
Описать как мета-шаги что-то типа И я заполняю блок "Паспортные данные"

В итоге у вас сценарий Е2Е не будет громоздким.


(Никита Масловский) #34

Можешь кинуть ссылку на референс про мета-шаги?


(Alexandr D ) #35

Вы можете просто создать класс с мета-шагами, и в нём уже создать метод, реализующий этот шаг - в нём будет заполнение всех необходимых полей.

Так же вы можете параметризировать мета-шаг (перегрузкой), как вам захочется, например так:

И я заполняю блок "Паспортные данные" данными из таблицы:
|Поле   |Значение  |
|Город  |Г. МИНСК  |
|и тд...|и тд......|

Specflow предоставляет очень сильный инструмент - https://github.com/techtalk/SpecFlow/wiki/Step-Argument-Conversions
где вы можете КАК ДУШЕ угодно ивзращаться с входными данными метода. Хотите - таблицей передавайте, хотите - список. Хотите - джейсоном и прочее.

Я портнул sbtqa PageFactory framework на C# (если вы знакомы с ним - он позволяет уменьшить количество самописных шагов в мульон раз), убрав оттуда весь лишний хлам на мой взгляд, включая мобильный драйвер ибо мне это не нужно было, можете посмотреть - https://github.com/Noksa/AAA/

Core шаги лежат тут: https://github.com/Noksa/AAA/blob/master/AT-Core-Specflow/Hooks/CoreSteps.cs

Шаги действий на блоках/страницах тут: https://github.com/Noksa/AAA/blob/master/AT-Core-Specflow/Core/BasePage.cs

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

Можете посмотреть, что к чему.


(vmaximv) #36

Это не BDD - это Keyword-driven.


(Никита Масловский) #37

Объясни, что не так?


(vmaximv) #38

Вы же сами посылали в гугл по этому вопросу.

Начните с https://en.wikipedia.org/wiki/Object-oriented_analysis_and_design и https://en.wikipedia.org/wiki/Domain_Specific_Language.

Если грубо и на пальцах - сценарий должен быть написан на high level dsl и должен описывать поведение системы. А в вашем варианте исполнения - это просто круглый тест-кейс запихнутый в квадратный BDD.


(Никита Масловский) #39

Gherkin сам по себе является High Levele DSL языком.


(vmaximv) #40

Вы серьезно считаете языком семантические конструкции из 3-4 keywords?


(Никита Масловский) #41

Предлагаю просто обратиться к автору.


(vmaximv) #42

Давайте:
https://docs.cucumber.io/bdd/better-gherkin/

Все это уже жевано-пережевано много лет назад.