This document describes the testing infrastructure and practices for the LuminariMUD codebase. The project uses multiple testing frameworks and approaches to ensure code quality and reliability.
Located in unittests/CuTest/, this is a lightweight C unit testing framework used for core system testing.
Key Features:
- Simple assertion macros
- Automatic test discovery
- Minimal setup required
- C-compatible
Usage Example:
#include "CuTest.h"
void TestSomething(CuTest* tc) {
int expected = 5;
int actual = some_function();
CuAssertIntEquals(tc, expected, actual);
}
CuSuite* GetSuite() {
CuSuite* suite = CuSuiteNew();
SUITE_ADD_TEST(suite, TestSomething);
return suite;
}A minimal unit testing framework available in unittests/minunit.h.
Features:
- Header-only implementation
- Simple macros for assertions
- Lightweight and fast
Individual modules may have their own specialized test suites.
The performance monitoring system (perfmon.c) includes a comprehensive test suite:
Test File: test_perfmon.c
Test Coverage:
- Basic PerfIntvlData operations
- Circular buffer behavior
- Data aggregation between levels
- Memory management (leak detection)
- Report generation and formatting
- Buffer safety and bounds checking
- Input validation and error handling
- Pulse logging functionality
- Threshold tracking accuracy
Running Tests:
# Build and run perfmon tests
make test-perfmon
# Clean test artifacts
make clean-test-perfmonTest Categories:
- Functional Tests - Verify correct behavior
- Safety Tests - Check buffer overflows and memory leaks
- Performance Tests - Validate optimization improvements
- Integration Tests - Test interaction with other systems
# Performance monitor tests
make test-perfmon
# CuTest framework tests
cd unittests/CuTest
make
./test_runnerFor memory leak detection, use valgrind:
# Run with memory checking
valgrind --leak-check=full --show-leak-kinds=all ./test_perfmon
# Check for buffer overflows
valgrind --tool=memcheck --track-origins=yes ./test_perfmon- Test Naming: Use descriptive names that indicate what is being tested
- Test Structure: Follow Arrange-Act-Assert pattern
- Coverage: Aim for both positive and negative test cases
- Independence: Tests should not depend on each other
- Cleanup: Always clean up resources in tests
static void TestFeatureName()
{
// Arrange - Set up test data
SomeStruct* data = create_test_data();
// Act - Execute the function being tested
int result = function_under_test(data);
// Assert - Verify the results
assert(result == expected_value);
// Cleanup
cleanup_test_data(data);
}Always include tests for:
- Null pointer handling
- Buffer boundary conditions
- Memory leak prevention
- Resource cleanup
Before committing code:
- Run relevant unit tests
- Check for memory leaks with valgrind
- Verify no new compiler warnings
- Test with different build configurations
Consider setting up automated testing for:
- Nightly builds
- Pull request validation
- Performance regression detection
- Memory leak monitoring
Use mock objects for testing components in isolation:
- Database connections
- Network sockets
- File system operations
- External dependencies
Create reusable test fixtures for common scenarios:
- Standard player characters
- Typical room configurations
- Common object types
- Network connection states
Include performance benchmarks for critical systems:
- Main game loop timing
- Database query performance
- Memory allocation patterns
- Network I/O throughput
Monitor for performance regressions:
- Compare execution times
- Track memory usage patterns
- Monitor resource consumption
- Validate optimization improvements
- Group related tests together
- Use clear, descriptive test names
- Include both positive and negative cases
- Test edge cases and boundary conditions
- Test error conditions explicitly
- Verify proper cleanup on failures
- Check return codes and error messages
- Test recovery mechanisms
- Document test purposes and expectations
- Include setup and teardown requirements
- Explain complex test scenarios
- Maintain test documentation alongside code
- Automated Test Runner - Script to run all tests
- Coverage Analysis - Track test coverage metrics
- Performance Baselines - Establish performance benchmarks
- Integration Testing - Full system integration tests
- Stress Testing - High-load scenario testing
- Continuous integration setup
- Automated memory leak detection
- Performance regression alerts
- Test result reporting and tracking
This testing guide should be updated as new testing practices and frameworks are adopted.