Testing Guide
This guide covers the taglib-wasm test suite, including how to run tests, write new tests, and maintain test quality.
Test Suite Overview
The test suite is comprehensive and covers all aspects of the library:
- Core functionality - Basic operations, format support
- API coverage - Core API, Simple API, Workers API
- Edge cases - Unicode, empty values, invalid inputs
- Error handling - Error types, messages, recovery
- Memory management - Cleanup, leak prevention
- Performance - Benchmarks, concurrent operations
- Integration - Real-world scenarios
Test Structure
Test Files
Located in the tests/
directory:
index.test.ts
- Main entry point that imports all test modulestaglib.test.ts
- Core functionality & integration testspicture-api.test.ts
- Picture/cover art functionalityedge-cases.test.ts
- Edge case and Unicode testingerror-handling.test.ts
- Error handling testsmemory.test.ts
- Memory management testsextended-metadata.test.ts
- Extended metadata fields (planned)
Test Utilities
test-utils.ts
provides shared utilities:
// Test file paths
export const TEST_FILES = {
wav: resolve("tests/test-files/wav/kiss-snippet.wav"),
mp3: resolve("tests/test-files/mp3/kiss-snippet.mp3"),
flac: resolve("tests/test-files/flac/kiss-snippet.flac"),
ogg: resolve("tests/test-files/ogg/kiss-snippet.ogg"),
m4a: resolve("tests/test-files/mp4/kiss-snippet.m4a"),
};
// Test metadata
export const TEST_TAGS = {
basic: {
title: "Test Title",
artist: "Test Artist",
album: "Test Album",
year: 2024,
track: 1,
genre: "Test Genre",
comment: "Test Comment",
},
unicode: {
title: "Unicode: 你好世界 🎵",
artist: "Артист טֶסט",
album: "🎸 Heavy Metal 🤘",
},
};
// Helper functions
export async function createTestFileWithMetadata(format: string, tags: any);
export async function measureTime(fn: () => Promise<void>);
export async function withTempFile(fn: (path: string) => Promise<void>);
Running Tests
Quick Start
# Run all tests
npm test
# Watch mode for development
npm run test:watch
# With coverage
npm run test:coverage
Running Specific Tests
# Core functionality only
deno test tests/taglib.test.ts
# Picture API only
deno test tests/picture-api.test.ts
# Edge cases
deno test tests/edge-cases.test.ts
# Run tests matching a pattern
deno test --filter "Unicode"
Multi-Runtime Testing
Test across different JavaScript runtimes:
# Test all runtimes
npm run test:multi-runtime
# Individual runtimes
npm run test:deno
npm run test:node
npm run test:bun
Performance Testing
Run performance benchmarks:
deno test --allow-read --allow-write tests/ --filter "Performance"
Writing Tests
Test Structure
Follow this pattern for consistency:
import {
assertEquals,
assertExists,
} from "https://deno.land/std@0.223.0/assert/mod.ts";
import { measureTime, TEST_FILES, TEST_TAGS } from "./test-utils.ts";
Deno.test("Feature: Description", async () => {
// Arrange
const testData = await createTestFileWithMetadata("mp3", TEST_TAGS.basic);
// Act
const result = await performOperation(testData);
// Assert
assertEquals(result.expected, actual);
// Cleanup (if needed)
await cleanup();
});
Best Practices
Use Shared Utilities
// Good - uses shared test data const buffer = await Deno.readFile(TEST_FILES.mp3); // Avoid - hardcoded paths const buffer = await Deno.readFile("./some/path/file.mp3");
Test Across Formats
for (const [format, path] of Object.entries(TEST_FILES)) { Deno.test(`Feature works with ${format}`, async () => { // Test implementation }); }
Clean Up Resources
// Use the withTempFile helper await withTempFile(async (tempPath) => { // Test with temporary file // Cleanup is automatic });
Measure Performance
const duration = await measureTime(async () => { // Performance-critical operation }); console.log(`Operation took ${duration}ms`);
Document Fixed Issues
Deno.test("Unicode: Works correctly", async () => { // Unicode support was fixed in v0.3.12 // All Unicode characters now work correctly });
Adding New Tests
When adding new features:
- Add tests to the appropriate test file
- Update test utilities if needed
- Run coverage to ensure no regression
- Test across multiple runtimes
- Update this documentation
Test Coverage
Current Coverage Goals
- ✅ Core functionality: 95%+ coverage
- ✅ Picture API: 90%+ coverage
- ✅ Error handling: 85%+ coverage
- 🚧 Extended metadata: 0% (not yet implemented)
- Target: 90%+ overall coverage
Viewing Coverage
# Generate coverage report
npm run test:coverage
# View HTML report
open coverage/index.html
Improving Coverage
- Run coverage report
- Identify uncovered lines
- Add tests for edge cases
- Focus on error paths
- Test boundary conditions
Integration Tests
The test suite includes real-world scenarios:
Music Library Processing
Simulates processing an album:
Deno.test("Integration: Music library processing", async () => {
// Create album structure
// Process all tracks
// Verify consistency
});
Batch Operations
Tests concurrent file processing:
Deno.test("Integration: Concurrent operations", async () => {
// Process 20 files simultaneously
// Measure performance
// Verify correctness
});
Cross-Format Operations
Tests tag transfer between formats:
Deno.test("Integration: Cross-format tag transfer", async () => {
// Read tags from MP3
// Write to FLAC
// Verify preservation
});
Debugging Tests
Verbose Output
# Run with verbose logging
DEBUG=* deno test tests/
# Or set in test
Deno.test("Debug test", async () => {
console.log("Debug info:", data);
});
Isolate Failing Tests
# Run single test file
deno test tests/specific-test.ts
# Run single test by name
deno test --filter "exact test name"
Common Issues
Module Loading Errors
- Ensure WASM is built:
npm run build:wasm
- Check import paths
- Ensure WASM is built:
File Not Found
- Run from project root
- Check test file paths
Permission Errors
- Add required permissions:
--allow-read --allow-write
- Add required permissions:
Memory Issues
- Ensure proper cleanup with
dispose()
- Check for memory leaks
- Ensure proper cleanup with
CI/CD Integration
GitHub Actions Example
name: Tests
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: denoland/setup-deno@v1
- uses: actions/setup-node@v3
- name: Install dependencies
run: npm install
- name: Build WASM
run: npm run build:wasm
- name: Run tests
run: npm test
- name: Upload coverage
uses: codecov/codecov-action@v3
Contributing
When contributing tests:
- Follow existing patterns
- Add meaningful test descriptions
- Test edge cases
- Ensure tests are deterministic
- Document any platform-specific behavior
- Run full test suite before submitting
Next Steps
- See Contributing Guidelines for more details
- Check Performance Guide for benchmark guidelines
- Read Error Handling for error testing patterns