mirror of https://github.com/buster-so/buster.git
automatic integratino test set up
This commit is contained in:
parent
7e982c3653
commit
021dbd2fa1
|
@ -109,6 +109,50 @@ pub enum Error {
|
|||
- Keep library-specific test helpers in the library
|
||||
- Use workspace-defined test macros if available
|
||||
|
||||
#### Database Integration Tests
|
||||
For tests that require database access, the preferred approach is to use automatic pool initialization:
|
||||
|
||||
```rust
|
||||
// In tests/mod.rs
|
||||
use database::pool::init_pools;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
lazy_static! {
|
||||
// Initialize test environment once across all tests
|
||||
static ref TEST_ENV: () = {
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
if let Err(e) = rt.block_on(init_pools()) {
|
||||
panic!("Failed to initialize test pools: {}", e);
|
||||
}
|
||||
println!("✅ Test environment initialized");
|
||||
};
|
||||
}
|
||||
|
||||
#[ctor::ctor]
|
||||
fn init_test_env() {
|
||||
lazy_static::initialize(&TEST_ENV);
|
||||
}
|
||||
```
|
||||
|
||||
Then write normal tests without explicit initialization:
|
||||
|
||||
```rust
|
||||
// In your test file
|
||||
#[tokio::test]
|
||||
async fn test_database_functionality() -> Result<()> {
|
||||
// Pool is already initialized - just get it
|
||||
let pool = database::pool::get_pg_pool();
|
||||
|
||||
// Your test code here
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
This pattern ensures:
|
||||
- Database pools are initialized exactly once at test startup
|
||||
- All tests can access the same pool without manual initialization
|
||||
- Test code remains clean without initialization boilerplate
|
||||
|
||||
### 5. Documentation
|
||||
- Follow workspace documentation style
|
||||
- Link to related workspace documentation
|
||||
|
|
|
@ -30,5 +30,4 @@ reqwest = { workspace = true }
|
|||
|
||||
|
||||
[dev-dependencies]
|
||||
tokio-test = { workspace = true }
|
||||
testkit = { path = "../../testkit" }
|
||||
tokio-test = { workspace = true }
|
|
@ -1,45 +0,0 @@
|
|||
use anyhow::Result;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_database_connection() -> Result<()> {
|
||||
// Get the database pool from testkit
|
||||
let pool = testkit::get_pg_pool();
|
||||
|
||||
// Test the connection by getting a connection from the pool
|
||||
let conn = pool.get().await?;
|
||||
|
||||
// If we got here without errors, the connection is working
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_with_isolation() -> Result<()> {
|
||||
// Get a unique test ID for data isolation
|
||||
let test_id = testkit::test_id();
|
||||
|
||||
// Get database pool
|
||||
let pool = testkit::get_pg_pool();
|
||||
|
||||
// Get a DB connection
|
||||
let mut conn = pool.get().await?;
|
||||
|
||||
// Here you would create test data with test_id for isolation
|
||||
// For example:
|
||||
// diesel::sql_query("INSERT INTO users (id, email, test_id) VALUES ($1, $2, $3)")
|
||||
// .bind::<diesel::sql_types::Uuid, _>(uuid::Uuid::new_v4())
|
||||
// .bind::<diesel::sql_types::Text, _>("test@example.com")
|
||||
// .bind::<diesel::sql_types::Text, _>(&test_id)
|
||||
// .execute(&mut conn)
|
||||
// .await?;
|
||||
|
||||
// Run assertions on the test data
|
||||
|
||||
// Clean up after the test
|
||||
// For example:
|
||||
// diesel::sql_query("DELETE FROM users WHERE test_id = $1")
|
||||
// .bind::<diesel::sql_types::Text, _>(&test_id)
|
||||
// .execute(&mut conn)
|
||||
// .await?;
|
||||
|
||||
Ok(())
|
||||
}
|
|
@ -120,4 +120,33 @@ async fn example_handler(req: PostChatRequest, user: AuthenticatedUser) -> Resul
|
|||
- Test the full request-response cycle for integration tests
|
||||
- Use test fixtures for consistent test data
|
||||
- Run tests with: `cargo test -p handlers`
|
||||
- Create tests for each handler in the corresponding `tests/` directory
|
||||
- Create tests for each handler in the corresponding `tests/` directory
|
||||
|
||||
### Automatic Test Environment Setup
|
||||
|
||||
Integration tests in this library use an automatic database pool initialization system. The environment is set up once when the test module is loaded, eliminating the need for explicit initialization in each test.
|
||||
|
||||
Key components:
|
||||
- `tests/mod.rs` contains the initialization code using `lazy_static` and `ctor`
|
||||
- Database pools are initialized only once for all tests
|
||||
- Tests can directly use `get_pg_pool()` without any setup code
|
||||
|
||||
Example test:
|
||||
```rust
|
||||
use anyhow::Result;
|
||||
use database::pool::get_pg_pool;
|
||||
|
||||
#[tokio::test]
|
||||
async fn test_handler_functionality() -> Result<()> {
|
||||
// Database pool is already initialized
|
||||
let pool = get_pg_pool();
|
||||
|
||||
// Test code here using the pool
|
||||
Ok(())
|
||||
}
|
||||
```
|
||||
|
||||
To add new test modules, simply:
|
||||
1. Create a new module in the `tests/` directory
|
||||
2. Add it to the module declarations in `tests/mod.rs`
|
||||
3. Write standard async tests using `#[tokio::test]`
|
|
@ -39,4 +39,6 @@ dashmap = "5.5.3"
|
|||
[dev-dependencies]
|
||||
tokio-test = { workspace = true }
|
||||
mockall = { workspace = true }
|
||||
dotenv = { workspace = true }
|
||||
dotenv = { workspace = true }
|
||||
lazy_static.workspace = true
|
||||
ctor = "0.4.1"
|
||||
|
|
|
@ -1,8 +1,22 @@
|
|||
use anyhow::Result;
|
||||
use database::pool::get_pg_pool;
|
||||
|
||||
// Just a regular tokio test - environment is initialized automatically
|
||||
#[tokio::test]
|
||||
async fn test_placeholder() -> Result<()> {
|
||||
// This is a placeholder test
|
||||
// Verify we can access the database pool without explicit initialization
|
||||
let _pool = get_pg_pool();
|
||||
|
||||
assert!(true);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// Another test - will share the same initialized environment
|
||||
#[tokio::test]
|
||||
async fn test_another_test() -> Result<()> {
|
||||
// Uses the same pool that was initialized once for all tests
|
||||
let _pool = get_pg_pool();
|
||||
|
||||
assert!(true);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,2 +1,27 @@
|
|||
use database::pool::init_pools;
|
||||
use lazy_static::lazy_static;
|
||||
|
||||
lazy_static! {
|
||||
// Initialize test environment once across all tests
|
||||
static ref TEST_ENV: () = {
|
||||
// Create a runtime for initialization
|
||||
let rt = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
// Initialize pools
|
||||
if let Err(e) = rt.block_on(init_pools()) {
|
||||
panic!("Failed to initialize test pools: {}", e);
|
||||
}
|
||||
|
||||
println!("✅ Test environment initialized");
|
||||
};
|
||||
}
|
||||
|
||||
// This constructor runs when the test binary loads
|
||||
#[ctor::ctor]
|
||||
fn init_test_env() {
|
||||
// Force lazy_static initialization
|
||||
lazy_static::initialize(&TEST_ENV);
|
||||
}
|
||||
|
||||
// Test modules
|
||||
pub mod dashboards;
|
||||
|
|
Loading…
Reference in New Issue