|
| 1 | +# Integration Test |
| 2 | + |
| 3 | +This directory contains integration tests for the CSGHb server. |
| 4 | + |
| 5 | +### Starting and Stopping the Test Environment |
| 6 | + |
| 7 | +Setting up the test environment for integration testing is simple. Follow the steps below: |
| 8 | + |
| 9 | +```go |
| 10 | + ctx := context.TODO() |
| 11 | + env, err := testinfra.StartTestEnv() |
| 12 | + defer func() { _ = env.Shutdown(ctx) }() |
| 13 | +``` |
| 14 | + |
| 15 | +However, before proceeding with writing your tests, please read the following explanation to fully understand what happens in these three lines of code. A lot is happening behind the scenes. |
| 16 | + |
| 17 | +When `testinfra.StartTestEnv()` is called, the following actions are performed in sequence: |
| 18 | + |
| 19 | +1. **Load the configuration file**: The `common/config/test.toml` configuration file is loaded. This config is used during integration tests. |
| 20 | +2. **Create a test PostgreSQL database**: A PostgreSQL database is created on a random port using test containers. The database configuration in the test config is updated accordingly. |
| 21 | +3. **Start the Gitaly server**: A Gitaly server is started using test containers. The configuration used for Gitaly is either `tests/gitaly.toml` or `tests/gitaly_github.toml` (used when running on GitHub). Please add a comment in the code explaining why two config files are required. The Gitaly server configuration is updated once the container is started. |
| 22 | +4. **Start the Temporal test server**: A local Temporal test server is started using the [temporaltest package](https://github.com/temporalio/temporal/blob/main/temporaltest/README.md). The workflow endpoint config is also updated. By default, the Temporal test server uses a random namespace to avoid conflicts, but we force the registration of the default namespace to ensure tests run. |
| 23 | +5. **Start the in-memory S3 server**: A local in-memory S3 server is started using [GoFakeS3](https://github.com/johannesboyne/gofakes3). This server is used with the MinIO Go SDK for testing LFS (Large File Storage) functionality. The S3 configuration is updated accordingly. |
| 24 | +6. **Start the Redis server**: A Redis server is started using test containers, and the Redis endpoint configuration is updated. |
| 25 | +7. **Start the CSGHub server**: The CSGHub user server and its workflows are started. |
| 26 | +8. **Start the CSGHub dataset viewer server**: The CSGHub dataset viewer server and its workflows are started. |
| 27 | +9. **Start the CSGHub main API server**: The CSGHub main API server and its workflows are started. |
| 28 | + |
| 29 | +That’s all. Note that not all services are started by default. For example, the NATS server or runner server is not started. If you need to test functionality related to these services, be sure to add them to the environment startup function. |
| 30 | + |
| 31 | +After the test environment is started, always defer the call to `env.Shutdown(ctx)` to ensure all resources are properly cleaned up. |
| 32 | + |
| 33 | +### Writing Tests |
| 34 | + |
| 35 | +There are two test files provided: |
| 36 | + |
| 37 | +- **model_test.go**: This tests CRUD operations for models and Git-related functionality. Since the model, dataset, space, and code all share the same repository and Git API code, you can consider this file to also test dataset, space, and code-related features. |
| 38 | +- **dataset_viewer_test.go**: This file tests the Temporal workflows for the dataset viewer server. |
| 39 | + |
| 40 | +The test code in these files clearly demonstrates how to test the API, Git, and workflows. There’s no need to repeat this here. |
| 41 | + |
| 42 | +One important thing to remember is that for all integration tests, you should add the following snippet at the beginning of your test function: |
| 43 | + |
| 44 | +```go |
| 45 | + if testing.Short() { |
| 46 | + t.Skip("skipping integration test") |
| 47 | + } |
| 48 | +``` |
| 49 | + |
| 50 | +This allows you to differentiate between unit tests and integration tests. |
| 51 | + |
| 52 | +### What to Test in Integration Tests |
| 53 | + |
| 54 | +Integration tests involve starting multiple services and interacting with real databases (as opposed to database unit tests, which use in-memory or transactional databases and roll back changes after the test). Writing too many integration tests can significantly slow down the testing process, so here are three key suggestions: |
| 55 | + |
| 56 | +1. **Group related actions into single test cases**: For example, basic CRUD operations can be tested in a single test case. However, avoid overloading tests. Separate unrelated actions, such as API and Git operations, into different tests. |
| 57 | +2. **Prioritize the most used features**: Focus on testing the 80% of use cases that are most commonly used in your service. These are the most critical and should not fail. |
| 58 | +3. **Test important but less common features**: For features that may not be used frequently but are critical (e.g., those that could result in significant issues, like financial losses), consider adding integration tests for them as well. |
| 59 | + |
| 60 | +### Starting a Test API Server |
| 61 | + |
| 62 | +You can also use the test environment to start a temporary test server. To do so, run the following command: |
| 63 | + |
| 64 | +``` |
| 65 | +go run main.go start-test-env |
| 66 | +``` |
0 commit comments