Зачем пользовательские проверки?
Встроенные проверки generic. assertEquals(expected, actual) работает для любого сравнения, но сообщение о падении лишено контекста. Пользовательские проверки добавляют доменный контекст: assertThat(user).isActive() выдаёт: Expected user "alice@example.com" to be active, but status was SUSPENDED.
Построение в Java
AssertJ Custom Assertions
public class UserAssert extends AbstractAssert<UserAssert, User> {
public UserAssert(User actual) { super(actual, UserAssert.class); }
public static UserAssert assertThat(User user) { return new UserAssert(user); }
public UserAssert isActive() {
isNotNull();
if (!actual.isActive()) {
failWithMessage("Expected user <%s> to be active but status was <%s>",
actual.getEmail(), actual.getStatus());
}
return this;
}
public UserAssert hasRole(String role) {
isNotNull();
if (!actual.getRole().equals(role)) {
failWithMessage("Expected user <%s> to have role <%s> but had <%s>",
actual.getEmail(), role, actual.getRole());
}
return this;
}
}
// Читается как спецификация
UserAssert.assertThat(user).isActive().hasRole("admin");
Пользовательские проверки в JavaScript
Playwright Custom Matchers
expect.extend({
async toBeLoggedIn(page) {
const isLoggedIn = await page.locator('.user-menu').isVisible();
return {
pass: isLoggedIn,
message: () => isLoggedIn
? 'Не ожидалось, что страница будет залогинена'
: 'Ожидалось, что страница залогинена, но меню пользователя не найдено'
};
},
});
await expect(page).toBeLoggedIn();
Мягкие проверки (Soft Assertions)
Стандартные проверки останавливают тест при первом падении. Мягкие собирают все падения и отчитываются в конце.
Java (AssertJ SoftAssertions)
@Test
void shouldValidateUserProfile() {
SoftAssertions softly = new SoftAssertions();
softly.assertThat(user.getName()).isEqualTo("Alice");
softly.assertThat(user.getEmail()).contains("@");
softly.assertThat(user.getRole()).isEqualTo("admin");
softly.assertThat(user.isActive()).isTrue();
softly.assertAll(); // Отчитывается обо ВСЕХ падениях
}
Playwright Soft Assertions
test('валидация элементов дашборда', async ({ page }) => {
await page.goto('/dashboard');
await expect.soft(page.locator('.welcome')).toHaveText('Welcome, Admin');
await expect.soft(page.locator('.stats')).toBeVisible();
await expect.soft(page.locator('.recent-orders')).toHaveCount(5);
});
Когда что использовать
| Тип | Когда | Пример |
|---|---|---|
| Встроенные | Простые сравнения | assertEquals(200, statusCode) |
| Пользовательские | Доменная валидация с понятными сообщениями | assertThat(user).isActive() |
| Мягкие | Валидация нескольких независимых свойств | Проверка всех полей профиля |
| Hamcrest | Сложные композиции условий | everyItem(hasProperty("active", is(true))) |
Упражнения
Упражнение 1: Доменные проверки
Создайте проверки для Order, напишите тесты, сравните сообщения с встроенными.
Упражнение 2: Сюита мягких проверок
Напишите тест, валидирующий 8 свойств мягкими проверками, внесите 3 падения, проверьте полный отчёт.
Упражнение 3: Playwright Custom Matchers
Создайте 3 кастомных матчера, используйте в e-commerce сюите, проверьте ясность сообщений.