order of assertEqual arguments is counterintuitive

Hi List, I noticed, that I pay more attention than I should, when working with assertions, because I am not sure about argument order i.e. whether the expected value goes first or vice-versa. Does anybody have similar thought? Such subtle detail should be easy to grasp with regular practice, but I observe difficulties and I suspect that there is a logical reason for that. Unit tests appeared long time ago in Java and spread over all languages. HUnit library inherited de facto standard assert function name and signature. I don't know reasoning behind original signature. I spell "assertEqual" expression as: "Assert that x equals to y" "y" sounds like a model value (i.e. expected value). In assignments "x <- y" y is the model value, because it defines "x". You get "x" - value on the left not on the right. Similar issue with test fixing - I always have to check first, that an expected value is actually one. There is no type safety preventing mixing arguments. I had to open and comprehend a source file with test, because test log is not 100% safe. -- Best regards, Daniil Iaitskov

On Tue, Mar 01, 2022 at 12:56:02PM -0500, Daneel Yaitskov wrote:
I noticed, that I pay more attention than I should, when working with assertions, because I am not sure about argument order i.e. whether the expected value goes first or vice-versa. Does anybody have similar thought?
The documentation is quite clear: https://hackage.haskell.org/package/HUnit-1.6.2.0/docs/Test-HUnit-Base.html#...
Such subtle detail should be easy to grasp with regular practice, but I observe difficulties and I suspect that there is a logical reason for that.
I spell "assertEqual" expression as: "Assert that x equals to y" "y" sounds like a model value (i.e. expected value).
As a combinator that can be curried, -- Check variable given against fixed wanted assertEqual prefix wanted :: (Eq a, Show a) => a -> Assertion is I think more useful than: -- Check variable wanted against fixed given. assertEqual prefix given :: (Eq a, Show a) => a -> Assertion
Similar issue with test fixing - I always have to check first, that an expected value is actually one. There is no type safety preventing mixing arguments.
The test works either way of course, the only thing that changes is the error message on failure. You could implement a type-safe wrapper: newtype Given a = Given a newtype Wanted a = Wanted a checkEq :: (Eq a, Show a) => String -> Given a -> Wanted a -> Assertion checkEq prefix (Given x) (Wanted y) = assertEqual prefix y x Then always call via: checkEq "Oops" (Given (2 + 2)) (Wanted 5) -- Viktor.

I think newtypes are awkward here. Better to use a record to get "named
arguments":
data ExpAct a = ExpAct
{ expected :: a
, actual :: a
}
assertSame
:: HasCallStack
=> (Eq a, Show a)
=> String
-> ExpAct a
-> Assertion
assertSame s ExpAct{expected=e, actual=a} = assertEqual s e a
Now you can write things like
assertSame "whatever" ExpAct{expected=4, actual=x}
On Tue, Mar 1, 2022, 2:38 PM Viktor Dukhovni
On Tue, Mar 01, 2022 at 12:56:02PM -0500, Daneel Yaitskov wrote:
I noticed, that I pay more attention than I should, when working with assertions, because I am not sure about argument order i.e. whether the expected value goes first or vice-versa. Does anybody have similar thought?
The documentation is quite clear:
https://hackage.haskell.org/package/HUnit-1.6.2.0/docs/Test-HUnit-Base.html#...
Such subtle detail should be easy to grasp with regular practice, but I observe difficulties and I suspect that there is a logical reason for that.
I spell "assertEqual" expression as: "Assert that x equals to y" "y" sounds like a model value (i.e. expected value).
As a combinator that can be curried,
-- Check variable given against fixed wanted assertEqual prefix wanted :: (Eq a, Show a) => a -> Assertion
is I think more useful than:
-- Check variable wanted against fixed given. assertEqual prefix given :: (Eq a, Show a) => a -> Assertion
Similar issue with test fixing - I always have to check first, that an expected value is actually one. There is no type safety preventing mixing arguments.
The test works either way of course, the only thing that changes is the error message on failure. You could implement a type-safe wrapper:
newtype Given a = Given a newtype Wanted a = Wanted a
checkEq :: (Eq a, Show a) => String -> Given a -> Wanted a -> Assertion checkEq prefix (Given x) (Wanted y) = assertEqual prefix y x
Then always call via:
checkEq "Oops" (Given (2 + 2)) (Wanted 5)
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

