This document provides detailed information about the Rust tests in the Pyroid project, including how to run them and what they test.
The Pyroid project includes comprehensive tests at both the Python and Rust levels:
- Python Tests: Test the Python API and fallback implementations
- Rust Tests: Test the core Rust implementations directly, without going through Python bindings
The Rust tests ensure that the underlying Rust code works correctly before it's exposed through the Python bindings, providing an additional layer of quality assurance.
To run all Rust tests:
cargo test --test test_rust_*To run tests for a specific module:
# Core functionality tests
cargo test --test test_rust_core
# Math operations tests
cargo test --test test_rust_math
# Data operations tests
cargo test --test test_rust_data
# Text operations tests
cargo test --test test_rust_text
# I/O operations tests
cargo test --test test_rust_io
# Image operations tests
cargo test --test test_rust_image
# ML operations tests
cargo test --test test_rust_implTo run a specific test:
cargo test --test test_rust_core test_configTo see more detailed output, including output from passing tests:
cargo test --test test_rust_* -- --nocaptureThe tests are automatically run on GitHub Actions for every push and pull request:
- Rust Tests: Run on multiple operating systems (Ubuntu, Windows, and macOS) to ensure cross-platform compatibility.
- Python Tests: Run the Python implementation tests that don't require the Rust extension.
You can see the status of the tests in the badge at the top of the README.md file.
The GitHub Actions workflow is defined in .github/workflows/tests.yml.
Tests for the core functionality of the Pyroid library:
- Config: Tests for the configuration system, including setting and getting options
- SharedData: Tests for the shared data container
- Thread-local Config: Tests for thread-local configuration
Tests for mathematical operations:
- Vector Operations: Tests for vector addition, subtraction, scalar multiplication, dot product, and norm
- Matrix Operations: Tests for matrix addition, subtraction, scalar multiplication, matrix multiplication, and transpose
- Statistical Functions: Tests for sum, mean, median, variance, and standard deviation
- Correlation: Tests for correlation calculation
Tests for data operations:
- Filter: Tests for filtering collections
- Map: Tests for mapping operations
- Reduce: Tests for reduction operations
- Sort: Tests for sorting operations
- DataFrame: Tests for DataFrame creation and column access
- DataFrame Apply: Tests for applying functions to DataFrame columns
- DataFrame GroupBy: Tests for grouping and aggregating DataFrame data
Tests for text operations:
- Reverse: Tests for string reversal
- Base64: Tests for base64 encoding and decoding
- Split: Tests for string splitting
- Join: Tests for string joining
- Replace: Tests for string replacement
- Regex Replace: Tests for regex-based replacement
- Case Conversion: Tests for uppercase and lowercase conversion
- Tokenize: Tests for text tokenization
- N-grams: Tests for n-gram generation
Tests for input/output operations:
- File Operations: Tests for reading, writing, and appending to files
- Directory Creation: Tests for creating directories when writing files
- Error Handling: Tests for handling errors with nonexistent files
Tests for image processing:
- Image Creation: Tests for creating new images
- Pixel Manipulation: Tests for getting and setting pixel values
- Resize: Tests for resizing images
- Grayscale: Tests for converting images to grayscale
- Blur: Tests for blurring images
Tests for machine learning operations:
- K-means Clustering: Tests for k-means clustering algorithm
- Linear Regression: Tests for linear regression
- Normalize: Tests for data normalization
- Distance Matrix: Tests for calculating distance matrices
The tests are implemented using Rust's built-in testing framework. The common module (tests/common/mod.rs) provides implementations of the functionality being tested, which are then used by the test modules.
The common module contains pure Rust implementations of all the functionality tested:
pub mod core { /* ... */ }
pub mod math { /* ... */ }
pub mod text { /* ... */ }
pub mod data { /* ... */ }
pub mod io { /* ... */ }
pub mod image { /* ... */ }
pub mod ml { /* ... */ }Each module provides implementations of the corresponding functionality in the Pyroid library.
Each test module follows a similar structure:
- Import the common module
- Define test functions for each piece of functionality
- Use assertions to verify that the functionality works as expected
For example:
#[test]
fn test_config() {
// Create a new Config
let mut config = core::Config::new();
// Set some options
config.set("parallel", true);
// Get the options
assert_eq!(config.get::<bool>("parallel").unwrap(), true);
}To add a new test:
- Identify the appropriate test module for your test
- Add a new test function with the
#[test]attribute - Implement the test logic
- Run the test to ensure it passes
If you need to test new functionality:
- Add the necessary implementation to the common module
- Create a new test function in the appropriate test module
- Run the test to ensure it passes
- Test fails with "assertion failed": Check that the implementation in the common module matches the expected behavior
- Test fails with "panicked at...": Check for runtime errors in the implementation
- Dead code warnings: These are normal and can be ignored, as not all functions in the common module are used in every test
To debug a failing test:
- Run the test with verbose output:
cargo test --test test_rust_* -- --nocapture - Add print statements to the test to see intermediate values
- Check the implementation in the common module for errors