Порядок и структуризация тестов или как написать код правильно?!

Добрый день,
Вопрос у меня более-менее общий, поэтому создал его в разделе “Общие вопросы”

Прошу поставить на путь истинный.

Начнем с того, что тест в моем понимании, это набор каких-то шагов - сценарий.

Представим следующий тест:
Логинимся на страницу.
Проверяем, что тайтл как ожидаем.
Заходим в аккаунт
Меняем пароль.
Смотрим, что появилось сообщение об успехе.
Выходим.

Я представляю это, как класс, с набором шагов, т.е.:

public class DemoTest(){
	
	@BeforeClass
	public void openPageAndLogin(){
		somePage.open();
		somePage.Login();
	}
	
	@Test
	public void doesPageTitleAsExpectedAfterLogin(){
		Assert.assertEquals(somePage.getTitle, "SomePage Title after Login");
	}
	
	@Test
	public void doesSuccessMsgAppearAfterPasswordChange(){
		somePage.openAccount();
		somePage.changePassword();
		Assert.assertEquals(somePage.getSuccessPwdChangeMsg(), "Some success msg");
	}
	
	@AfterTest
	public void logOut(){
		somePage.logOut();
	}
}

Пример набран на коленке, поэтому строго не судите.
Вот этот класс DemoTest является в моём представлении тестом (что может быть в корне не верным).
Соответственно он абсолютно независим от других тестов.

Но вопрос в том, как упорядочить шаги. Допустим мне кровь из носа надо, чтобы первым прошла проверка тайтла.
Сейчас я решаю подобные проблемы использованием параметра priority.
Таким образом, шаги получаются более-менее независимыми друг от друга, и если один упадет, то следующий все равно запустится.

Вопросы у меня следующие:

  1. Насколько я ошибаюсь в классификации - класс это тест с шагами.
  2. Как правильно упорядочивать тесты?
  3. Как группируете тесты Вы?

На вопрос сподвигло очень частое упоминание, что один класс чуть ли не один шаг. Но в рамках ГУИ мне это представляется не совсем возможным.
А так же, что не должно быть никаких зависимостей (я в этом плане полностью согласен, но лишь отталкиваясь от: класс - тест с шагами)
Вопросы теоретические, т.е. как оно практикуется и как должно быть (Хотя бы в теории)

Общепринято, что метод с аннотацией @Test == Тест_Кейс, класс с Тест_Кейсами == Тест_Сьют/Часть_Тест_Сьюта.

А можно примеры/источники?

1 лайк

форумы, вэб, надо искать. Возможно где-то и здесь проскакивало.

А зачем разделять данный код не несколько аннотаций, посудите сами, если не отработает openPageAndLogin(), то и doesPageTitleAsExpectedAfterLogin() то же не пройдет, так же само как и doesSuccessMsgAppearAfterPasswordChange(), и тем более logOut() (как минимум NoSuchElementException), данный код это одна аннотация Test.
В моем видении это можно построить так:

    public class DemoTest(){

@Test
public void userCanChangePassword(){
	somePage.open();
            Assert.assertTrue(somePage.isOpen(), "Failed to open some page");
	somePage.Login();
	Assert.assertTrue(somePage.isLogined(), "Failed to login user");
	somePage.openAccount();
            Assert.assertTrue(somePage.isAccountOpen, "Failed to open account");
	somePage.changePassword();
	Assert.assertEquals(somePage.isPasswordChanged(), "Failed to change password");

}

А уже в классе SomePage, порекомендую использовать аннотации Step, из Allure.
Рекомендую посмотреть это видео, там наглядно показано как можно грамотно построить свои тесты

2 лайка

Класс, в его истинном обличии, характеризуется набором свойств и поведений. Под поведением обычно подразумевают метод. Если рассматривать класс, как тест кейс, то что в этом случае будет являться его методом? Шаг тест кейса? Unit framework’и под тестами подразумевают набор степов внутри метода. Что по сути уже противоречит вашей концепции.

Логическое разделение функциональности можно организовать посредством пакетов - packages.

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

Методами же тут будут являться: createEntity / editEntity / deleteEntity.

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

Целые suites могут быть представлены в качестве регрессионного или смоук набора для проверки необходимой функциональности.

1 лайк

В принципе выше уже ответили, но я тоже допишу

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

Такой подход как раз позволяет сделать тесты:

  • читабельными
  • независимыми
  • атомарными (в масштабе проверок, один тест - одна проверка)

Правильно их не упорядочивать. Описанный выше подход автоматически решает проблему упорядочивания. Впоследствии, конечно, будут возникать желания добавит зависимость тестам, но всё это можно решить другими методами (DDT, использование test fixture, созданием зависимостей внутри самого теста и т.д.)

Внутри класса тесты группируются по смыслу. Например, все тесты для некоторой фичи, или компонента. Тут важно соблюдать баланс и не пихать в один класс слишком много (> 30) тестов. Лучше их ещё как-то разбить и сгруппировать по отдельным классам. Классы группируются в packet-ы (Java) или namespace-ы (C#). TestNG позволяет ещё добавлять свои группы, что может быть очень удобным для сквозной группировки тестов из разных сьютов, например, по важности, group = “P1”. И т.д.

2 лайка

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