How the tests work - papito/altitude GitHub Wiki

There are three kinds of tests that run with make test:

  • Integration (service-level, database-backed)
  • Controller (web interface)
  • Unit (models, functions)

All of these can run individually, to save time - see the Makefile for actual commands.

Each test can run individually if it's tagged as Focused, as in:

test("Upload with multiple files", Focused) {
  ...
}

Integration tests

Bundled in AllIntegrationTestSuites

The bundles run twice - for Sqlite and Postgres

Controller tests and the forced Postgres config

Bundled in AllControllerTestSuites

Controller tests run with the suite and the embedded Jetty app instance in Postgres mode.

Controller tests are challenging as it involves Scalatra test framework spinning up an embedded Jetty and its own servlet context before our tests even initialize. This calls for different setup/teardown patterns compared to service-level tests (the database needs to be reset before every test, for example).

The problem is with the embedded Jetty starting an app instance before we get to set up our code. While we can tell an integration test which DB engine to use, the separate servlet context grabs the default and runs with it. All of that compounds to making controller tests run under both DB engines within one sbt test command a pretty gnarly task, so the solution is to force the controller test bundle run once - under Postgres.

  1. On the server end, we set the default to Postgres for the database in test reference.conf. This takes care of the embedded Jetty process.

  2. The test bundle itself uses the db engine override

Making this work IS technically possible using Typescript Config ENV overrides and dark setup magic for the controller tests to work under both DBs, but it's a pretty big ask.

Auth with controller tests

This is tricky because we cannot use Mockito with a separate server process - our test thread cannot control that version of the code. What now? Do we log in a user for each request? That sounds cumbersome.

The solution is to use a custom Scentry strategy - TestRememberMeStrategy (it's wired in the Altitude app during init but only in TEST). The strategy reads special test-only headers that specify user and repository IDs, setting them in the request context when a login is required.

Unit tests

Bundled in AllUnitTestSuites

Miscellaneous

Why are all tests annotated with @DoNotDiscover?

Since we run the test suites via bundles, the tests themselves should not be visible to the test runner. Otherwise, the tests will run twice - separately and via a bundle they are in.