Repository navigation
testing: add TB.TempDir() string #35998
Description
Activity
Yeah, the artifacts could be useful for debugging. If there is an explicit os.RemoveAll, I can just comment that out when debugging. With the new function I guess I can do the same by digging into the testing package and commenting out that line, but that is more complicated. Maybe add a new helper that keeps the artifacts that can be used for debugging? t.Keep()? t.NoCleanup?
@cherrymui, no need. You can write:
defer func() { if t.Failed() { os.Exit(1) } }
Or since you know it's already failing:
defer log.Fatalf("check out the failing files in %v", t.TempDir())
... then no cleanup will happen due to the
os.Exit(1)(whichlog.Fatalfalso does).Reacted by Tv, Tom Thorogood and Yegor MyskinReacted by Oleg KovalovWhy not have a flag which prevents tempdir deletion, something like
-test.keeptmp? I'd think that'd be simpler than manually inserting defers (for most uses), and within this proposal the testing framework is already in charge of managing the directory's lifetime.Reacted by Tv, Yegor Myskin, Prashant V and Frédéric G. MARAND@bradfitz Good to know. Thanks!
@zikaeroh, flag/knob fatigue. Too much crap can be overwhelming. Especially for stuff that's rarely needed. "It might be useful sometimes" is not the bar to add stuff. You also have to consider the fatigue costs for more docs and more
-helpspew.Reacted by Thomas and Codey OxleySince I’m not seeing it mentioned, have you considered a more verbose and explicit API variation that returns a cleanup closure?
Somewhat inspired by
context.WithCancel, it may look like:func (*T) TempDir() (dir string, cleanup func())
It would make idiomatic first usage require two extra lines:
func Test(t *testing.T) { // ... tempDir, cleanup := t.TempDir() defer cleanup() // ... use tempDir }
The advantage would be that it’s easier to temporarily modify not to clean up, more readable that there’s no leak to first-time readers, possible to detect when cleanup isn’t called, but at the cost of some additional verbosity. But maybe two lines isn’t bad compared to the 4+ it requires now.
Throwing it out there for consideration, but I’m not convinced this would be better.
Reacted by Tushar Dwivedi and Klimov Sergei@dmitshur, if I wanted to write verbose code, I already can today? 🤷♂️
I wrote some tempdir helpers that we use for a lot of tests at work. A trick I used (which I took from @tv42) is to detect whether the test is being run under
go testand, if it is, locate the tempdir inside the go tool's own temp directory. (In this case the deferredtd.Remove()does nothing.) Then if you want to inspect the tempdir, you use-workto print the directory and not delete it.Reacted by Brad Fitzpatrick, Tv and Tom Thorogood17 remaining items
Change https://golang.org/cl/226983 mentions this issue:
doc: document testing.TB.TempDir in release notes- added a commit that references this issue
on Apr 3, 2020 What's the guideline for making sure the package
testingrespects the Go 1 compatibility promise? Adding methods likeCleanupandTempDirto the interfacetesting.TBbreaks custom implementations.The test code is not explicitly excluded from the document, and it's unclear to me if we're in the "it may be necessary to add methods to types" case, which seems to be more concerned about structs and embedding.
@Deleplace note that the docs already say
TB is the interface common to T and B, and the implementation explicitly forbids any other type from ever implementing TB:https://golang.org/src/testing/testing.go?s=19485:20043#L536
// A private method to prevent users implementing the // interface and so future additions to it will not // violate Go 1 compatibility. private()If someone wants to use a subset of the interface that's also implemented by other types, they should declare their own interface with the few methods they are interested in. Backwards compatibility will apply there, because we will only ever add methods to TB, not modify or remove existing ones.
Thanks Daniel, that's exactly the info I was looking for! Indeed I was not aware of
TB.private.- locked and limited conversation to collaborators
on May 5, 2021
It's pretty usual to have tests make temp files.
And it's pretty usual to have tests leak temp files. (#23619 tracks detecting it for Go's own tests, as it keeps coming up)
Doing things properly also gets kinda boilerplatey.
I propose adding a method to testing.TB, *testing.T, and *testing.B something like this: