Thank you for your interest in contributing to the Zig Test Framework! This document provides guidelines and instructions for contributing.
- Code of Conduct
- Getting Started
- Development Setup
- Project Structure
- Development Workflow
- Coding Standards
- Testing
- Commit Messages
- Pull Request Process
- Release Process
- Be respectful and inclusive
- Focus on constructive feedback
- Help others learn and grow
- Follow the Zig community guidelines
- Zig 0.15.1 or later
- Git
- Basic understanding of testing frameworks (Jest, Vitest, or similar)
-
Fork the repository
# Clone your fork git clone https://github.com/YOUR_USERNAME/zig-test-framework.git cd zig-test-framework
-
Add upstream remote
git remote add upstream https://github.com/ORIGINAL_OWNER/zig-test-framework.git
-
Build the project
zig build
-
Run tests
zig build test zig build examples
zig-test-framework/
├── src/ # Core framework source code
│ ├── assertions.zig # Assertion library
│ ├── suite.zig # Test suite management (describe/it)
│ ├── test_runner.zig # Test execution engine
│ ├── reporter.zig # Test reporters (Spec, Dot, JSON)
│ ├── matchers.zig # Advanced matchers
│ ├── mock.zig # Mocking and spying
│ ├── cli.zig # Command-line interface
│ ├── lib.zig # Public API exports
│ └── main.zig # CLI entry point
├── tests/ # Framework self-tests
├── examples/ # Usage examples
├── .github/ # CI/CD and templates
├── build.zig # Build configuration
├── build.zig.zon # Package manifest
└── README.md # Documentation
-
Create a feature branch
git checkout -b feature/your-feature-name
-
Make your changes
- Write code following our coding standards
- Add tests for new functionality
- Update documentation as needed
-
Test your changes
# Run all tests zig build test # Run examples zig build examples # Format code zig fmt src/ tests/ examples/
-
Commit your changes
git add . git commit -m "feat: add amazing feature"
-
Push to your fork
git push origin feature/your-feature-name
-
Create a Pull Request
- Go to GitHub and create a PR
- Fill out the PR template
- Link any related issues
Follow the official Zig Style Guide:
- Indentation: 4 spaces (no tabs)
- Line length: Aim for 100 characters, max 120
- Naming:
camelCasefor functions and variablesPascalCasefor typesSCREAMING_SNAKE_CASEfor constants
- Comments: Use
//for single-line,///for doc comments
-
Error Handling
- Use Zig's error unions (
!T) - Provide clear error messages
- Document error conditions
- Use Zig's error unions (
-
Memory Management
- Always accept an allocator parameter
- Clean up resources in
deinit() - Test for memory leaks
-
Public API
- Add doc comments (
///) for all public functions - Export through
lib.zig - Maintain backward compatibility
- Add doc comments (
-
Testing
- Write tests for all new features
- Use inline tests in modules when appropriate
- Add integration tests in
tests/directory
/// Checks if a value is truthy
/// Returns an assertion that succeeds if the value is truthy
pub fn toBeTruthy(self: Self) !void {
const is_truthy = switch (@typeInfo(T)) {
.bool => self.actual,
.optional => self.actual != null,
.int => self.actual != 0,
else => true,
};
if (self.negated) {
if (is_truthy) {
std.debug.print("\nExpected value to be falsy\n", .{});
return AssertionError.AssertionFailed;
}
} else {
if (!is_truthy) {
std.debug.print("\nExpected value to be truthy\n", .{});
std.debug.print(" Received: {any}\n", .{self.actual});
return AssertionError.AssertionFailed;
}
}
}# All framework tests
zig build test
# Run examples
zig build examples
# Specific test file (if needed)
zig test src/assertions.zig-
Unit Tests - Test individual functions in isolation
test "toBe should compare primitive values" { const allocator = std.testing.allocator; try expect(allocator, 5).toBe(5); try expect(allocator, true).toBe(true); }
-
Integration Tests - Test multiple components together
test "runner executes suite with hooks" { // Test setup, execution, teardown flow }
-
Example Tests - Demonstrate usage
- Add to
examples/directory - Show real-world scenarios
- Add to
- Aim for >80% code coverage
- Test both success and failure cases
- Test edge cases and error conditions
- Verify memory cleanup
Follow Conventional Commits:
<type>(<scope>): <subject>
<body>
<footer>
- feat: New feature
- fix: Bug fix
- docs: Documentation changes
- style: Code style changes (formatting, etc.)
- refactor: Code refactoring
- perf: Performance improvements
- test: Adding or updating tests
- chore: Maintenance tasks
# Feature
feat(assertions): add toThrow error assertion
# Bug fix
fix(reporter): correct color output on Windows
# Documentation
docs(readme): update installation instructions
# Multiple changes
feat(matchers): add toBeCloseTo for floating-point comparison
Implements toBeCloseTo matcher for comparing floating-point
numbers with configurable precision.
Closes #123- Tests pass (
zig build test) - Examples work (
zig build examples) - Code is formatted (
zig fmt) - Documentation is updated
- CHANGELOG.md is updated (for significant changes)
- No memory leaks
- Commits follow convention
Fill out the PR template completely:
- Description of changes
- Related issues
- Testing performed
- Breaking changes (if any)
- Maintainer reviews your PR
- Address any feedback
- Once approved, PR will be merged
- Delete your feature branch
- PRs require at least one approval
- All tests must pass
- No merge conflicts
- Follow-up issues created for future work
We follow Semantic Versioning:
- MAJOR: Breaking changes
- MINOR: New features (backward compatible)
- PATCH: Bug fixes (backward compatible)
- Update version in
build.zig.zon - Update CHANGELOG.md
- Create git tag:
git tag -a v1.2.3 -m "Release 1.2.3" - Push tag:
git push origin v1.2.3 - GitHub Actions will create the release
- Issues: Search existing issues or create a new one
- Discussions: Use GitHub Discussions for questions
- Zig Community: Join the Zig Discord or Ziggit forums
Contributors will be recognized in:
- CHANGELOG.md for their contributions
- GitHub contributors page
- Release notes
Thank you for contributing to Zig Test Framework! 🎉