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.
-
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.
-
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.