Proposal Details
I propose to add the following methods to testing.T (and others):
func (*testing.T) WithValue(key, val any) *testing.T
func (*testing.T) Value(key any) any
Its use would be similar to context.Context, but the idea is that it allows one to pass additional configuration parameters to testing helpers which might be called somewhere deep. Because generally testing.T is passed to all helpers (so that they can call t.Helper() it is reasonable to use t also to pass some additional optional values.
Example: github.com/stretchr/testify package prints diffs when assertions fail. The issue is that there are different ways to print those diffs. For example, should one respect String methods on structs printed (might hide important information) or not (might make structs unreadable because it uses default state representation). To configure this github.com/stretchr/testify could have global settings, but that is fragile. Better would be that caller could call something like t = t.WithValue(testify.UseStringify, true) and then pass this t to its assert.Equal. Why is this better than just having assert.Equal accepting a parameter because assert.Equal might be called deep inside some other testing helper and caller wants to control that. So I propose that such setting could be passed through t itself.
Ugly workaround is to misuse environment variables and use t.Setenv but that disables parallelism and is simply ugly.
Proposal Details
I propose to add the following methods to
testing.T(and others):Its use would be similar to
context.Context, but the idea is that it allows one to pass additional configuration parameters to testing helpers which might be called somewhere deep. Because generallytesting.Tis passed to all helpers (so that they can callt.Helper()it is reasonable to usetalso to pass some additional optional values.Example:
github.com/stretchr/testifypackage prints diffs when assertions fail. The issue is that there are different ways to print those diffs. For example, should one respectStringmethods on structs printed (might hide important information) or not (might make structs unreadable because it uses default state representation). To configure thisgithub.com/stretchr/testifycould have global settings, but that is fragile. Better would be that caller could call something liket = t.WithValue(testify.UseStringify, true)and then pass thistto itsassert.Equal. Why is this better than just havingassert.Equalaccepting a parameter becauseassert.Equalmight be called deep inside some other testing helper and caller wants to control that. So I propose that such setting could be passed throughtitself.Ugly workaround is to misuse environment variables and use
t.Setenvbut that disables parallelism and is simply ugly.