Skip to main content

write-tests

Use when writing, fixing or reviewing DocApply tests, whether server JUnit resource tests under src/test/java or client Vitest specs under src/test/webapp, or when a test fails locally or in CI.

来源信息

仓库
ls1intum/doc-apply
最近来源活动
2026年9月30日 17:51
检测到的 SKILL.md 语言
英语
星标
2
分支
4

安装方式

默认使用会先检查来源的 Prompt;你也可以切换为直接命令,或下载本地副本。

检查来源文件

决定是否安装前,请先阅读 SKILL.md,以及 SkillsMP 当前展示的配套文件。

正在显示 SKILL.md

SKILL.md
来源说明 · 只读预览
name
write-tests
description
Use when writing, fixing or reviewing DocApply tests, whether server JUnit resource tests under src/test/java or client Vitest specs under src/test/webapp, or when a test fails locally or in CI.
# Write tests The full guidelines are [server-tests.mdx](../../../docs/docs/developer/server-guidelines/server-tests.mdx) and [client-tests.mdx](../../../docs/docs/developer/client-guidelines/client-tests.mdx). Both test trees mirror the source package structure. ## Server (JUnit 5, AssertJ, Testcontainers MySQL) Docker must be running; tests start their own MySQL container. ### Where tests go - Test at the resource layer: `<module>/web/rest/<Name>ResourceTest.java`, extending `de.tum.cit.aet.AbstractResourceTest`. - Do not add `*ServiceTest` classes. Service behaviour is covered through the endpoint that uses it. A few legacy service tests exist; do not extend them. - Architecture rules live in `DTOArchitectureTest` and `TechnicalStructureTest`. ### Building blocks | Need | Use | | -------------------- | ------------------------------------------------------------------------------------------------- | | Clean state per test | `@Autowired DatabaseCleaner databaseCleaner;` then `databaseCleaner.clean()` in `@BeforeEach` | | Test data | `utility/testdata/*TestData` factories, e.g. `UserTestData.savedProfessor(userRepository, group)` | | HTTP calls | `@Autowired MvcTestClient api;` with `getAndRead`, `postAndRead`, `putAndRead`, `deleteAndRead` | | Authenticated user | `api.with(JwtPostProcessors.jwtUser(user.getUserId(), "ROLE_PROFESSOR"))` | | Mock a collaborator | `Mockito.mock(...)` plus `ReflectionTestUtils.setField(...)`, not `@MockitoBean` | If no factory method fits, add one to the closest `*TestData` class with JavaDoc. ### Rules - Name tests `should<ExpectedBehavior>When<StateUnderTest>` and group them with `@Nested`. - Use the most specific AssertJ assertion: `assertThat(list).hasSize(1)`, not `assertThat(list.size()).isEqualTo(1)`. - Use deterministic data and IDs returned by the database. Never hardcode IDs. - Cover the authorization cases: the owner, another user of the same role, and a role that must get `403`. - Never put `@MockitoBean`, `@MockitoSpyBean`, `@TestPropertySource`, `@ActiveProfiles`, `@DirtiesContext`, `@ContextConfiguration` or `@Import` on a concrete test class. Each one starts another Spring context. Shared setup belongs in the abstract base class. - Do not use `@Isolated`. Tests run in parallel and must not share mutable state. ### Commands ```bash ./gradlew test --tests 'RatingResourceTest*' -x webapp # one class, including @Nested classes ./gradlew test -DincludeTags='ArchitectureTest' -x webapp # architecture tests ./gradlew test jacocoTestReport -x webapp # all tests plus coverage open build/reports/jacoco/test/html/index.html ``` CI also runs `./gradlew spotlessCheck -Pprod` and `./gradlew checkstyleMain -x webapp -Pprod`. ## Client (Vitest, ng-mocks) Specs live in `src/test/webapp/app/...`, mirroring `src/main/webapp/app/...`. Shared helpers are in `src/test/webapp/util/`. ### What to test - Test observable behaviour: user interactions, output emissions, branches, computed signals, HTTP requests and error paths, validators, pure utilities. - Do not write `should create` or `toBeTruthy()` existence tests, styling or class-presence checks, getter or setter round-trips, or tests that only check a default value. Delete them when you touch a file that has them. - Collapse three or more similar tests into one `it.each` table. ### Rules - Every `it(...)` title starts with `should`. - Mock dependencies individually with `MockComponent`, `MockPipe`, `MockDirective` and `MockProvider`. Never import full modules, never use `NO_ERRORS_SCHEMA` or `overrideTemplate()`. - Create mocks inside `beforeEach`, not at module scope, so call counts do not leak between tests. After the first `fixture.detectChanges()`, `await fixture.whenStable()` and `vi.clearAllMocks()` if initialization calls would pollute assertions. - Clean up in `afterEach`: `httpMock.verify()` when using `HttpTestingController`, and `vi.restoreAllMocks()`. - Prefer `toHaveBeenCalledOnce()` over `toHaveBeenCalled()` or `toHaveBeenCalledTimes(1)`. - Vitest has no `toBeTrue()` or `toBeFalse()`. Use `toBe(true)` and `toBe(false)`. - Production style rules apply to specs: no object or array spread, no `as any`. Reach private members with `component['member']`; for a typed view use `as unknown as <Type>`. ### Commands ```bash pnpm exec vitest run src/test/webapp/app/path/to/thing.spec.ts # one spec pnpm run test # all specs plus coverage pnpm run test:ci # with CI thresholds pnpm run compile:ts:tests # type-check specs pnpm run prettier:check # format gate for specs ``` ESLint ignores `src/test/webapp/**`, so Prettier and `compile:ts:tests` are the only CI gates on spec style and types. Run both before pushing. ## CI failures | Symptom | Fix | | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------ | | Server coverage below 60% lines, 32% branches | Add resource-level tests for the changed endpoints; check `build/reports/jacoco/test/html/index.html`. | | Client coverage below 50/40/50/50 | Add behaviour tests for the changed code; check `build/test-results/vitest/coverage/index.html`. | | Server tests slow, many context starts in logs | A concrete test class added a context-changing annotation. Move it to the base class. | | Test passes alone, fails in the suite | Shared state. Clean the database in `@BeforeEach`, or move client mocks into `beforeEach`. |
在 GitHub 查看