Skip to content

Testing

Sigurd Evensen edited this page Apr 24, 2026 · 7 revisions

This Page describes how testing is applied in the HelpMeHelp JavaFX application.

Overview

The project uses JUnit 5 with Maven Surefire for automated testing. Tests run via mvn test.

Test Structure

src/test/java/edu/ntnu/idi/idatt1005/hmh/
├── MainTest.java                    # App startup and routing
├── util/
│   ├── UserDatabaseTest.java        # User DB initialization, auth, registration
│   ├── DonationDatabaseTest.java    # Donation persistence and seeding
│   └── HashingTest.java             # Password hashing (implicit via UserDatabaseTest)
├── registers/
│   └── OrganizationRegisterTest.java # HTML parsing for org metadata
└── ui/
    ├── LandingPageFiltersTest.java   # Filtering, sorting, tag parsing
    ├── DashboardPageViewMetricsTest.java # Dashboard aggregation logic
    └── ...                         # UI layout and component tests

Test-Driven Development (TDD)

The project follows a test-driven approach. Example from the dashboard implementation:

Step 1: Write failing tests first (TDD)

The plan shows failing tests first, then implementation to satisfy them:

@Test
void calculateTotalDonated_sumsValidAmountsAndSkipsInvalid() {
    List<Donation> donations = List.of(
        new Donation("Org A", "12/04/2026", "$100", "alice"),
        new Donation("Org B", "13/04/2026", "$12,5", "alice"),
        new Donation("Org C", "13/04/2026", "invalid", "alice")
    );
    assertEquals(112.5, DashboardPageView.calculateTotalDonated(donations));
}

Step 2: Run test class and verify it fails

Run: mvn -Dtest=DashboardPageViewMetricsTest test

Expected: FAIL because DashboardPageView and helper methods are not implemented yet.

Testing Patterns

1. Database Tests with Isolation

Uses @TempDir JUnit 5 annotation for isolated temp directories:

@TempDir
Path tempDir;

@Test
void initializeCreatesDatabaseAndSeedsDefaultDonations() throws Exception {
    Path databasePath = tempDir.resolve("nested").resolve("donations.db");
    DonationDatabase.initialize(databasePath.toString());
    assertTrue(Files.exists(databasePath));
    assertEquals(7, countRows(databasePath, "SELECT COUNT(*) FROM donations"));
}

2. Initialization Tests

Ensures initialization doesn't duplicate data on repeated runs:

@Test
void initializeIsIdempotentAndDoesNotDuplicateSeedRows() throws Exception {
    Path databasePath = tempDir.resolve("donations-idempotent.db");
    DonationDatabase.initialize(databasePath.toString());
    DonationDatabase.initialize(databasePath.toString());
    assertEquals(7, countRows(databasePath, "SELECT COUNT(*) FROM donations"));
}

3. UI Navigation Tests

Tests that UI components contain expected buttons/text:

@Test
void landingPageBuild_containsDashboardAndProfileButtonsInNavbar() {
    BorderPane root = LandingPageView.build(() -> {}, () -> {});
    List<String> labels = extractTopButtonLabels(root);
    assertTrue(labels.contains("Dashboard"));
    assertTrue(labels.contains("Profile"));
}

Testing Strategy

Dashboard

- Add focused unit tests for dashboard aggregation helpers:
  - total and average calculations
  - unique donor counting (case-insensitive)
  - top-3 organization ranking by donated amount
  - latest-date extraction with parseable/unparseable dates
- Add small routing test coverage in `MainTest` for new dashboard navigation methods where practical.
- Keep existing tests unchanged except where method signatures/callback contracts require updates.

Sorting

- Add/adjust unit tests for creation-date extraction behavior:
  - parses `dateCreated` from JSON-LD.
  - falls back to `datePublished` when needed.
  - returns `null` when no supported source exists.
- Add/adjust unit tests for newest-created sorting behavior:
  - newest date first.
  - null dates last.
  - alphabet tie-break for equal dates.
- Run `mvn test` after implementation.

Expanded descriptions

Manual verification:

1. Run `mvn javafx:run`.
2. Confirm collapsed list displays truncated descriptions consistently.
3. Click a card and verify full description appears.
4. Confirm expanded cards with longer descriptions become taller than others.
5. Click again and verify description returns to truncated state and donation controls hide.

Regression check:

- Existing search/filter behavior remains unchanged.
- Donation controls still work when expanded.

What Gets Tested

Area Test Approach
Database initialization Idempotency, seed data, migrations
Authentication Username/email login, password verification, hashing
Registration Duplicate rejection, profile creation
Organization parsing HTML scraping, date extraction, fallback behavior
Filtering/Sorting Tag parsing, alphabetical, popularity, newest
Dashboard metrics Aggregation, totals, unique donors, top orgs
Password security PBKDF2 hashing format, verification
UI navigation Button presence, routing callbacks

What Is NOT Automatically Tested

  • Manual UI verification (manual testing in specs)
  • Network/API integration (relies on live network, graceful fallback)
  • Visual layout pixel-perfect checks
  • End-to-end donation submission flow

Running Tests

# Run all tests
mvn test

# Run specific test class
mvn -Dtest=DashboardPageViewMetricsTest test

# Run with coverage (if configured)
mvn test -Dcoverage=true

Testing Approach

The testing approach emphasizes:

  1. Unit tests first — focused on isolated logic
  2. Failing tests before implementation — TDD approach
  3. Idempotency — safe to run multiple times
  4. Graceful degradation — tests verify default fallbacks work
  5. Manual verification — for UI/visual behavior not easily automated
Clone this wiki locally