I've always done `equal (thingToTest args) expectedValue` just as a
habit, but it's usually the right order for me in haskell because
`equal (f args) $ big complicated value`. It seems more common that
the expected value is larger than arguments are. But I don't think I
chose it due to that, it was probably that I also write `if mode ==
Whatever then ...` with the constant on the right, and that's probably
some kind of "mental handedness" habit.
But I've also usually written my own test frameworks, so I got to make
the rules. If I use someone else's, then I try to follow whatever
convention they put forth. I'm not sure it's ever mattered much
though, because as soon as I see an error I go to the line that
generated it, and then it's pretty clear if the left or right side is
the expected value.
On Tue, Mar 1, 2022 at 2:50 PM David Feuer
I think newtypes are awkward here. Better to use a record to get "named arguments":
data ExpAct a = ExpAct { expected :: a , actual :: a }
assertSame :: HasCallStack => (Eq a, Show a) => String -> ExpAct a -> Assertion assertSame s ExpAct{expected=e, actual=a} = assertEqual s e a
Now you can write things like
assertSame "whatever" ExpAct{expected=4, actual=x}
On Tue, Mar 1, 2022, 2:38 PM Viktor Dukhovni
wrote: On Tue, Mar 01, 2022 at 12:56:02PM -0500, Daneel Yaitskov wrote:
I noticed, that I pay more attention than I should, when working with assertions, because I am not sure about argument order i.e. whether the expected value goes first or vice-versa. Does anybody have similar thought?
The documentation is quite clear:
https://hackage.haskell.org/package/HUnit-1.6.2.0/docs/Test-HUnit-Base.html#...
Such subtle detail should be easy to grasp with regular practice, but I observe difficulties and I suspect that there is a logical reason for that.
I spell "assertEqual" expression as: "Assert that x equals to y" "y" sounds like a model value (i.e. expected value).
As a combinator that can be curried,
-- Check variable given against fixed wanted assertEqual prefix wanted :: (Eq a, Show a) => a -> Assertion
is I think more useful than:
-- Check variable wanted against fixed given. assertEqual prefix given :: (Eq a, Show a) => a -> Assertion
Similar issue with test fixing - I always have to check first, that an expected value is actually one. There is no type safety preventing mixing arguments.
The test works either way of course, the only thing that changes is the error message on failure. You could implement a type-safe wrapper:
newtype Given a = Given a newtype Wanted a = Wanted a
checkEq :: (Eq a, Show a) => String -> Given a -> Wanted a -> Assertion checkEq prefix (Given x) (Wanted y) = assertEqual prefix y x
Then always call via:
checkEq "Oops" (Given (2 + 2)) (Wanted 5)
-- Viktor. _______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

On Tuesday, March 1st, 2022 at 18:56, Daneel Yaitskov
Hi List,
I noticed, that I pay more attention than I should, when working with assertions, because I am not sure about argument order i.e. whether the expected value goes first or vice-versa. Does anybody have similar thought?
Such subtle detail should be easy to grasp with regular practice, but I observe difficulties and I suspect that there is a logical reason for that.
Unit tests appeared long time ago in Java and spread over all languages. HUnit library inherited de facto standard assert function name and signature. I don't know reasoning behind original signature.
I spell "assertEqual" expression as: "Assert that x equals to y"
"y" sounds like a model value (i.e. expected value).
In assignments `"x <- y"` y is the model value, because it defines `"x"`.
You get `"x"` - value on the left not on the right.
Similar issue with test fixing - I always have to check first, that an expected value is actually one. There is no type safety preventing mixing arguments. I had to open and comprehend a source file with test, because test log is not 100% safe.
I think it is common in Haskell to have the most reusable argument(s) first. Like in this case: shouldBeFour = assertEqual "" 4 assert1 = shouldBeFour (2 + 2) assert2 = shouldBeFour (2 * 2) But styles, like people, may vary between libraries.

I have also been bitten by this order, but I can also blame myself for not reading the documentation and relying on my previous experience with other libraries, thus building an intuition that I believed was universal (when it was in fact not). I don't think it's worth much arguing about the order of things or the "intuition" at play here, since fortunately this library comes with a manual. Very few software match our mental expectations, and even the one we write are specifically tailored for our selves of a given time and place. And as we all know, we are a stranger to our future selves. Cheers Hécate Le 01/03/2022 à 18:56, Daneel Yaitskov a écrit :
Hi List,
I noticed, that I pay more attention than I should, when working with assertions, because I am not sure about argument order i.e. whether the expected value goes first or vice-versa. Does anybody have similar thought?
Such subtle detail should be easy to grasp with regular practice, but I observe difficulties and I suspect that there is a logical reason for that.
Unit tests appeared long time ago in Java and spread over all languages. HUnit library inherited de facto standard assert function name and signature. I don't know reasoning behind original signature.
I spell "assertEqual" expression as: "Assert that x equals to y" "y" sounds like a model value (i.e. expected value).
In assignments |"x <- y"| y is the model value, because it defines |"x"|. You get |"x"| - value on the left not on the right.
Similar issue with test fixing - I always have to check first, that an expected value is actually one. There is no type safety preventing mixing arguments. I had to open and comprehend a source file with test, because test log is not 100% safe.
--
Best regards, Daniil Iaitskov
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.
-- Hécate ✨ 🐦: @TechnoEmpress IRC: Hecate WWW:https://glitchbra.in RUN: BSD

Little point of history: the xUnit family of unit testing
frameworks originated in *Smalltalk* (SUnit), which is why
the graphic user interface for running tests was a standard
part of it. It wasn't just that you could drive tests from
a graphic terminal, it was that testing was *integrated*
with the IDE. The Wikipedia page on jUnit gets this right,
acknowledging the priority of SUnit. Credit should be
given to a specific person: Kent Beck, author of the original
version of SUnit. It would be good for the HUnit document
to give credit where credit is due.
AS for the interface, what is the problem?
It's always <HUnit function> "some string" <other arguments>.
It doesn't really matter very much whether the observed or
expected value is presented next in assertEqual, but it is
documented as expected-then-observed.
On Wed, 2 Mar 2022 at 06:57, Daneel Yaitskov
Hi List,
I noticed, that I pay more attention than I should, when working with assertions, because I am not sure about argument order i.e. whether the expected value goes first or vice-versa. Does anybody have similar thought?
Such subtle detail should be easy to grasp with regular practice, but I observe difficulties and I suspect that there is a logical reason for that.
Unit tests appeared long time ago in Java and spread over all languages. HUnit library inherited de facto standard assert function name and signature. I don't know reasoning behind original signature.
I spell "assertEqual" expression as: "Assert that x equals to y" "y" sounds like a model value (i.e. expected value).
In assignments "x <- y" y is the model value, because it defines "x". You get "x" - value on the left not on the right.
Similar issue with test fixing - I always have to check first, that an expected value is actually one. There is no type safety preventing mixing arguments. I had to open and comprehend a source file with test, because test log is not 100% safe.
--
Best regards, Daniil Iaitskov
_______________________________________________ Haskell-Cafe mailing list To (un)subscribe, modify options or view archives go to: http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe Only members subscribed via the mailman list are allowed to post.

Sounds like you want `@?=`, which is less confusingly spelled `shouldBe` in hspec.
-- Keith
Sent from my phone with K-9 Mail.
On 1 March 2022 17:56:02 UTC, Daneel Yaitskov
Hi List,
I noticed, that I pay more attention than I should, when working with assertions, because I am not sure about argument order i.e. whether the expected value goes first or vice-versa. Does anybody have similar thought?
Such subtle detail should be easy to grasp with regular practice, but I observe difficulties and I suspect that there is a logical reason for that.
Unit tests appeared long time ago in Java and spread over all languages. HUnit library inherited de facto standard assert function name and signature. I don't know reasoning behind original signature.
I spell "assertEqual" expression as: "Assert that x equals to y" "y" sounds like a model value (i.e. expected value).
In assignments "x <- y" y is the model value, because it defines "x". You get "x" - value on the left not on the right.
Similar issue with test fixing - I always have to check first, that an expected value is actually one. There is no type safety preventing mixing arguments. I had to open and comprehend a source file with test, because test log is not 100% safe.
--
Best regards, Daniil Iaitskov
participants (8)
-
Arjen
-
Daneel Yaitskov
-
David Feuer
-
Evan Laforge
-
Hécate
-
Keith
-
Richard O'Keefe
-
Viktor Dukhovni