la10736 / rstest

Fixture-based test framework for Rust
Apache License 2.0
1.21k stars 43 forks source link

Recommendation on choosing between different sets of `#[values(...)]`? #261

Open ghost-in-the-zsh opened 5 months ago

ghost-in-the-zsh commented 5 months ago

I have the following use-case, but I'm not clear on how to proceed[^1]. We can already do this:

#[rstest]
fn your_test(#[values(1, 2, 3)] val: u8) { ... }

But suppose you want to build different sets of #[values(...)], based on some condition: how should I go about it? (NOTE: This is about conditional comp-time selection, not dynamic #[values()].) For example, the following would result in a compile error, but probably communicates the intended idea:

#[rstest]
fn your_test(#[cfg_attr(feature = "myfeat", values(1, 2, 3))] val: u8) { ... }

I realize trying to make this part of the signature is likely the main problem, since the param must always be present and conditional compilation here would break that guarantee. But are there other options?

For example, is there a way to define the entries that #[values(...)] should hold outside, as a list[^2]? I tried something like this, but it didn't give me what I was hoping it would:

// You could feature-flag the `const` def
const VALUES: [u8; 3] = [1,2,3];

#[rstest]
fn your_test(
    #[values(VALUES)]   // <<-- Error: expects `u8`, received `[u8; 3]`
    val: u8
) { ... }

Is there a workaround or a "best practice" to achieve the intent described above? Do I have to write two separate/duplicate functions and feature-gate them instead, as shown below?:

#[cfg(feature = "f1")]
#[rstest]
fn your_test(#[values(1, 2, 3)] val: u8) { ... }

#[cfg(feature = "f2")]
#[rstest]
fn your_test(#[values(4, 5, 6)] val: u8) { ... }

Or maybe I need to write a macro[^3] to split my arrays into comma-separated values at comp-time to make them acceptable by #[values(...)]?

I hope there's a better way. I've read the docs several times, but if the answer is there, I must've missed it. I'm fairly new to rstest itself (thanks, btw :+1:) and I look forward to using it more; there're still some things I need to understand better.

Thanks again.

PS: Sorry if this is a duplicate. The other issues that had references to #[values()] seemed unrelated.

[^1]: If it is, it wasn't clear to me from the docs. [^2]: I know I can define independent consts and then use them as #[values(CONST_1, CONST_2, CONST_3)] val: u8 ..., but I can't just plug a vector/array in there directly. [^3]: Not sure it's as "easy" as it might sound at first.