Skip to main content
Bitwarden Server uses xUnit as its primary testing framework, with AutoFixture for test data generation and NSubstitute for mocking.

Test Project Structure

The test/ directory contains 23 test projects organized by the code they test:

Running Tests

Run All Tests

Run Specific Test Project

Run Tests by Filter

Run Tests with Coverage

Test Framework Components

xUnit

All tests use xUnit as the test runner:
test/Core.Test/Core.Test.csproj

AutoFixture

AutoFixture generates test data automatically:

NSubstitute

NSubstitute provides mocking capabilities:

Writing Unit Tests

Basic Test Structure

Here’s an example from the codebase:
test/Core.Test/NotificationCenter/Commands/CreateNotificationCommandTest.cs

Using BitAutoData

The [BitAutoData] attribute combines xUnit’s [InlineData] with AutoFixture:

SutProvider Pattern

SutProvider (System Under Test Provider) automatically mocks dependencies:

Verifying Mock Interactions

Writing Integration Tests

Integration tests verify that components work together correctly.

Database Integration Tests

Integration tests use real database connections:

API Integration Tests

API integration tests make HTTP requests to test endpoints:

Test Data Generation

Custom AutoFixture Customizations

Create customizations for complex entities:
Use it in tests:

Testing Patterns

Arrange-Act-Assert (AAA)

All tests follow the AAA pattern:

Test Naming Convention

Tests are named: MethodName_Scenario_ExpectedOutcome Examples:
  • CreateAsync_Authorized_NotificationCreated
  • GetById_UserNotFound_ThrowsNotFoundException
  • UpdatePassword_InvalidPassword_ReturnsFailed

Testing Best Practices

Test One Thing

Use Meaningful Test Data

Avoid Test Interdependence

Mock External Dependencies

Running Tests in CI/CD

Tests run automatically in GitHub Actions:

Troubleshooting Tests

Tests Fail Locally But Pass in CI

  1. Ensure database is clean:
  2. Clear test artifacts:

Flaky Integration Tests

  • Add retry logic for timing-sensitive tests
  • Increase timeouts for async operations
  • Ensure proper test isolation

Mock Setup Not Working

Verify argument matchers:

See Also