-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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
proposal: testing: add TB.CleanupErr #63257
Comments
As one data point, this morning I fixed a bug where a test did Instead we could have written |
Happy to send a CL if this gets approved - the implementation is trivial. This is purely about reducing verbosity on the caller side. |
Yet another example is chaining of multiple cleanup steps while checking errors. Right now, I might write:
Whereas now I could write:
|
Devil's advocate: Isn't the obvious missing API here Context: I wrote my own be.NilErr helper. |
Sorry, I don't see how that's an obvious conclusion, or how it relates to this proposal. |
If there were
This feels a little bit too much like fixing one spot where writing |
Personally, I disagree - I would rather solve the issue of If general error handling were to make |
FWIW, with @dsnet's try package, you could do:
|
Much moreso than the rest of the standard library, the I agree with the assessment that most times I have cleanup to do in a test it's something fallible, like deleting some temporary files or terminating a child process, and so I would agree that this seems like a common enough situation to deserve a concise way of writing it, and that having a concise way to write it is likely to help authors write correct tests that will fail when their cleanup steps fail. Since the concept of cleanup is relatively new the codebases I spend most time in haven't universally adopted it yet, but there is some existing use of |
#32111 added
TB.Cleanup
, which I find really useful. However, more often than not I actually have afunc() error
rather than afunc()
- and I want the cleanup to fail the test if a non-nil error appears.Right now you can sort of get away with this by either ignoring the error, e.g.
t.Cleanup(func() { returnsErr() })
, or something similar which checks the error and callst.Error
if it's not nil.I'm left wishing for
t.CleanupErr
takingfunc() error
due to this being a relatively common scenario in my experience - then I could do e.g.t.CleanupErr(returnsErr)
, ort.CleanupErr(f.Close)
, ort.CleanupErr(cmd.Wait)
, ort.CleanupErr(proc.Kill)
, etc.The API would call
TB.Error
instead ofTB.Fatal
if an error is returned, since we still want all cleanups to run even when some of them fail. If an early cleanup fails and makes others fail as well, getting more errors is better than skipping some cleanups and potentially not releasing/deleting resources.In #32111 (comment), @egonelbre suggested that
TB.Cleanup
should have takenfunc() error
from the start, and I disagreed with that, funnily enough :) I've changed my mind since then per the above. It's worth noting that I still think thefunc()
form is useful - plenty of use cases don't return an error, such ast.Cleanup(cancel)
ort.Cleanup(func() { global = nil })
.Worth noting that this should also make cases where parameters are involved simpler, even if a func literal would still be needed. For example,
could become just
t.CleanupErr(func() error { return os.Chdir(orig) })
, avoiding the need for multiple lines.I'm also reminded of the new
sync.OnceX
APIs too -OnceFunc
takesfunc()
,OnceValue
takesfunc() T
,OnceValues
takesfunc() (T1, T2)
. I don't think generics make sense here, since the testing package can only do something reasonably useful with an error.The text was updated successfully, but these errors were encountered: