This document provides information on how to run and write tests for the emp3r0r project.
To run all tests in the project:
cd core
go test ./...To run tests for specific packages:
cd core
go test ./lib/util/...
go test ./lib/crypto/...
go test ./lib/sysinfo/...To run tests and generate a coverage report:
cd core
go test -cover ./...For detailed coverage information:
cd core
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.outThis will open an HTML report showing which lines of code are covered by tests.
To see detailed output from each test:
cd core
go test -v ./...To run a specific test function:
cd core
go test -v -run TestFunctionName ./lib/util/...To run tests matching a pattern:
cd core
go test -v -run "TestParseCmd.*" ./lib/util/...To detect race conditions in concurrent code:
cd core
go test -race ./...Some tests are platform-specific and use build tags.
Tests in lib/sysinfo/virt_test.go are Linux-only:
cd core
go test -tags linux ./lib/sysinfo/...On non-Linux platforms, these tests will be skipped automatically.
- Test files should be named
*_test.go - Place test files in the same package as the code being tested
- Example:
str.go→str_test.go
- Test functions must start with
Test - Use descriptive names:
TestParseCmdWithQuotes - Benchmark functions start with
Benchmark - Example functions start with
Example
Use table-driven tests for testing multiple scenarios:
func TestParseCmd(t *testing.T) {
tests := []struct {
name string
input string
expected []string
}{
{
name: "simple command",
input: "ls -la",
expected: []string{"ls", "-la"},
},
// Add more test cases...
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := ParseCmd(tt.input)
if !reflect.DeepEqual(result, tt.expected) {
t.Errorf("got %v, want %v", result, tt.expected)
}
})
}
}Use the testutil package for common test utilities:
import "github.com/jm33-m0/emp3r0r/core/lib/testutil"
func TestExample(t *testing.T) {
tmpDir := testutil.TempDir(t)
filePath := testutil.CreateTempFile(t, tmpDir, "test.txt", "content")
testutil.AssertEqual(t, result, expected)
testutil.AssertNoError(t, err)
}Use build tags for platform-specific tests:
//go:build linux
// +build linux
package sysinfo
import "testing"
func TestLinuxSpecificFunction(t *testing.T) {
// Test code here
}- Test both success and failure cases: Include tests for error conditions
- Use descriptive test names: Make it clear what each test is checking
- Keep tests independent: Tests should not depend on each other
- Use subtests: Group related tests using
t.Run() - Clean up resources: Use
t.Cleanup()ordeferfor cleanup - Avoid external dependencies: Mock external services where possible
- Test edge cases: Empty strings, nil values, boundary conditions
- Use t.Helper(): Mark helper functions with
t.Helper()for better error messages
For cryptographic and security-sensitive functions:
- Use known test vectors where available
- Test with invalid inputs (fuzzing candidates)
- Verify proper error handling
- Test boundary conditions
- Ensure no secrets are logged
- Aim for >70% code coverage for tested packages
- Focus on critical paths and security-sensitive code
- Don't sacrifice test quality for coverage percentage
Tests run automatically on:
- Push to main/master/develop branches
- Pull requests to main/master/develop branches
The CI pipeline:
- Tests on multiple Go versions (1.21, 1.22, 1.23)
- Tests on multiple platforms (Linux, macOS, Windows)
- Runs race detector
- Generates coverage reports
- Runs linters
View test results in the GitHub Actions tab of the repository.
To run benchmarks:
cd core
go test -bench=. ./lib/util/...To compare benchmarks:
cd core
go test -bench=. ./lib/util/... > old.txt
# Make changes
go test -bench=. ./lib/util/... > new.txt
go install golang.org/x/perf/cmd/benchstat@latest
benchstat old.txt new.txtSome tests may be Linux/macOS specific. Check for build tags and platform-specific code.
If -race flag causes failures, investigate concurrent access to shared variables.
Focus on:
- Error paths that aren't tested
- Edge cases
- Complex conditional logic
If you get import cycle errors in tests:
- Create a separate
_testpackage - Example:
package util_testinstead ofpackage util
- Go Testing Documentation
- Table-Driven Tests
- Go Test Coverage
- Testify Package (if you want to use it)
When contributing code:
- Write tests for new functionality
- Ensure existing tests pass
- Add tests for bug fixes
- Update this documentation if needed
For questions or issues with tests, please open an issue on GitHub.