API Testing
Writing test code can often be tedious, isn’t it? I used to find it a headache too, especially before developing Milkio, because I found that few frameworks emphasized testing during design. This usually means writing a lot of mock code and repetitive logic, or doing some meaningless work just to pass the tests.
When designing Milkio, I spent a lot of time making testing simple and easy. Now, you can debug your API while developing it. Once you debug a feature, you can keep it as a test case. This way, you don’t need to rely on tools like Postman to debug the API anymore!
You may have noticed that there is a test example below the API in the /src/hello-world/say.ts
file. In fact, you can write a test case for each API, although it is not mandatory, it is strongly recommended as a best practice.
Each API can have multiple test cases because the defineApiTest
function accepts an array as the second parameter. Tests are executed sequentially because API testing is different from unit testing and usually relies on resources that are difficult to fully simulate, such as databases. Therefore, we ensure that tests do not affect each other by clearing the database between tests.
Testing API Features
In testing, you can easily execute the API you have written before, even without entering the API path. You can also use test.reject
to intentionally fail the test.
Using Client Testing
Previously, we used the test.execute
method for testing, which essentially directly executes your API method without network requests, request
, or response
objects.
We can rely on our client package to send real requests for testing, making your tests closer to real-world scenarios.
In testing, you can use the test.client.execute
method to send requests using the client package:
By default, requests are sent to http://localhost:9000/
. If you use the Milkio VS Code Extension, it will automatically start your HTTP server for testing. If you change the port number or want to modify the client package’s initialization logic, you can edit:
Generating Random Parameters
Writing parameters for tests is always tedious and difficult to be comprehensive. You can use the test.randParams
method to generate random parameters.
The randomly generated parameters are inferred based on the types of your API parameters. If the random content does not meet your expectations, you can narrow down the types or add more rigorous Typia type tags to generate more suitable random parameters.
Testing Other APIs
During testing, you may need to call other APIs. For example, if you are testing an update API, you may need to create data before updating. In this case, you can use the executeOther
method to execute other APIs. If needed, you can also use randOtherParams
to generate random parameters for these APIs:
Of course, you can also use the test.client.executeOther
method to send real network requests for testing.
Testing Streaming APIs
You can test streaming APIs using the test.executeStream
method.
If you want to call other streaming APIs, you can use the test.executeStreamOther
method.
Of course, you can still use the test.client.executeStream
and test.client.executeStreamOther
methods to send real network requests for testing using the client package.
Lifecycle Hooks
In the /src/api-test.ts
file, you can define some functions to run before testing starts or before each test run.
For example, you may want to clear the database or Redis cache before each test to ensure that each test runs in a clean environment.
For onBefore
, you can return an object that will be merged into the test object. You can add some utility functions for testing. Here is an example of a greeting tool: