I think there's a lot of value to gain in eliminating this inconsistency from the ecosystem, to have an actual idiom of the order of "actual VS expected" or "expected VS actual" in assertions.
Because the "actual VS expected" case reads more naturally, and because it is also the most common, I propose changing the error message of a failing assert_eq! to "actual VS expected":
assertion `actual == expected` failed
actual: "a"
expected: "b"
If ~1/3 of the uses choose one order, and the other ~2/3 use the other order, I don't think that's enough of a consensus for us to codify. It would be incorrect a lot of the time. Also, in my experience, when a programming language does choose an order for expected vs actual, my personal experience is getting this wrong a lot of the time (and seeing others get it wrong a lot of the time). So I think rust's approach of not choosing a canonical ordering for this is better.
I'm both then since I see both orders used in my personal projects - mostly because there's no better indication from the compiler which value should go where. I'd stick to one given the indication.
I tend to do actual, expected because actual is usually just a variable reference while expected can be a large literal or other more verbose expression and the last argument is far more amenable to reformat splay than the former (IMO).
It's worth checking out the design of googletest - Rust which uses matcher expressions to make it more obvious that the right side is the expected value (e.g. assert_that! documentation) and also it has advanced matchers that provide more detailed error messages, printing subexpressions wherever Debug is implemented (matches_pattern!). It also adds its own test runner that you may optionally use to support tests that useResult for failures instead of panic-based assertions or support non-fatal assertions to be able to see multiple failures instead of stopping at the first.
Those proportions are not indicative of consensus, they are indicative of ambiguity. An ambiguity which hurts understanding of test output.
As to which should be picked, I wouldn't be upset if someone flipped a coin. Non-ambiguous would be better than the status quo. That said obviously it should be (actual, expected) as it is alphabetic.
jUnit and related use the opposite order for a similar reason: they're assuming that expected is often a small literal, and actual is often a function call with a bunch of parameters (the call that's being tested). This is also the documented convention used in googletest for other languages, though apparently not the Rust port as mentioned above?
I've rarely seen any test framework for any language which documents the order as actual, expected - most either don't assign a specific meaning or use expected, actual.
What if neither argument is the actual or expected one? For instance, if I'm writing a zip_eq for slices and assert they both have the same length? And what about assert_ne?
I'm not strongly opposed, just curious whether these questions were considered?
In those cases the actual/expected labels become roughly as meaningful as left and right. For assert_ne the labels could become unactual and unexpected, or perhaps they could be left as is.
Not familiar with the C++ version, but for the Rust version the second argument allows matchers, so the distinction there between the first and second argument can't be easily removed.
Changing the message will not be an effective way of eliminating inconsistency in the ecosystem: most people will not notice, so we'll just be making code worse.
If this is something that could be linted on, perhaps, but otherwise this is not a good idea. There is clearly ambiguity in the ecosystem, you cannot just force consensus through a behavior change.
Furthermore, not every assertion case has a clear expected/actual, sometimes the thing is indeed just "are these two things the same".
A better proposal that helps eliminate confusion would be to add expected= and actual= disambiguators to the macro, e.g. assert_eq!(expected = foo, actual = bar), which change the displayed error message. I'm not sure if it pulls its weight (it feels verbose to me), but it would allow for folks to opt in to expected/actual messaging. I certainly have times where I wish the assertion error message told me which was the expected value.
I'd find it much more valuable if the output would highlight the actual difference. When asserting equality between structs (especially large or nested ones) you often get two blobs of std::fmt::Debug outputs you have to look through to find a (sometimes) one character difference.
Not sure on the feasability of that though [1], but even diff on the output text + color highlighting would be very useful in that situation. Example (inspired by Wordle):
Red for sections that don't occur in the Debug output of the other side
Optional: Orange for (larger) sections that are in the other side but not in the same place
White for matching sections (same place/order)
Especially when order does not matter for equality like with HashMap. âŠī¸
For the standard library, this could be solved by a debug hook like std::fmt::set_debug_hook, so we can have a separate crate colored_debug_hook that you install, and it intercepts output of any Debug call. We might do something more advanced, and the hook could be able to modify more granular parts of the debug output, like the debug_struct or debug_tuple methods etc.
Perhaps it is down to coding style, but actual is usually a variable whereas expected is either hand-typed or also pulling a local variable (e.g., to make sure a configuration value gets through). Could be that the borrow checker tends to nudge towards having a local variable for computed results? It also avoids "cross-over" when doing let cases = [(input, answer), âĻ]; into a for (a, e) in cases { assert_eq!(i.some_method(), e); } loop.
Right, this is definitely a coding style thing - I wasn't proposing that this is universal or even common in Rust, just that you can argue for the exact opposite conclusion based on the same "size of parameter" argument, and this is the basis for some other test libraries explicitly defining the order as expected, actual.
I didn't give my actual opinion on the topic in my reply, which probably made my point less clear. I don't think assert_eq! should use expected/actual labels in either order, because it seems to me that there is no real consensus (either in Rust or in other languages/libraries) around which order is correct, and explicitly defining the order now is not going to fix that - it's just going to end up with a bunch of code where the labels are backwards. I don't think introducing a new assertion with a different name really fixes this either if it's still possible to switch them in the code without an error, because people will carry over their assumptions about the "right" order from other contexts and still get it wrong.
For some new testing assertion primitive like the matcher-based options mentioned, where the two parameters are not interchangable and switching them will actually fail to compile, that's a different story, but I would assume that anyone defining an intentionally non-symmetrical primitive like this would already be making it produce the desired kind of output that makes it clear what happened.