Skip to main content
Glama
README.md6.07 kB
# Test Documentation ## Overview This directory contains the test suite for the Contentful GraphQL MCP Server. We use a lightweight unit testing approach focused on testing public APIs with minimal dependencies. ## Philosophy After experiencing issues with complex integration tests and module mocking, we adopted a **lightweight unit testing approach** that prioritizes: 1. **Reliability**: Tests that consistently pass and don't break due to implementation changes 2. **Speed**: Fast execution for quick feedback during development 3. **Simplicity**: Easy to understand and maintain test code 4. **Focus**: Testing behavior, not implementation details ## Directory Structure ``` test/ ├── unit/ # All unit tests │ ├── graphql-handlers.unit.test.ts # Cache and utility functions │ ├── validation.unit.test.ts # Environment validation │ ├── tools.unit.test.ts # Tool configuration │ └── streamable-http.unit.test.ts # HTTP server functionality ├── setup.ts # Global test configuration └── README.md # This file ``` ## Test Infrastructure - **Vitest**: Modern test runner with excellent TypeScript support - **Built-in Mocking**: Using Vitest's native mocking capabilities - **Environment Variables**: Automatic setup of test environment ## Current Test Coverage ### graphql-handlers.unit.test.ts (17 tests) - Cache management functions (`getCacheStatus`, `clearCache`, `isCacheAvailable`) - GraphQL utility functions (`formatGraphQLType`, `isScalarType`, `isSearchableTextField`, `isReferenceType`) ### validation.unit.test.ts (9 tests) - Environment variable validation logic - HTTP port validation with edge cases - Error handling and `process.exit` behavior ### tools.unit.test.ts (13 tests) - Tool configuration schema generation - GraphQL tool definitions and structure validation - Environment property injection testing ### streamable-http.unit.test.ts (6 tests) - StreamableHTTP server functionality - Route setup and handler registration - Server lifecycle management **Total: 45 tests, all passing** ## Running Tests ```bash # Run all tests npm test # Run tests in watch mode npm run test:watch # Run specific test file npm test test/unit/graphql-handlers.unit.test.ts # Run with coverage npm run test:coverage ``` ## Writing New Tests ### Basic Test Structure ```typescript import { describe, it, expect } from "vitest" import { functionToTest } from "../../src/path/to/module" describe("functionToTest", () => { it("should do what it's supposed to do", () => { const result = functionToTest("input") expect(result).toBe("expected output") }) }) ``` ### Environment Variable Testing ```typescript import { describe, it, expect, beforeEach, afterEach } from "vitest" describe("environment dependent function", () => { let originalEnv: NodeJS.ProcessEnv beforeEach(() => { originalEnv = { ...process.env } }) afterEach(() => { process.env = originalEnv }) it("should work with valid environment", () => { process.env.REQUIRED_VAR = "test-value" expect(() => functionToTest()).not.toThrow() }) }) ``` ### Mocking Functions ```typescript import { describe, it, expect, vi } from "vitest" describe("function with dependencies", () => { it("should handle mocked dependency", () => { const mockFn = vi.fn().mockReturnValue("mocked result") const result = functionToTest(mockFn) expect(mockFn).toHaveBeenCalledWith("expected input") expect(result).toBe("expected output") }) }) ``` ## Guidelines ### What to Test - ✅ Public API functions that are exported and used - ✅ Error handling and edge cases - ✅ Environment variable validation - ✅ Configuration generation and validation ### What NOT to Test - ❌ Private/internal functions not exported - ❌ Implementation details that might change - ❌ Third-party library behavior - ❌ Complex integration scenarios (keep those simple) ### Best Practices 1. **One Assertion Per Test**: Each test should verify one specific behavior 2. **Descriptive Names**: Test names should clearly describe what's being tested 3. **Arrange-Act-Assert**: Structure tests with clear setup, execution, and verification 4. **Independent Tests**: Tests should not depend on each other 5. **Fast Execution**: Aim for tests that run in milliseconds ### Common Patterns #### Testing Functions That Return Objects ```typescript it("should return object with expected properties", () => { const result = generateConfig() expect(result).toHaveProperty("name") expect(result).toHaveProperty("description") expect(result.name).toBe("expected-name") }) ``` #### Testing Error Conditions ```typescript it("should throw error for invalid input", () => { expect(() => validateInput("invalid")).toThrow("Expected error message") }) ``` #### Testing Async Functions ```typescript it("should handle async operation", async () => { const result = await asyncFunction() expect(result).toBe("expected result") }) ``` ## Troubleshooting ### Common Issues 1. **Import Errors**: Make sure the path to the module is correct 2. **Environment Variables**: Use beforeEach/afterEach to properly set up and clean up 3. **Async Tests**: Don't forget to use `await` or return promises 4. **Mocking**: Use Vitest's `vi.fn()` for simple mocks ### Debugging Tests ```bash # Run single test with verbose output npm test -- --reporter=verbose test/unit/specific.test.ts # Run tests with debugging npm test -- --inspect-brk ``` ## Future Considerations As the codebase grows, consider: 1. **Test Utilities**: Create helper functions for common test patterns 2. **Custom Matchers**: Add domain-specific assertions 3. **Performance Tests**: Add tests for performance-critical functions 4. **Integration Tests**: Carefully add integration tests for critical workflows Remember: The goal is reliable, fast tests that give confidence in the code without becoming a maintenance burden.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ivo-toby/contentful-mcp-graphql'

If you have feedback or need assistance with the MCP directory API, please join our Discord server