Last active
May 27, 2020 03:54
-
-
Save mvndaai/54d13611d62e8fa9306bdd11a2bb4666 to your computer and use it in GitHub Desktop.
Go table test
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tabletest | |
import "errors" | |
//ForceError will return an error if the boolean is true | |
func ForceError(force bool) error { | |
if force { | |
return errors.New("forced error") | |
} | |
return nil | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package tabletest | |
import ( | |
"testing" | |
) | |
func TestWithTables(t * testing.T){ | |
tests := []struct{ | |
name string | |
expectedError bool | |
forceError bool | |
}{ | |
{name: "pass without error", expectedError: false, forceError: false}, | |
{name: "pass with error", expectedError: true, forceError: true}, | |
{name: "fail without error", expectedError: true, forceError: false}, | |
{name: "fail with error", expectedError: false, forceError: true}, | |
{name: func()string{ | |
/* | |
Sometimes you want to use a function to generate a happy object for all tests and then change one thing about it | |
This is complicated in a table test because multiple lines of code is not usually expected in initiating a struct | |
If you make an anonymous function, like this, you can call your function to create a happy object | |
After editing it, return the new object | |
Since there is the () after the {} it is returned immediately | |
ex: h := happyObject(); h.value = "change"; return h; | |
*/ | |
return "name from function" | |
}(), | |
expectedError: false, forceError: false}, | |
} | |
for _, test := range tests { | |
// `t.Run` appends the name to a test and makes a fatal only relate to the specific test | |
// See the output below to see how much it simplifies finding issues | |
t.Run(test.name, func(t *testing.T){ | |
//If a test is safe to run concurrently you can use `t.Parallel()` | |
defer func(){ | |
if t.Failed(){ | |
t.Log("extra logging only if failed, not shown when running verbose tests") | |
} | |
/* | |
Wrapping `t.Log` in `if t.Failed()` makes sure this is only logged if the test has already failed | |
This helps keep logs clean when running in verbose mode | |
Wrapping this in a `defer` is a trick to make the additonal logging always show on failures | |
This is especially helpful when using `t.Fatal` | |
*/ | |
}() | |
err := ForceError(test.forceError) | |
if (err != nil) != test.expectedError { | |
t.Fatal("Error was not expected:", err) | |
// `t.Fatal` stops the test here. If you want it to continue after an error use `t.Error` | |
} | |
}) | |
} | |
} | |
/* Output of `go test ./... -v` | |
--- FAIL: TestWithTables (0.00s) | |
--- PASS: TestWithTables/pass_without_error (0.00s) | |
--- PASS: TestWithTables/pass_with_error (0.00s) | |
--- FAIL: TestWithTables/fail_without_error (0.00s) | |
tabletest_test.go:45: Error was not expected: <nil> | |
tabletest_test.go:39: extra logging only if failed, not shown when running verbose tests | |
--- FAIL: TestWithTables/fail_with_error (0.00s) | |
tabletest_test.go:45: Error was not expected: forced error | |
tabletest_test.go:39: extra logging only if failed, not shown when running verbose tests | |
--- PASS: TestWithTables/name_from_function (0.00s) | |
*/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment