testify
testify copied to clipboard
assert.Contains with []byte should match string
Description
When using assert.Contains on byte slices, the assertion fails even if the expected subsequence exists.
Environment:
- Go version: 1.23
- Testify version: v1.10.0
Step To Reproduce
func Test(t *testing.T) {
slice1 := []byte(`Hello World Hello`)
slice2 := []byte(`World`)
// This assertion fails, even though slice1 does contain slice2.
assert.Contains(t, slice1, slice2)
// These alternatives work as expected:
assert.Contains(t, string(slice1), string(slice2))
if !bytes.Contains(slice1, slice2) {
t.Errorf("Expected slice1 to contain %q", slice2)
}
}
Expected behavior
The assert.Contains function should pass when a byte slice contains another byte slice. This behavior is consistent with the expectation that the function would detect the presence of a subsequence within a byte array.
Actual behavior
The test fails when using assert.Contains on byte slices, which indicates that the assertion function does not properly support byte slice containment checks.
Hello, I will solve this issue.
Related to https://github.com/stretchr/testify/pull/1526
As mentioned in #1526, we have chosen not to give []byte behavior equivalent to that of string in assert.Contains because:
- Contains has already been inappropriately overloaded with slice/array contains element behavior:
Contains(t, []byte{1}, 1) - The string behavior works for all string kinds including named types, this is difficult to map onto []byte, should it work with these types?
type mySlice []byte // mySlice("how about it?") type myByte byte // []myByte{} type myOtherSlice []myByte // myOtherSlice{}
Because of these properties and their interactions; the resulting Contains assertion is too complicated to properly document, maintain and use.
Anyone looking for the functionality should use a conversion:
slice1 := []byte(`Hello World Hello`)
slice2 := []byte(`World`)
assert.Contains(t, string(slice1), string(slice2))