New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
assert.Equal randomly fails testing maps #143
Comments
I agree, it sounds like a bad idea to compare string representations. This is not robust enough. Why not simply |
👍 remove For example, the |
I'm fine with this, though I am not sure if there are tests that rely on this behavior. Care to submit a PR with it removed and tests passing? |
Aren't such tests broken by design since the iteration over the keys is intentionally random? |
I am not sure either. That portion was written ages ago when we were just learning about the best way to compare objects. I'll give it a look. The tests may be broken by design, yes. |
It seems the only test that depends on this is a test comparing functions. See https://github.com/stretchr/testify/blob/master/assert/assertions_test.go#L119 @cryptix @benma @OttoAllmendinger @phemmer this will change behavior when it comes to comparing functions. I am fine with this change myself, as I never do that. Thoughts? |
We could add an explicit check to see if the 2 items being compared are functions, and if so manually check them for equality (instead of deferring to |
A simple if reflect.ValueOf(expected) == reflect.ValueOf(actual) {
return true
} made that test pass. I'm comfortable with that. |
@tylerb I didn't think that comparing reflected Values with == made sense. The godocs indicate that as I recall. You're just testing how |
You're right. From this post on SO it seems this is probably something we shouldn't even try to do. I won't miss it myself. |
Yeah, I'd just return the value from But I wonder if maybe, because a literal numeric is boxed into an |
At the very least, when reporting the 2 values are not equal, the types of the values needs to shown too, to avoid output like this:
|
@evanphx Right. This is something that could be added, certainly. For example, in my other testing framework, is (I don't use testify anymore), I do: aValue := reflect.ValueOf(a)
bValue := reflect.ValueOf(b)
// Convert types and compare
if bValue.Type().ConvertibleTo(aValue.Type()) {
return reflect.DeepEqual(a, bValue.Convert(aValue.Type()).Interface())
} to handle these cases. This could be added to address your issue. Thoughts? |
Yeah, that would definitely work. |
It looks like the |
Why has this issue been marked as closed? I'm still getting errors when comparing int to int64. Also, @evanphx is right. Errors like |
I would recommend opening a new issue for this so it can be discussed and a proper solution implemented. On Thu, Apr 16, 2015 at 4:43 PM, Andrei notifications@github.com wrote:
|
Am I correct in my understanding that this was never resolved? |
This is still happening in the latest library version. The tests pass in macOS but fails in linux. Can someone have a look on this please ? |
The presence of In your example, the issue arises due to the random order in which the map values are printed by If you're encountering issues with such random failures, one approach could be to explicitly convert the maps to a consistent format before comparison. For instance, you could convert the maps to JSON strings and then compare those strings. This ensures a consistent representation for comparison, regardless of the internal order of the map's elements. Here's how you might modify your test function: import (
"encoding/json"
// ... other imports
)
func TestExactly(t *testing.T) {
map1 := map[string]interface{}{"foo": 1234, "bar": int16(4321)}
map2 := map[string]interface{}{"foo": 1234, "bar": int32(4321)}
jsonMap1, _ := json.Marshal(map1)
jsonMap2, _ := json.Marshal(map2)
if assert.Equal(t, string(jsonMap1), string(jsonMap2)) {
fmt.Printf("Everything is ok\n")
} else {
fmt.Printf("Everything is NOT OK\n")
}
} This modification ensures that the order of map elements doesn't affect the comparison, and you'll get consistent results even if the map representations are different due to type variations. |
assert.Equal
(and other functions) will randomly fail testing equality of maps with the same values but different type.For example:
Results in:
The issue is because the type on
bar
is different between the maps (int16
in one,int32
in the other).ObjectsAreEqual
usesreflect.DeepEqual
which properly detects this, but then it continues to check equality of afmt.Sprintf("%#v",...)
on the values, and this randomly fails depending on the order it prints the map values in.The solution seems simple: remove the
fmt.Sprintf()
check. But I wasn't sure why that was in there to begin with.The text was updated successfully, but these errors were encountered: