diff --git a/docs/06-concepts/18-testing/02-the-basics.md b/docs/06-concepts/18-testing/02-the-basics.md index 68717d21..6c2fe9a9 100644 --- a/docs/06-concepts/18-testing/02-the-basics.md +++ b/docs/06-concepts/18-testing/02-the-basics.md @@ -4,10 +4,10 @@ The `withServerpod` helper provides a `sessionBuilder` that helps with setting up different scenarios for tests. To modify the session builder's properties, call its `copyWith` method. It takes the following named parameters: -|Property|Type|Default|Description| -|:-----|:-----|:---:|:-----| -|`authentication`|`AuthenticationOverride?`|`AuthenticationOverride.unauthenticated()`|See section [Setting authenticated state](#setting-authenticated-state).| -|`enableLogging`|`bool?`|`false`|Wether logging is turned on for the session.| +|Property|Description|Default| +|:---|:---|:---:| +|`authentication`|See section [Setting authenticated state](#setting-authenticated-state).|`AuthenticationOverride.unauthenticated()`| +|`enableLogging`|Whether logging is turned on for the session.|`false`| The `copyWith` method creates a new unique session builder with the provided properties. This can then be used in endpoint calls (see section [Setting authenticated state](#setting-authenticated-state) for an example). @@ -125,13 +125,15 @@ withServerpod( The following optional configuration options are available to pass as a second argument to `withServerpod`: -|Property|Type|Default| +|Property|Description|Default| |:-----|:-----|:---:| -|`rollbackDatabase`|`RollbackDatabase?`|`RollbackDatabase.afterEach`| -|`runMode`|`String?`|`ServerpodRunmode.test`| -|`enableSessionLogging`|`bool?`|`false`| -|`applyMigrations`|`bool?`|`true`| -|`testGroupTagsOverride`|`List?`|`null`| +|`applyMigrations`|Whether pending migrations should be applied when starting Serverpod.|`true`| +|`enableSessionLogging`|Whether session logging should be enabled.|`false`| +|`rollbackDatabase`|Options for when to rollback the database during the test lifecycle (or disable it). See detailed description [here](#rollback-database-configuration).|`RollbackDatabase.afterEach`| +|`runMode`|The run mode that Serverpod should be running in.|`ServerpodRunmode.test`| +|`serverpodLoggingMode`|The logging mode used when creating Serverpod.|`ServerpodLoggingMode.normal`| +|`serverpodStartTimeout`|The timeout to use when starting Serverpod, which connects to the database among other things. Defaults to `Duration(seconds: 30)`.|`Duration(seconds: 30)`| +|`testGroupTagsOverride`|By default Serverpod test tools tags the `withServerpod` test group with `"integration"`. This is to provide a simple way to only run unit or integration tests. This property allows this tag to be overridden to something else. Defaults to `['integration']`.|`['integration']`| ### `rollbackDatabase` {#rollback-database-configuration} @@ -224,22 +226,6 @@ await transactionFuture; In production, the transaction call will throw if any database exception happened during its execution, _even_ if the exception was first caught inside the transaction. However, in the test tools this will not throw an exception due to how the nested transactions are emulated. Quelling exceptions like this is not best practise, but if the code under test does this setting `rollbackDatabase` to `RollbackDatabse.disabled` will ensure the code behaves like in production. -### `runMode` - -The run mode that Serverpod should be running in. Defaults to `test`. - -### `enableSessionLogging` - -Wether session logging should be enabled. Defaults to `false`. - -### `applyMigrations` - -Wether pending migrations should be applied when starting Serverpod. Defaults to `true`. - -### `testGroupTagsOverride` {#test-group-tags-override-configuration} - -By default Serverpod test tools tags the `withServerpod` test group with `"integration"`. This is to provide a simple way to only run unit or integration tests. This property allows this tag to be overridden to something else. Defaults to `null` (i.e. no override). - ## Test exceptions The following exceptions are exported from the generated test tools file and can be thrown by the test tools in various scenarios, see below. diff --git a/docs/06-concepts/18-testing/03-advanced-examples.md b/docs/06-concepts/18-testing/03-advanced-examples.md index 27078416..6d70726f 100644 --- a/docs/06-concepts/18-testing/03-advanced-examples.md +++ b/docs/06-concepts/18-testing/03-advanced-examples.md @@ -15,7 +15,7 @@ dart test -t integration dart test -x integration ``` -To change the name of this tag, see the [`testGroupTagsOverride`](the-basics#test-group-tags-override-configuration) configuration option. +To change the name of this tag, see the [`testGroupTagsOverride`](the-basics#configuration) configuration option. ## Test business logic that depends on `Session` @@ -113,3 +113,37 @@ withServerpod('Given CommunicationExampleEndpoint', (sessionBuilder, endpoints) }); }); ``` + +## Optimising number of database connections + +By default, Dart's test runner runs tests concurrently. The number of concurrent tests depends on the running hosts' available CPU cores. If the host has a lot of cores it could trigger a case where the number of connections to the database exceeeds the maximum connections limit set for the database, which will cause tests to fail. + +Each `withServerpod` call will lazily create its own Serverpod instance which will connect to the database. Specifically, the code that causes the Serverpod instance to be created is `sessionBuilder.build()`, which happens at the latest in an endpoint call if not called by the test before. + +If a test needs a session before the endpoint call (e.g. to seed the database), `sessionBuilder.build()` has to be called which then triggers a database connection attempt. + +If the max connection limit is hit, there are two options: + +- Raise the max connections limit on the database. +- Build out the session in `setUp`/`setUpAll` instead of the top level scope: + +```dart +withServerpod('Given example test', (sessionBuilder, endpoints) { + // Instead of this + var session = sessionBuilder.build(); + + + // Do this to postpone connecting to the database until the test group is running + late Session session; + setUpAll(() { + session = sessionBuilder.build(); + }); + // ... +}); +``` + +:::info + +This case should be rare and the above example is not a recommended best practice unless this problem is anticipated, or it has started happening. + +:::