agentleFS
apacheapache/fineract/.agents/skills/fineract-testing/SKILL.md

fineract-testing

Skill2.6k starsChanged 13 days agoApache-2.0View on GitHub

Choose, write, run and verify tests for Apache Fineract changes, covering JUnit unit tests, the fineract-provider Cucumber tests, Feign-client integration tests, the two-factor and OAuth2 suites, and Cucumber E2E scenarios. Use when adding or changing tests, when a code change needs test coverage, when a test fails, or before claiming that a change works.

We split this skill into the rules it gives an agent

16 rules. About 0 are common, 3 are distinctive, and 13 are very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈3

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 13

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use JUnit Jupiter, with Mockito through @ExtendWith(MockitoExtension.class), as the example in rule 2 does.

    line 27
  2. Very specific:

    Run one class with ./gradlew :<module>:test --tests <ClassName>.

    line 39
  3. Very specific:

    If your class needs its own @BeforeAll, give it a new name.

    line 57
  4. Very specific:

    Never import io.restassured, and never add a file to config/checkstyle/restassured-baseline.xml: the FeignNoRestAssured check in …

    line 63
  5. Very specific:

    If the generated model lacks a field, add it to the matching *ApiResourceSwagger class and regenerate both clients.

    line 68
  6. Distinctive:

    Keep each test class self-contained, and undo any global configuration you change.

    line 76
  7. Very specific:

    Put scenarios in a .feature file under fineract-e2e-tests-runner/src/test/resources/features and step definitions under …

    line 94
  8. Very specific:

    Use @TestRailId:C<number> only for an existing TestRail case, because results are posted to that case …

    line 110
  9. Distinctive:

    If there is none, ask in the PR rather than guessing.

    line 113
  10. Very specific:

    Start a server first. For the integration suites, use the Docker stack in CONTRIBUTING.md, "Integration tests", which CI also uses.

    line 117
  11. Very specific:

    Run the tests you added or changed against that server.

    line 120
  12. Distinctive:

    If a test fails, run it at the base commit before blaming your change (IT-20).

    line 122
  13. Very specific:

    Check the report for skipped tests.

    line 124
  14. Very specific:

    If Gradle reports the test task as UP-TO-DATE or FROM-CACHE, the tests did not run.

    line 126
  15. Very specific:

    Before pushing, run ./gradlew spotlessApply and the checks in .github/workflows/build-quality-checks.yml that your change touches …

    line 128
  16. Very specific:

    Follow CONTRIBUTING.md, "Pull Requests".

    line 134

≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Fineract Testing

Paths are relative to the repository root, and .adoc names refer to fineract-doc/src/docs/en/chapters/testing/. Each rule below comes from the file or check named next to it; if this skill and that source disagree, the source wins.

Choose the suite

SuiteWhere the tests liveNeeds a running serverGuide
Unitsrc/test/java of the module you changedNoCONTRIBUTING.md, "Unit tests"
Cucumber in fineract-providerfineract-provider/src/test/resources/featuresNo.github/workflows/build-cucumber.yml
Integrationintegration-testsYesintegration.adoc, integration-feign.adoc
Two-factor, OAuth2twofactor-tests, oauth2-testsYes, started in that auth modeintegration.adoc, "Authentication modes"
Cucumber E2Efineract-e2e-tests-runner (features), fineract-e2e-tests-core (steps)Yescucumber.adoc

The build never starts a server. Start one before running any suite marked "Yes", or every API call fails (CONTRIBUTING.md, "How to run tests").

Unit tests

  1. Use JUnit Jupiter, with Mockito through @ExtendWith(MockitoExtension.class), as the example in rule 2 does. The modules exclude the JUnit 4 vintage engine (for example fineract-provider/dependencies.gradle), so a JUnit 4 @Test never runs.
  2. Code that reads the tenant or the business date needs the thread context. Set it in @BeforeEach and clear it with ThreadLocalContextUtil.reset() in @AfterEach. Money also needs the tenant's rounding mode, which sits in a static cache that reset() does not clear: set it with MoneyHelper.initializeTenantRoundingMode and remove it with MoneyHelper.clearCacheForTenant, as fineract-working-capital-loan/src/test/java/org/apache/fineract/portfolio/workingcapitalloan/service/WorkingCapitalLoanAsOfBalanceReadServiceImplTest.java does.
  3. Let exceptions propagate instead of catching them. To test a failure, use assertThrows, not @Test(expected = ...) (CONTRIBUTING.md, "Error Handling").
  4. Run one class with ./gradlew :<module>:test --tests <ClassName>. The command for the whole fast suite is in CONTRIBUTING.md, "Unit tests". If you changed fineract-provider, also run ./gradlew :fineract-provider:cucumber, because test does not run its features.

Integration tests

