rust-lang / rust-lang/rust

RFC: Introduce `setup`, `teardown`, and `fixture` attributes for `cargo test`

Open
#117,668 11 comments 45 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

A-libtest C-feature-request T-testing-devex
Dominant language
Rust
Stars
119k
Forks
16.1k
PR merge metrics
PR metrics pending

Description

Problem

The current testing framework in Rust, as implemented by cargo test, lacks a convenient way to define and manage setup teardown, and fixtures objects for tests. While it is possible to implement such functionality using structs, implementing the Drop trait in case of teardown, and such, this approach can be cumbersome and lacks the expressiveness and convenience of more declarative fixture management.

The absence of a dedicated mechanism for defining fixtures and their lifecycles results in the following issues:

  1. Test authors often need to implement repetitive and error-prone setup teardown code and common structs instance for fixtures, making tests less maintainable.
  2. Complex test setups, teardowns, and resource management require a non-trivial amount of boilerplate code.
  3. There is no standard way to share setup/teardown, and fixtures across multiple tests or test modules, potentially leading to duplication of setup/teardown code and fixtures.
Proposed Solution

This RFC proposes the introduction of three new attributes #[setup], #[teardown], and #[fixture] which can be used in Rust test functions to indicate functions that should serve as setup/teardown functions, and fixture objects respectively. Test authors can define setup functions/teardown functions, and common objects with these attributes, and the testing framework will ensure that they are executed appropriately before and after test functions that use them. For instance:

use std::fs;
use tempfile::TempDir;

#[fixture]
fn temp_dir() -> TempDir {
    let temp_dir = TempDir::new().expect("Failed to create temporary directory");
    temp_dir
}

#[setup]
fn setup() {
   // Setup before tests
}

#[teardown]
fn teardown() {
   // Cleanup after tests 
}

#[test(setup, teardown)] // The usage of these functions is debatable
fn test_with_temp_dir(temp_dir) { // fixtures are passed to the test function as args
    // Test logic with temp_dir fixture arg
    // ...
}

With these attributes, test authors can set up necessary fixtures or resources in a clear and standardized manner before the test execution and ensure proper cleanup afterward. This feature will streamline the development of tests, particularly in cases where complex setup and teardown operations are required.

Notes

Introducing setup, teardown, and fixture attributes in Cargo Test will improve the test development experience by simplifying resource management, enhancing test predictability, and enabling developers to write more complex tests with ease. This RFC aligns with the goal of making Rust testing more ergonomic and developer-friendly.

P.S. Just stumbled upon rstest which provides fixtures, but lacks a setup/teardown mechanism.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reviewing the existing cargo test testing framework and compare its capabilities with the linked rstest project. Clarify the semantics and scope of the setup, teardown, and fixture attributes before proposing implementation work; done means maintainers agree on a concrete design.

Written by the indexing model from the issue text.

Assessment

Tech stack
rust
Domain
testing-qa
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
20/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.