I would like to know the use case of t.Cleanup
introduced in Go1.14. What is the convenience of t.Cleanup as compared to using defer?
https://golang.org/pkg/testing/#T.Cleanup.
For example, let's say we create a temporary directory, and when we test it, we want to delete the temporary directory we created.
t.Cleanup
can be used to write a test as follows, but it also works as defer os.RemoveAll(tempDir)
.
package mypkg
import (
"io/ioutil"
"os"
"testing"
)
func TestDirwalk(t *testing.T) {
tempDir, err := ioutil.TempDir(".", "temp")
if err != nil {
t.Errorf("create tempDir: %v", err)
}
t.Cleanup(func() { os.RemoveAll(tempDir) })
// something...
}
At the command line in the greetings directory, run the go test command to execute the test. The go test command executes test functions (whose names begin with Test ) in test files (whose names end with _test.go). You can add the -v flag to get verbose output that lists all of the tests and their results.
To run your tests in this mode, run go test in your project's root directory. In the package list mode, go test compiles and tests each package listed as arguments to the command. If a package test passes, go test prints only the final 'ok' summary line. If a package test fails, go test prints the complete test output.
Test Cleanup is code that runs after each test. Test cleanup is declared inside the same class where your tests are declared. Also any assertions you have that go in TestCleanup can fail the test. This is very useful if you have values you check for each test in the same location that could potentially fail the test.
Note: The t. Helper() function indicates to the Go test runner that our Equal() function is a test helper. This means that when t. Errorf() is called from our Equal() function, the Go test runner will report the filename and line number of the code which called our Equal() function in the output.
Once available as a standalone program, the Chrome Cleanup tool is now a part of the actual browser itself and can detect and remove harmful software along with restoring hijacked settings back to their original state.
In a way, it’s kind of like Windows’ built-in Disk Cleanup tool, which frees up space on your hard drive by deleting useless files—old temporary files created by programs, temporary Internet files for Internet Explorer, Windows error report logs, and more.
Using tools for data cleaning will make for more efficient business practices and quicker decision-making. Software like Tableau Prep can help you drive a quality data culture by providing visual and direct ways to combine and clean your data.
How do you clean data? Step 1: Remove duplicate or irrelevant observations Remove unwanted observations from your dataset, including duplicate... Step 2: Fix structural errors Structural errors are when you measure or transfer data and notice strange naming... Step 3: Filter unwanted outliers Often, ...
t.Cleanup
is useful for cleaning up resources allocated by a helper function when the test does not care about the resource itself.
Consider testing a service layer. The service uses a *sql.DB
but does not create it itself.
package testutils
import (
"testing"
"my/db"
"my/domain"
)
func NewTestSubject(t *testing.T) *domain.Service {
t.Helper()
sqldb := newDatabase(t)
s, _ := domain.NewService(sqldb)
return s
}
func newDatabase(t *testing.T) *sql.DB {
t.Helper()
d, _ := db.Create()
t.Cleanup(func() {
d.Close()
})
}
Without t.Cleanup
newTestSubject
would have to return (*domain.Service, *sql.DB)
, leaking details about domain.Service
's construction.
Besides what others have pointed out, t.Cleanup()
is also useful when dealing with parallel subtests, where the cleanup should only run after all subtests have completed. Consider
func TestSomething(t *testing.T){
setup()
defer cleanup()
t.Run("parallel subtest 1", func(t *testing.T){
t.Parallel()
(...)
})
t.Run("parallel subtest 2", func(t *testing.T){
t.Parallel()
(...)
})
}
which doesn't work because the test function will return while the the subtests are still running, causing the resources required by the subtests to get wiped out by defer cleanup()
.
Before t.Cleanup()
a way to solve this was to wrap the subtests on another test
func TestSomething(t *testing.T){
setup()
defer cleanup()
t.Run("parallel tests", func(t *testing.T){
t.Run("subtest 1", func(t *testing.T){
t.Parallel()
(...)
})
t.Run("subtest 2", func(t *testing.T){
t.Parallel()
(...)
})
})
}
which looks ok, but with t.Cleanup()
it gets way better
func TestSomething(t *testing.T){
setup()
t.Cleanup(cleanup)
t.Run("parallel subtest 1", func(t *testing.T){
t.Parallel()
(...)
})
t.Run("parallel subtest 2", func(t *testing.T){
t.Parallel()
(...)
})
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With