New integration tests call the server through the generated Feign client. Read rules IT-01 to IT-20 in integration-feign.adoc before writing one.

  1. Extend the base class for the product under test: FeignLoanTestBase, FeignSavingsTestBase, FeignWorkingCapitalTestBase or FeignDepositTestBase in integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/, otherwise FeignIntegrationTest one directory up.
  2. The loan and savings bases register LoanTestLifecycleExtension and FeignSavingsLifecycleExtension. Before and after every test, these close, un-approve or reject every open loan or savings account in the tenant, so create accounts inside each test, not in @BeforeAll.
  3. If your class needs its own @BeforeAll, give it a new name. Reusing the base method's name (setupHelpers, setupSavingsHelpers, setupWorkingCapitalHelpers, setupDepositHelpers) hides it, and the base helpers are never set up.
  4. Make calls through FeignCalls (ok, executeVoid, fail, failVoid) from fineract-client-feign/src/main/java/org/apache/fineract/client/feign/util/FeignCalls.java, and assert the exact status and error code of a failure (IT-02, IT-10).
  5. Never import io.restassured, and never add a file to config/checkstyle/restassured-baseline.xml: the FeignNoRestAssured check in config/checkstyle/checkstyle.xml fails the build. A test you migrate off REST Assured deletes its baseline entry in the same change (integration-feign.adoc, "The Baseline").
  6. If the generated model lacks a field, add it to the matching *ApiResourceSwagger class and regenerate both clients. Do not work around it in the test (IT-05, "Fixing a Generated Model at Source").
  7. For anything that depends on the date, run the steps inside runAt(date, ...). The loan, savings and working capital bases provide it; elsewhere, call runAt on a FeignBusinessDateHelper (integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/helpers/FeignBusinessDateHelper.java). It turns the business date on, sets it, and turns it off again afterwards.
  8. Keep each test class self-contained, and undo any global configuration you change. CI splits test classes across shards on each of PostgreSQL, MySQL and MariaDB (.github/workflows/build-postgresql.yml and its MySQL and MariaDB variants), so no class can rely on another one having run.

Keep the default lists in sync

Some tests compare the database with a list kept by hand. When your change adds one of these, update the list in the same change:

When you addAlso updateOtherwise this fails
A global configuration (c_configuration row)GlobalConfigurationHelper.getAllDefaultGlobalConfigurations() in integration-tests/src/test/java/org/apache/fineract/integrationtests/common/GlobalConfigurationHelper.javaTests that reset global configurations, such as GlobalConfigurationTest
A scheduler job (JobName value)Its job row, inserted by a Liquibase changesetSchedulerJobsTest, which compares the two counts
An external business event typeExternalEventConfigurationTestData in integration-tests/src/test/java/org/apache/fineract/integrationtests/client/feign/modules/ExternalEventConfigurationIntegrationTest

Cucumber E2E scenarios

  1. Put scenarios in a .feature file under fineract-e2e-tests-runner/src/test/resources/features and step definitions under fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/stepdef (cucumber.adoc, "Writing New E2E Tests").
  2. On a fresh database, run once with INITIALIZATION_ENABLED=true to create the products and charges the scenarios expect, and enable the business date (cucumber.adoc, "Test Data Initialization" and "Business Date Configuration").
  3. From fineract-e2e-tests-runner, run one feature with ../gradlew cucumber -Pcucumber.features="src/test/resources/features/<Name>.feature", and filter with -Pcucumber.tags. A filter that matches nothing reports 0 scenarios and still exits 0, so read the summary line (integration.adoc, "The WAR deployment").
  4. Event assertions are skipped unless EVENT_VERIFICATION_ENABLED=true. E2E CI sets it and runs ActiveMQ (.github/workflows/build-e2e-tests.yml, docker-compose-postgresql-test-activemq.yml), so a local run without it does not check events.
  5. Use @TestRailId:C<number> only for an existing TestRail case, because results are posted to that case (fineract-e2e-tests-core/src/test/java/org/apache/fineract/test/testrail/TestRailClient.java). If there is none, ask in the PR rather than guessing.

Run and verify

  1. Start a server first. For the integration suites, use the Docker stack in CONTRIBUTING.md, "Integration tests", which CI also uses; that section also covers running without Docker. For E2E, see the previous section.
  2. Run the tests you added or changed against that server. Compiling and spotlessCheck are not verification (IT-18).
  3. If a test fails, run it at the base commit before blaming your change (IT-20). If your change touches server code, rebuild and restart the server at the base commit too.
  4. Check the report for skipped tests. Some fineract-provider tests are skipped, not failed, when Docker is not running (@Testcontainers(disabledWithoutDocker = true)).
  5. If Gradle reports the test task as UP-TO-DATE or FROM-CACHE, the tests did not run. Add --rerun-tasks (CONTRIBUTING.md, "How to run tests").
  6. Before pushing, run ./gradlew spotlessApply and the checks in .github/workflows/build-quality-checks.yml that your change touches (Checkstyle, Spotless, SpotBugs, RAT, Javadoc).

Flaky tests

Follow CONTRIBUTING.md, "Pull Requests". First rule out your own change ("Run and verify", step 3). Search JIRA for the test; if there is no report, file one and link it to FINERACT-850. Propose @Disabled // TODO FINERACT-NNNN only when comments show the test failing in at least 3 past PRs, and only in a separate PR.

Download now (ZIP)

Trending

More talk lately.about the whole repository

Dec 2025: 0 mentionsJan 2026: 1 mentionFeb 2026: 1 mentionMar 2026: 1 mentionApr 2026: 0 mentionsMay 2026: 3 mentionsJun 2026: 2 mentionsJul 2026: 3 mentionsAug 2026: 6 mentionsSep 2026: 3 mentionsOct 2026: 13 mentionsNov 2026: 0 mentions
Dec 2025Jun 2026Nov 2026
Mentions a month of the apache/fineract repository that our weekly crawl found. There is no adoption data for this file yet.

Who's talking about apache/fineract

The biggest 5 of 54 mentions linking to the repository that our crawl found. Each line is their own headline.

See all 54

Talked about on GitHub, Hacker News and Stack Overflow (54 times).

On GitHub · 50

45 more on GitHub

On Hacker News · 2

On Stack Overflow · 2

  • In this repositoryOne other file it gives its agents.

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

Reviews can't be read right now.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.