К основному содержанию
правило официальный · GitHub

java-junit5-assertions — правило для GitHub Copilot

Правило задаёт единый стиль для JUnit 5: проверки исключений, группировка assertAll, ленивые сообщения и контроль времени выполнения.

Установить в GitHub Copilot · Вручную: положить файлы Все способы и платформы ↓
.github/instructions/java-junit5-assertions.instructions.md
Открыть на GitHub

Что делает java-junit5-assertions

Правило применяется к файлам **/*Test.java, **/*IT.java, **/*Steps.java и **/*StepDefs.java. Оно задаёт порядок аргументов в assertEquals, советует явные статические импорты и требует delta для сравнений чисел с плавающей точкой.

Для нескольких свойств одного объекта используется assertAll, для точного типа исключения — assertThrowsExactly, а для проверки типа результата — assertInstanceOf. Сложные сообщения об ошибках передаются через Supplier<String>, чтобы не собирать их при успешной проверке. Есть правила для assertDoesNotThrow, assertIterableEquals, assertArrayEquals и таймаутов.

Правило сохраняет стиль AssertJ в проектах, где он уже принят, и не смешивает JUnit 4 с JUnit 5. assertTimeoutPreemptively запускает код в отдельном потоке, поэтому ThreadLocal и состояние @Transactional не передаются.

Какие задачи решает

  • проверить порядок expected и actual в assertEquals
  • сгруппировать проверки объекта через assertAll
  • проверить исключение с точным типом
  • сравнить коллекции и массивы специализированными assertions
  • задать таймаут для долгой операции

