1 unstable release
Uses new Rust 2024
new 0.4.1 | Apr 13, 2025 |
---|
#965 in Testing
Used in fluent-test
6KB
59 lines
FluentTest
A fluent, Jest-like testing library for Rust that builds upon the standard testing infrastructure. FluentTest provides expressive assertions with readable error messages while maintaining compatibility with Rust's built-in testing functionality.
Features
- Fluent, Expressive API: Write tests in a readable, chainable style similar to Jest.
- Logical Chain Modifiers: Combine assertions with
.and()
and.or()
operators. - Helpful Error Messages: Get clear error messages that include variable names and expressions.
- Seamless Integration: Works alongside Rust's standard testing infrastructure.
- Beautiful Test Output: Enhanced test reporting with visual cues and better organization.
- Type-Safe Assertions: Leverages Rust's type system for compile-time safety.
Roadmap
- Basic matchers for primitive types
- Matchers for collections (Vec, HashMap, etc.)
- Matchers for Option and Result types
- Logical chain modifiers (AND/OR)
- Custom matcher support
- Improved test output formatting
- CI/CD integration for automatic releases
- Documentation and examples
- More advanced matchers (e.g., regex, custom types)
- Performance optimizations
- Support for async testing
- Custom console client (e.g., for CI/CD or nice terminal output)
- Support for code coverage reporting
- Support for mocking and stubbing
- Integration with other testing frameworks (e.g., mockito, assert_eq)
- Community contributions and feedback
- Continuous improvement based on user feedback
- Enhanced error reporting and debugging tools
- Integration with popular CI/CD tools
Quick Start
Add FluentTest to your project:
cargo add fluent-test --dev
Write your first test:
use fluent_test::prelude::*;
#[test]
fn should_check_values() {
// By default, FluentTest behaves like standard Rust assertions
// To enable enhanced output, configure it:
config().enhanced_output(true).apply();
let my_number = 5;
let my_string = "hello world";
let my_vec = vec![1, 2, 3];
expect!(my_number).to_be_greater_than(3);
expect!(my_string).to_contain("world");
expect!(my_vec).to_have_length(3);
}
You can also enable enhanced output globally by setting the environment variable:
FLUENT_TEST_ENHANCED_OUTPUT=true cargo test
Available Matchers
FluentTest provides a comprehensive set of matchers for various types. All matchers support negation through either the
not()
method or the expect_not!
macro.
For complete documentation of all matchers, please see the Wiki documentation.
Boolean Matchers
- to_be_true - Checks if a boolean is true
- to_be_false - Checks if a boolean is false
View Boolean Matchers documentation
Equality Matchers
- to_equal - Checks if a value equals another value
View Equality Matchers documentation
Numeric Matchers
- to_be_greater_than - Checks if a number is greater than another
- to_be_greater_than_or_equal - Checks if a number is greater than or equal to another
- to_be_less_than - Checks if a number is less than another
- to_be_less_than_or_equal - Checks if a number is less than or equal to another
- to_be_even - Checks if a number is even
- to_be_odd - Checks if a number is odd
- to_be_zero - Checks if a number is zero
- to_be_positive - Checks if a number is positive
- to_be_negative - Checks if a number is negative
- to_be_in_range - Checks if a number is within a specified range
View Numeric Matchers documentation
String Matchers
- to_be_empty - Checks if a string is empty
- to_contain - Checks if a string contains a substring
- to_start_with - Checks if a string starts with a prefix
- to_end_with - Checks if a string ends with a suffix
- to_match - Checks if a string matches a pattern
- to_have_length - Checks if a string has a specific length
View String Matchers documentation
Collection Matchers
- to_be_empty - Checks if a collection is empty
- to_have_length - Checks if a collection has a specific length
- to_contain - Checks if a collection contains a specific element
- to_contain_all_of - Checks if a collection contains all specified elements
- to_equal_collection - Compares two collections for element-wise equality
View Collection Matchers documentation
HashMap Matchers
- to_be_empty - Checks if a HashMap is empty
- to_have_length - Checks if a HashMap has a specific length
- to_contain_key - Checks if a HashMap contains a specific key
- to_contain_entry - Checks if a HashMap contains a specific key-value pair
View HashMap Matchers documentation
Option Matchers
- to_be_some - Checks if an Option contains a value
- to_be_none - Checks if an Option is None
- to_contain_value - Checks if an Option contains a specific value
View Option Matchers documentation
Result Matchers
- to_be_ok - Checks if a Result is Ok
- to_be_err - Checks if a Result is Err
- to_contain_ok - Checks if a Result contains a specific Ok value
- to_contain_err - Checks if a Result contains a specific Err value
View Result Matchers documentation
Using Modifiers
FluentTest provides powerful modifiers to create complex assertions, including:
- Negation with the
.not()
method orexpect_not!
macro - Logical chaining with
.and()
and.or()
operators - Combining negation with logical operators
// Example of chained assertions
expect!(number).to_be_greater_than(30)
.and().to_be_less_than(50)
.and().to_be_even();
// Example of negation
expect!(value).not().to_equal(100);
View Using Modifiers documentation
Custom Matchers
FluentTest is designed to be easily extensible. You can create your own custom matchers to make your tests more expressive and domain-specific.
View Custom Matchers documentation
Output Formatting
FluentTest enhances the standard test output with colors, symbols, and improved formatting:
- Color Coding: Green for passing tests, red for failing tests
- Unicode Symbols: Check (✓) marks for passing conditions, cross (✗) for failing ones
- Clean Variable Names: Reference symbols (
&
) are automatically removed from output - Consistent Indentation: Multi-line output is properly indented for readability
View Output Formatting documentation
Architecture
FluentTest uses a modular, event-driven architecture:
- Backend Layer - Core assertion evaluation logic
- Config System - Controls the library's behavior
- Event System - Decouples assertion execution from reporting
- Frontend Layer - Reporting and user interface
View Architecture documentation
Releases
This project is automatically published to crates.io when:
- The version in Cargo.toml is increased beyond the latest git tag
- The code is merged to the master branch
- All CI checks pass (tests, examples, linting)
The publishing workflow will:
- Create a git tag for the new version (vX.Y.Z)
- Publish the package to crates.io
- Generate a GitHub release using notes from CHANGELOG.md
- Fall back to auto-generated notes if no CHANGELOG entry exists
Code Coverage
This project uses Rust's official LLVM-based code coverage instrumentation to track test coverage. The coverage workflow:
- Compiles the project with coverage instrumentation using Rust nightly's
-C instrument-coverage
flag - Runs the test suite to generate raw coverage data in LLVM's profraw format
- Uses grcov to convert the raw coverage data to:
- LCOV format for uploading to Codecov.io
- HTML reports for local viewing
Coverage reports are automatically generated on each push to the master branch and for pull requests.
Viewing Coverage Reports
- The latest coverage report is always available on Codecov.io
- Each CI run also produces an HTML coverage report available as a downloadable artifact
Running Code Coverage Locally
To generate coverage reports locally:
# Install required components
rustup component add llvm-tools-preview
cargo install grcov
cargo install rustfilt
# Build with coverage instrumentation and run tests
RUSTFLAGS="-C instrument-coverage" cargo test
# Generate HTML report
grcov . --binary-path ./target/debug/ -s . -t html --branch --keep-only "src/**" -o ./coverage
# Generate Markdown report
grcov . --binary-path ./target/debug/ -s . -t markdown --branch --keep-only "src/**" -o ./coverage/coverage.md
Then open ./coverage/index.html
in your browser or view the Markdown report in your favorite editor.
License
This project is licensed under the MIT License - see the LICENSE file for details.
Dependencies
~210–650KB
~15K SLoC