

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
123456# Backend Testing Rules78Use this rule when creating or updating backend Java tests.910## Commands1112Run backend verification from the repo root:1314```bash15CURSOR_DEV=true nix develop -c pnpm backend:verify16```1718When no database migration is involved, this is faster:1920```bash21CURSOR_DEV=true nix develop -c pnpm backend:test_only22```2324Always run all backend unit tests instead of a selected file or test case.2526## Core Principles27281. Test behavior, not implementation. Verify system behavior through pre/post state transitions and keep tests resilient to internal structure changes.292. Prefer controller or other stable-boundary tests for behavior users see through HTTP. These tests often do not reference the internal class you edited.303. Do not mirror the package tree with one test class per production class. One observable test can cover several layers.314. Test services and algorithms directly only when they are an independent, intentional contract, such as pure logic or algorithms.325. Keep tests small and focused: one behavior per test and descriptive names that explain the behavior.3334Controller-style example:3536```java37@Test38void shouldBeAbleToSaveNoteWhenValid() throws UnexpectedNoAccessRightException {39 Note note = makeMe.aNote().creatorAndOwner(userModel).please();40 final NoteRealm noteRealm = controller.show(note);41 assertThat(noteRealm.getId(), equalTo(note.getId()));42}43```4445Independent algorithm example:4647```java48@ParameterizedTest49@CsvSource({50 "moon, partner of earth, partner of earth",51 "Sedition, word sedition means this, word [...] means this"52})53void clozeDescription(String title, String markdown, String expectedClozeDescription) {54 assertThat(55 new ClozedString(clozeReplacement, markdown).hide(new NoteTitle(title)).maskedContentAsMarkdown(),56 containsString(expectedClozeDescription));57}58```5960## Database Tests6162- Tests use actual database interactions with `@Transactional`.63- This gives confidence in database operations and repository behavior.6465```java66@SpringBootTest67@ActiveProfiles("test")68@Transactional69class RestNoteControllerTests {70 // ...71}72```7374## MakeMe Builders7576- Use the central `makeMe` factory to create test data.77- Each entity has its own builder, such as `NoteBuilder` or `ConversationBuilder`.78- Use method chaining for readability.79- End with `please()` to build the object.80- Use `please(boolean needPersist)` to control database persistence.81- Builders handle relationships and dependencies automatically.8283```java84Note note = makeMe.aNote()85 .creatorAndOwner(userModel)86 .titleConstructor("title")87 .content("description")88 .please();89```9091## Test Organization9293- Group related tests with `@Nested`.94- Use `@BeforeEach` for common setup, keeping setup minimal and relevant to the group.95- Initialize test data using MakeMe builders.96- Use mocking sparingly, mainly for external services.97- Mock `OpenAIClient` structured Responses output with `OpenAiStructuredResponseMock` in controller tests.9899```java100@Nested101class CreateNoteTest {102 Note parent;103 NoteCreationDTO noteCreation;104105 @BeforeEach106 void setup() {107 // ...108 }109110 @Test111 void shouldBeAbleToSaveNoteWhenValid() {112 // ...113 }114}115```116117## Assertions118119- Use `assertThat` with descriptive matchers for readable failures.120- Test both happy paths and error cases.121- Use `assertThrows` for exception testing.122- Use `@ParameterizedTest` for multiple scenarios with less code.123- Each test should create its own data and avoid sharing mutable state.124125```java126assertThat(noteRealm.getNote().getTopicConstructor(), equalTo(note.getTopicConstructor()));127assertThat(noteRealm.getFromBazaar(), is(true));128```129130```java131assertThrows(132 UnexpectedNoAccessRightException.class,133 () -> controller.show(note));134```135
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| nerds-odd-e/doughnut.cursor/rules/general.mdc · 49 | Cursor rules | styledo-not | 49/100 | 14 days ago | |
| nerds-odd-e/doughnut.clinerules/daisyui.md · 49 | Cline rules | setuplint-formatstyleui+1 | 57/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/architecture-decisions.mdc · 49 | Cursor rules | no sections | 16/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/backend-code.mdc · 49 | Cursor rules | styletypesdatabasedo-not | 61/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/cli.mdc · 49 | Cursor rules | setupbuildteststyle+4 | 96/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/db-migration.mdc · 49 | Cursor rules | stylearchdatabasedeployment | 64/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/e2e-authoring.mdc · 49 | Cursor rules | setupteststylearch+3 | 80/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/e2e-ocr.mdc · 49 | Cursor rules | setuptesting-strategydo-not | 46/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/frontend-api.mdc · 49 | Cursor rules | styletesting-strategyapido-not | 57/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/frontend-component.mdc · 49 | Cursor rules | testlint-formatstylearch+2 | 76/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/frontend-storybook.mdc · 49 | Cursor rules | buildteststyletesting-strategy+1 | 69/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/frontend-testing.mdc · 49 | Cursor rules | buildteststyletesting-strategy+2 | 89/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/gsd-coexistence.mdc · 49 | Cursor rules | style | 60/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/linting_formating.mdc · 49 | Cursor rules | testlint-formatstylearch+6 | 88/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/mcp-server.mdc · 49 | Cursor rules | buildtestlint-formatarch+2 | 85/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/planning.mdc · 49 | Cursor rules | teststylearchdo-not+1 | 75/100 | 14 days ago | |
| nerds-odd-e/doughnut.cursor/rules/script.mdc · 49 | Cursor rules | testarch | 58/100 | 14 days ago | |
| nerds-odd-e/doughnutAGENTS.md · 49 | AGENTS.md | no sections | 47/100 | 14 days ago | |
| nerds-odd-e/doughnutCLAUDE.md · 49 | CLAUDE.md | agent-behaviour | 47/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 46 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 14 days ago | |
| dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| markstev/mark-starter.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+6 | 99/100 | 14 days ago | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/20-hermes-api-tests.mdc · 46 | Cursor rules | teststyletesting-strategysecurity+3 | 97/100 | 14 days ago |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/nerds-odd-e-doughnut-cursor-rules-backend-testing)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.