Примеры запросов агенту

  • Проверь тесты в **/*Test.java и исправь порядок аргументов в assertEquals.
  • Перепиши проверки объекта через assertAll, сохрани текущий стиль AssertJ.
  • Добавь точную проверку исключения и таймаут для теста долгой операции.

Как установить java-junit5-assertions

Вручную: положить файлы

.github/instructions/java-junit5-assertions.instructions.md

Поле applyTo задаёт, к каким файлам применять

По шагам, с командами для каждой платформы: AGENTS.md и CLAUDE.md: что это, кто читает и какой выбрать

Вопросы о java-junit5-assertions

Как установить java-junit5-assertions в GitHub Copilot?

Создайте файл .github/instructions/java-junit5-assertions.instructions.md и поместите в него содержимое правила.

Что делает java-junit5-assertions?

Правило стандартизирует проверки JUnit 5: импорты, сравнения, исключения, группировку assertions, типы результатов и таймауты.

Что произойдёт с @Transactional при assertTimeoutPreemptively?

Код выполняется в отдельном потоке, поэтому состояние ThreadLocal, включая @Transactional, не передаётся.

Исходный текст

java-junit5-assertions.instructions.md · MIT
---
description: "Standardizes JUnit 5 (Jupiter) assertions with best practices for performance, readability, and modern features (5.8+). Covers Supplier messages, assertAll, assertThrowsExactly, and performance-critical timeouts."
applyTo: "**/*Test.java, **/*IT.java, **/*Steps.java, **/*StepDefs.java"
---

# JUnit 5 Assertions Best Practices

Follow these best practices when writing, reviewing, or refactoring Java test code with JUnit Jupiter (JUnit 5 and JUnit 6; the `org.junit.jupiter.api.Assertions` API used here is the same in both). These rules focus on test accuracy, performance (lazy evaluation), and leveraging modern Jupiter features.

If the project already standardizes on AssertJ, follow that instead for new assertions and keep these rules for Jupiter-style tests. Never rewrite a project's existing assertion style just to match this file. See the `java-junit` skill for the wider testing guidance.

## 1. Imports

Prefer static imports for assertions to reduce boilerplate. Unless your team conventions dictate otherwise, prefer explicit imports over wildcard (`*`) imports.

```java
// ❌ BAD — verbose and clutters the test method
Assertions.assertEquals(expected, actual);

// ❌ BAD — wildcard import (unless standard in your team)
import static org.junit.jupiter.api.Assertions.*;

// ✅ GOOD — explicit static import
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

assertEquals(expected, actual);
```

> **Best for**: Improving readability and keeping test methods focused on logic. Always import from `org.junit.jupiter.api.Assertions`.

## 2. assertEquals — Expected Value First

`expected` is always the **first** argument, `actual` is always **second**.

```java
// ❌ BAD — swapped; failure message is misleading
assertEquals(calculator.add(1, 1), 2);

// ✅ GOOD
assertEquals(2, calculator.add(1, 1));

// ✅ GOOD — floating point: always provide a delta
assertEquals(0.3, 0.1 + 0.2, 1e-9);
```

> **Best for**: Ensuring failure logs correctly report "Expected [X] but was [Y]".

## 3. Failure Messages — Supplier vs String

Pass failure messages as a `Supplier<String>` when the message construction is expensive (e.g., string formatting or complex object inspection).

```java
// ❌ BAD — expensive message constructed even when the assertion passes
assertEquals(expected, actual, "Expected %s but got %s".formatted(expected, actual));

// ✅ GOOD — evaluated only on failure (Lazy evaluation)
assertEquals(expected, actual,
    () -> "Expected %s but got %s".formatted(expected, actual));

// ✅ GOOD — simple, constant string literal (zero overhead)
assertTrue(isActive, "User account must be active");
```

> **Best for**: Performance-critical test suites and complex diagnostic messages.

## 4. assertAll — Group Related Assertions

Use `assertAll` when checking multiple properties of the same result. All assertions run even if earlier ones fail.

```java
// ❌ BAD — stops at first failure; other properties go unchecked
assertEquals("Jane", person.firstName());
assertEquals("Doe",  person.lastName());

// ✅ GOOD
assertAll("person",
    () -> assertEquals("Jane", person.firstName()),
    () -> assertEquals("Doe",  person.lastName()),
    () -> assertEquals(30,     person.age())
);
```

> **Best for**: Comprehensive object state verification and avoiding "partial failure" ambiguity.

## 5. Exception Testing — assertThrows vs assertThrowsExactly

`assertThrows` returns the exception for further verification. Use `assertThrowsExactly` for strict type matching.

```java
// ✅ assertThrows — passes if thrown type IS-A expected type (subclasses accepted)
ArithmeticException ex = assertThrows(
    ArithmeticException.class,
    () -> calculator.divide(1, 0)
);
assertEquals("/ by zero", ex.getMessage());

// ✅ assertThrowsExactly — passes ONLY if type matches EXACTLY (JUnit 5.8+)
assertThrowsExactly(IllegalArgumentException.class, () -> {
    throw new IllegalArgumentException("invalid");
});
```

> **Best for**: `assertThrows` for general hierarchy testing; `assertThrowsExactly` when the precise implementation class is part of the API contract.

## 6. assertDoesNotThrow

Use when the absence of an exception is the explicit contract being tested.

```java
// ✅ GOOD — captures and returns the result for further assertions
int result = assertDoesNotThrow(() -> service.calculate(data));
assertEquals(100, result);
```

> **Best for**: Explicitly documenting that a specific edge case should not trigger an error.

## 7. Performance & Deadlines — assertTimeout

Use `assertTimeout` to ensure execution completes within a limit. Use `assertTimeoutPreemptively` only when hard-abortion is required.

```java
// ✅ assertTimeout — waits for completion, then checks duration
assertTimeout(Duration.ofSeconds(1), () -> service.heavyTask());

// ⚠️ assertTimeoutPreemptively — hard-aborts at deadline (Separate thread)
// Warning: ThreadLocal state (@Transactional) does NOT propagate.
assertTimeoutPreemptively(Duration.ofMillis(500), () -> service.fastTask());
```

> **Best for**: SLA verification and preventing hanging tests in CI/CD pipelines.

## 8. Type Safety — assertInstanceOf

Prefer `assertInstanceOf` (JUnit 5.8+) over `assertTrue` + `instanceof` to get automatic casting.

```java
// ❌ BAD — requires manual cast after assertion
assertTrue(result instanceof SuccessResponse);

// ✅ GOOD — returns the casted object
SuccessResponse resp = assertInstanceOf(SuccessResponse.class, result);
assertEquals(200, resp.statusCode());
```

> **Best for**: Testing polymorphic results and reducing boilerplate casting.

## 9. Collections and Arrays

Use dedicated assertions for deep comparison and informative diffs.

```java
// ✅ assertIterableEquals — element-by-element deep diff on failure
assertIterableEquals(expectedList, actualList);

// ✅ assertArrayEquals — deep comparison for arrays
assertArrayEquals(expectedArray, actualArray);
```

> **Best for**: Verifying list order and complex data structure contents.

## 10. Anti-Patterns

- **Misusing `assertTrue` for Equality:** Do not use `assertTrue(result == 42)`. Use `assertEquals(42, result)` to see both values in logs.
- **Substituting `assertNotNull` for real checks:** Don't just check for null if you can check the value. `assertEquals(expected, result)` is always better than `assertNotNull(result)`.
- **Suppressing Failures:** Never catch `AssertionError` to hide a failure.
- **Legacy Imports:** Do not mix `org.junit.Assert` (JUnit 4) with JUnit 5 tests.

© github · MIT · github/awesome-copilot

Похожие правила IDE

Все правила IDE по теме «Языки программирования» →

Из того же набора928

Весь набор →
joyride-workspace-automation Настраивает GitHub Copilot для интерактивной автоматизации VS Code на ClojureScript через Joyride. Помогает писать проектные скрипты через REPL прямо внутри редактора. ★ 40 451звёзд репо joyride-user-project Правило помогает разрабатывать проекты Joyride на ClojureScript через REPL и автоматизировать VS Code. Оно пригодится, когда нужно проверить код в среде VS Code до правок файлов. ★ 40 451звёзд репо java-upgrade Правило подсказывает Copilot подключить скилл java-upgrade, когда вы меняете версию Java в Maven или Gradle. Пригодится при переходе между LTS. ★ 40 451звёзд репо java-mcp-server Набор инструкций для разработки MCP-серверов на Java с официальным MCP Java SDK 2.x. Помогает настроить сборку, транспорт и регистрацию инструментов. ★ 40 451звёзд репо intellij-java-kotlin Правило задаёт Copilot рамки работы с Java и Kotlin в IntelliJ IDEA: сборка через Gradle или Maven, аккуратные правки и проверка теми же командами, что в CI. ★ 40 451звёзд репо instructions Свод правил и структура для создания качественных файлов инструкций Copilot с привязкой по glob-маскам. ★ 40 451звёзд репо html-css-style-color-guide Правило задаёт ограничения и рекомендации для цветового оформления HTML и CSS. Помогает выбирать фоны, текстовые цвета и градиенты с учётом контраста. ★ 40 451звёзд репо hooks Правило-инструкция для GitHub Copilot о том, как писать хуки: конфиг в .github/hooks/, скрипты на Bash и PowerShell, коды выхода и запрет действий. ★ 40 451звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой