Skip to content

Commit 18193f7

Browse files
authored
feat: Add test tools docs (#167)
* feat: add test tools docs * feat: add doc for all exported types * fix(review): apply suggestions * fix(review): add intro to each best practice * fix(review): add better test instructions * fix(review): clarify exception scope * fix(review): add complete file reference * fix(review): rework session builder section * fix: minor rephrase * fix: add experimental-flag, add serverpod mini notice * fix(review): rephrase, remove redundant header ids * fix(review): remove redundant comment
1 parent 2214364 commit 18193f7

File tree

5 files changed

+687
-0
lines changed

5 files changed

+687
-0
lines changed

Diff for: docs/06-concepts/18-testing/01-get-started.md

+212
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
# Get started
2+
3+
Serverpod provides simple but feature rich test tools to make testing your backend a breeze.
4+
5+
:::info
6+
7+
For Serverpod Mini projects, everything related to the database in this guide can be ignored.
8+
9+
:::
10+
11+
<details>
12+
<summary> Have an existing project? Follow these steps first!</summary>
13+
<p>
14+
For existing non-Mini projects, a few extra things need to be done:
15+
1. Add the `server_test_tools_path` key to `config/generator.yaml`. Without this key, the test tools file is not generated. The default location for the generated file is `integration_test/test_tools/serverpod_test_tools.dart`, but this can be set to any path (though should be outside of `lib` as per Dart's test conventions).
16+
17+
2. New projects now come with a test profile in `docker-compose.yaml`. This is not strictly mandatory, but is recommended to ensure that the testing state is never polluted. Add the snippet below to the `docker-compose.yaml` file in the server directory:
18+
19+
```yaml
20+
# Test services
21+
postgres_test:
22+
image: postgres:16.3
23+
ports:
24+
- '9090:5432'
25+
environment:
26+
POSTGRES_USER: postgres_test
27+
POSTGRES_DB: projectname_test
28+
POSTGRES_PASSWORD: "<insert database test password>"
29+
volumes:
30+
- projectname_data:/var/lib/postgresql/data
31+
profiles:
32+
- '' # Default profile
33+
- test
34+
redis_test:
35+
image: redis:6.2.6
36+
ports:
37+
- '9091:6379'
38+
command: redis-server --requirepass "<insert redis test password>"
39+
environment:
40+
- REDIS_REPLICATION_MODE=master
41+
profiles:
42+
- '' # Default profile
43+
- test
44+
```
45+
46+
<details>
47+
<summary>Or copy the complete file here.</summary>
48+
<p>
49+
50+
```yaml
51+
services:
52+
# Development services
53+
postgres:
54+
image: postgres:16.3
55+
ports:
56+
- '8090:5432'
57+
environment:
58+
POSTGRES_USER: postgres
59+
POSTGRES_DB: projectname
60+
POSTGRES_PASSWORD: "<insert database development password>"
61+
volumes:
62+
- projectname_data:/var/lib/postgresql/data
63+
profiles:
64+
- '' # Default profile
65+
- dev
66+
redis:
67+
image: redis:6.2.6
68+
ports:
69+
- '8091:6379'
70+
command: redis-server --requirepass "<insert redis development password>"
71+
environment:
72+
- REDIS_REPLICATION_MODE=master
73+
profiles:
74+
- '' # Default profile
75+
- dev
76+
77+
# Test services
78+
postgres_test:
79+
image: postgres:16.3
80+
ports:
81+
- '9090:5432'
82+
environment:
83+
POSTGRES_USER: postgres_test
84+
POSTGRES_DB: projectname_test
85+
POSTGRES_PASSWORD: "<insert database test password>"
86+
volumes:
87+
- projectname_data:/var/lib/postgresql/data
88+
profiles:
89+
- '' # Default profile
90+
- test
91+
redis_test:
92+
image: redis:6.2.6
93+
ports:
94+
- '9091:6379'
95+
command: redis-server --requirepass "<insert redis test password>"
96+
environment:
97+
- REDIS_REPLICATION_MODE=master
98+
profiles:
99+
- '' # Default profile
100+
- test
101+
102+
volumes:
103+
projectname_data:
104+
```
105+
106+
</p>
107+
</details>
108+
3. Create a `test.yaml` file and add it to the `config` directory:
109+
110+
```yaml
111+
# This is the configuration file for your local test environment. By
112+
# default, it runs a single server on port 8090. To set up your server, you will
113+
# need to add the name of the database you are connecting to and the user name.
114+
# The password for the database is stored in the config/passwords.yaml.
115+
#
116+
# When running your server locally, the server ports are the same as the public
117+
# facing ports.
118+
119+
# Configuration for the main API test server.
120+
apiServer:
121+
port: 9080
122+
publicHost: localhost
123+
publicPort: 9080
124+
publicScheme: http
125+
126+
# Configuration for the Insights test server.
127+
insightsServer:
128+
port: 9081
129+
publicHost: localhost
130+
publicPort: 9081
131+
publicScheme: http
132+
133+
# Configuration for the web test server.
134+
webServer:
135+
port: 9082
136+
publicHost: localhost
137+
publicPort: 9082
138+
publicScheme: http
139+
140+
# This is the database setup for your test server.
141+
database:
142+
host: localhost
143+
port: 9090
144+
name: projectname_test
145+
user: postgres
146+
147+
# This is the setup for your Redis test instance.
148+
redis:
149+
enabled: false
150+
host: localhost
151+
port: 9091
152+
```
153+
154+
4. Add this entry to `config/passwords.yaml`
155+
156+
```yaml
157+
test:
158+
database: '<insert database test password>'
159+
redis: '<insert redis test password>'
160+
```
161+
162+
That's it, the project setup should be ready to start using the test tools!
163+
</p>
164+
</details>
165+
166+
Go to the server directory and generate the test tools by running `serverpod generate --experimental-features testTools`. The default location for the generated file is `integration_test/test_tools/serverpod_test_tools.dart`. The folder name `integration_test` is chosen to differentiate from unit tests (see the [best practises section](best-practises#unit-and-integration-tests) for more information on this).
167+
168+
The generated file exports a `withServerpod` helper that enables you to call your endpoints directly like regular functions:
169+
170+
```dart
171+
// Import the generated file, it contains everything you need.
172+
import 'test_tools/serverpod_test_tools.dart';
173+
174+
void main() {
175+
withServerpod('Given Example endpoint', (sessionBuilder, endpoints) {
176+
test('when calling `hello` then should return greeting', () async {
177+
final greeting =
178+
await endpoints.example.hello(sessionBuilder, 'Michael');
179+
expect(greeting, 'Hello, Michael!');
180+
});
181+
});
182+
}
183+
```
184+
185+
A few things to note from the above example:
186+
187+
- The test tools should be imported from the generated test tools file and not the `serverpod_test` package.
188+
- The `withServerpod` callback takes two parameters: `sessionBuilder` and `endpoints`.
189+
- `sessionBuilder` is used to build a `session` object that represents the server state during an endpoint call and is used to set up scenarios.
190+
- `endpoints` contains all your Serverpod endpoints and lets you call them.
191+
192+
:::tip
193+
194+
The location of the test tools can be changed by changing the `server_test_tools_path` key in `config/generator.yaml`. If you remove the `server_test_tools_path` key, the test tools will stop being generated.
195+
196+
:::
197+
198+
Before the test can be run the Postgres and Redis also have to be started:
199+
200+
```bash
201+
docker-compose up --build --detach
202+
```
203+
204+
By default this starts up both the `development` and `test` profiles. To only start one profile, simply add `--profile test` to the command.
205+
206+
Now the test is ready to be run:
207+
208+
```bash
209+
dart test integration_test
210+
```
211+
212+
Happy testing!

0 commit comments

Comments
 (0)