Por Que Aserciones Personalizadas?
Las aserciones incorporadas son genericas. assertEquals(expected, actual) funciona para cualquier comparacion, pero el mensaje de falla carece de contexto. Las aserciones personalizadas agregan contexto de dominio: assertThat(user).isActive() produce: Expected user "alice@example.com" to be active, but status was SUSPENDED.
Construyendo Aserciones Personalizadas en 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;
}
}
// Se lee como una especificacion
UserAssert.assertThat(user).isActive().hasRole("admin");
Aserciones Personalizadas en JavaScript
Playwright Custom Matchers
expect.extend({
async toBeLoggedIn(page) {
const isLoggedIn = await page.locator('.user-menu').isVisible();
return {
pass: isLoggedIn,
message: () => isLoggedIn
? 'No se esperaba que la pagina estuviera logueada'
: 'Se esperaba que la pagina estuviera logueada, pero no se encontro el menu de usuario'
};
},
});
await expect(page).toBeLoggedIn();
Soft Assertions
Las aserciones estandar detienen la ejecucion en la primera falla. Las soft assertions recolectan todas las fallas y las reportan al final.
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(); // Reporta TODAS las fallas
}
Playwright Soft Assertions
test('validar elementos del dashboard', 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);
});
Cuando Usar Cada Tipo
| Tipo | Usar Cuando | Ejemplo |
|---|---|---|
| Incorporadas | Comparaciones simples | assertEquals(200, statusCode) |
| Personalizadas | Validacion de dominio con mensajes claros | assertThat(user).isActive() |
| Soft assertions | Validar multiples propiedades independientes | Verificar todos los campos de un perfil |
| Hamcrest matchers | Composiciones complejas de condiciones | everyItem(hasProperty("active", is(true))) |
Ejercicios
Ejercicio 1: Aserciones de Dominio
Crea aserciones personalizadas para una entidad Order, escribe tests usandolas, compara mensajes de falla.
Ejercicio 2: Suite de Soft Assertions
Escribe test que valide 8 propiedades con soft assertions, introduce 3 fallas, verifica que todas se reportan.
Ejercicio 3: Playwright Custom Matchers
Crea 3 matchers personalizados, usalos en suite de e-commerce, verifica claridad de mensajes de falla.