Documentation
¶
Overview ¶
Package got provides a comprehensive testing framework for Go applications.
Package got provides a comprehensive testing framework for Go applications. It offers a fluent API for writing expressive and readable tests with built-in support for test cases, assertions, and error handling.
The package includes:
- Test runner with fluent API for organizing test cases
- Built-in assertion methods for common testing scenarios
- Support for table-driven tests with structured test cases
- Error handling utilities for testing error conditions
- Mock utilities for Redis and SQL databases
Example usage:
func TestCalculator(t *testing.T) {
r := got.New(t, "Calculator Tests")
r.Case("Testing addition")
result := 2 + 3
r.Require(result == 5, "2 + 3 should equal 5")
r.Case("Testing division by zero")
_, err := divide(10, 0)
r.Errf(err, "Division by zero should return error")
}
For more examples, see the example functions in this package.
Index ¶
- func CaseBuilder(name string) *caseBuilder
- type Case
- type Namer
- type R
- func (r *R) AssertContains(container, item any, msg ...string) *R
- func (r *R) AssertEqual(expected, actual any, msg ...string) *R
- func (r *R) AssertErr(err error)
- func (r *R) AssertErrf(err error, desc string, args ...any)
- func (r *R) AssertFalse(condition bool, msg ...string) *R
- func (r *R) AssertNil(value any, msg ...string) *R
- func (r *R) AssertNoErr(err error)
- func (r *R) AssertNoErrf(err error, desc string, args ...any)
- func (r *R) AssertNotContains(container, item any, msg ...string) *R
- func (r *R) AssertNotEqual(expected, actual any, msg ...string) *R
- func (r *R) AssertNotNil(value any, msg ...string) *R
- func (r *R) AssertNotPanics(fn func(), msg ...string) *R
- func (r *R) AssertPanics(fn func(), msg ...string) *R
- func (r *R) AssertTrue(condition bool, msg ...string) *R
- func (r *R) Benchmark(name string, f func(b *testing.B)) *R
- func (r *R) Case(format string, args ...any) *R
- func (r *R) Caser(name string, f func(t *testing.T)) *R
- func (r *R) Cases(cases []Case, f func(c Case, tt *testing.T))
- func (r *R) Cleanup(fn func()) *R
- func (r *R) Deadline() (deadline time.Time, ok bool)
- func (r *R) Fail(format string, args ...any)
- func (r *R) FailNow(cond bool, desc string, args ...any)
- func (r *R) Fatal(format string, args ...any)
- func (r *R) Getenv(key string) string
- func (r *R) GoroutineCount() *R
- func (r *R) Helper() *R
- func (r *R) MemoryUsage() *R
- func (r *R) Parallel() *R
- func (r *R) Pass(format string, args ...any)
- func (r *R) Require(cond bool, desc string, args ...any)
- func (r *R) Run(name string, f func(t *testing.T)) *R
- func (r *R) RunParallel(fn func(*testing.PB)) *R
- func (r *R) Setenv(key, value string) *R
- func (r *R) Skip(reason string, args ...any) *R
- func (r *R) SkipIf(condition bool, reason string, args ...any) *R
- func (r *R) SkipUnless(condition bool, reason string, args ...any) *R
- func (r *R) StartTimer() *R
- func (r *R) StopTimer() *R
- func (r *R) TempDir() string
- func (r *R) TestInfo() *R
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func CaseBuilder ¶
func CaseBuilder(name string) *caseBuilder
CaseBuilder creates a new case builder for fluent test case construction. This provides a builder pattern for creating test cases with method chaining.
Parameters:
- name: The initial name for the test case
Returns:
- *caseBuilder: A new case builder instance
Example:
case := got.CaseBuilder("Test Case").
Input("hello").
Want(5).
WantErr(false).
Err(nil).
Build()
Types ¶
type Case ¶
type Case interface {
Namer
Input() any // the input of the test case
Want() any // the expected result of the test case
WantErr() bool // whether the test case should return an error
Err() error // the error of the test case
}
Case defines the structure of a test case for table-driven tests. It provides a standardized way to define test inputs, expected outputs, and error conditions for multiple test scenarios.
The interface includes:
- Name(): A descriptive name for the test case
- Input(): The input data for the test
- Want(): The expected output/result
- WantErr(): Whether the test case should produce an error
- Err(): The specific error expected (if WantErr() is true)
Example:
case := got.NewCase("Valid Login", "[email protected]", true, false, nil)
// case.Name() returns "Valid Login"
// case.Input() returns "[email protected]"
// case.Want() returns true
// case.WantErr() returns false
// case.Err() returns nil
func NewCase ¶
NewCase creates a new test case with the provided parameters. This is the simplest way to create a test case for table-driven tests.
Parameters:
- name: A descriptive name for the test case
- input: The input data for the test
- want: The expected output/result
- wantErr: Whether the test case should produce an error
- err: The specific error expected (if wantErr is true)
Returns:
- Case: A new test case instance
Example:
case := got.NewCase("Valid Input", "hello", 5, false, nil)
case := got.NewCase("Invalid Input", "", 0, true, errors.New("empty input"))
type Namer ¶
type Namer interface {
Name() string
}
Namer is an interface for objects that have a name. This is used by the Case interface to provide naming functionality.
type R ¶
R represents a test runner that provides a fluent API for writing tests. It embeds *testing.T to provide all standard testing functionality while adding enhanced logging, assertion methods, and test case management.
The runner maintains state for:
- title: The main test suite title
- caseNum: Current case number for automatic numbering
- prefix: Formatted prefix for case logging
- startTime: Test start time for timing
- benchmark: Whether running in benchmark mode
- parallel: Whether test is marked as parallel
Example:
r := got.New(t, "My Test Suite")
r.Case("First test case")
r.Require(condition, "Description")
func New ¶
New creates a new test runner instance from a testing.T. The title parameter is used to identify the test suite in logs and output.
Parameters:
- t: The testing.T instance from the test function
- title: A descriptive title for the test suite
Returns:
- *R: A new test runner instance
Example:
func TestMyFeature(t *testing.T) {
r := got.New(t, "My Feature Tests")
// Use r for test cases and assertions
}
Example ¶
// This example shows how to create a new test runner
// In a real test function, you would do:
// func TestExample(t *testing.T) {
// r := New(t, "Example")
// // Output: Test Case => Example
// }
fmt.Println("Test Case => Example")
fmt.Println("&{Example 0 <nil> <nil>}")
Output: Test Case => Example &{Example 0 <nil> <nil>}
func (*R) AssertContains ¶
AssertContains provides a more descriptive contains assertion
func (*R) AssertEqual ¶
AssertEqual provides a more descriptive equality assertion
func (*R) AssertErr ¶
AssertErr checks if the provided error is not nil. If err is not nil, it passes the test; otherwise, it fails with a default message. This is useful for testing error conditions where you expect an error to occur.
Parameters:
- err: The error to check
Example:
_, err := divide(10, 0) r.AssertErr(err) // Expects an error for division by zero
func (*R) AssertErrf ¶
AssertErrf checks if the provided error is not nil with a custom description. If err is not nil, it passes the test with the given description. If err is nil, it fails the test and stops execution. This method is useful when you need to provide context about what error was expected.
Parameters:
- err: The error to check
- desc: A description of what error was expected
- args: Arguments for the description format string
Example:
_, err := validateInput("")
r.AssertErrf(err, "Empty input should cause validation error")
func (*R) AssertFalse ¶
AssertFalse provides a more descriptive false assertion
func (*R) AssertNoErr ¶
AssertNoErr checks if the provided error is nil. If err is nil, it passes the test; otherwise, it fails with a default message. This is a convenience method for the common case of checking for no error.
Parameters:
- err: The error to check
Example:
_, err := someFunction() r.AssertNoErr(err)
func (*R) AssertNoErrf ¶
AssertNoErrf checks if the provided error is nil with a custom description. If err is nil, it passes the test with the given description. If err is not nil, it fails the test, logs the error details, and stops execution. This method is useful when you need to provide context about what operation failed.
Parameters:
- err: The error to check
- desc: A description of what operation should not have failed
- args: Arguments for the description format string
Example:
user, err := authenticateUser(username, password) r.AssertNoErrf(err, "User authentication should succeed for %s", username)
func (*R) AssertNotContains ¶
AssertNotContains provides a more descriptive not-contains assertion
func (*R) AssertNotEqual ¶
AssertNotEqual provides a more descriptive inequality assertion
func (*R) AssertNotNil ¶
AssertNotNil provides a more descriptive non-nil assertion
func (*R) AssertNotPanics ¶
AssertNotPanics provides a more descriptive no-panic assertion
func (*R) AssertPanics ¶
AssertPanics provides a more descriptive panic assertion
func (*R) AssertTrue ¶
AssertTrue provides a more descriptive true assertion
func (*R) Case ¶
Case starts a new test case with a descriptive message. It automatically increments the case number and logs the case description. The method supports printf-style formatting for dynamic case descriptions.
Parameters:
- format: A format string describing the test case
- args: Arguments for the format string
Returns:
- *R: The runner instance for method chaining
Example:
r.Case("Testing user authentication with valid credentials")
r.Case("Testing division by zero with divisor %d", 0)
Example ¶
// This example shows how to use Case method
// In a real test function, you would do:
// func TestCase(t *testing.T) {
// r := New(t, "Example Case")
// r.Case("this is a test case: %d", 1)
// }
fmt.Println("Test Case => Example Case")
fmt.Println("Case 1 -> this is a test case: 1")
Output: Test Case => Example Case Case 1 -> this is a test case: 1
func (*R) Caser ¶
Caser runs a test case with the given name and function. It combines Case and Run methods to create a named subtest with automatic case logging. This is useful for organizing related test scenarios under a common name.
Parameters:
- name: The name of the test case
- f: The test function to execute
Returns:
- *R: The runner instance for method chaining
Example:
r.Caser("Valid Login", func(t *testing.T) {
// Test valid login scenario
r.Require(login("user", "pass"), "Login should succeed")
})
Example ¶
// This example shows how to use Caser method
// In a real test function, you would do:
// func TestCaser(t *testing.T) {
// r := New(t, "Example Caser")
// r.Caser("should pass", func(tt *testing.T) {
// r.Pass("pass in subtest")
// })
// }
func (*R) Cases ¶
Cases runs a set of test cases, executing the provided function for each case. This method is designed for table-driven tests where you have multiple test scenarios with different inputs and expected outputs.
For each test case, it:
- Logs the case description using Case()
- Runs the case as a subtest using Run()
- Passes the case data to the test function
Parameters:
- cases: A slice of Case implementations containing test data
- f: The test function that will be executed for each case
Example:
cases := []got.Case{
got.NewCase("Valid Input", "hello", 5, false, nil),
got.NewCase("Empty Input", "", 0, false, nil),
}
r.Cases(cases, func(c got.Case, tt *testing.T) {
result := len(c.Input().(string))
r.Require(result == c.Want().(int), "Length should match expected")
})
Example ¶
// This example shows how to use Cases method
// In a real test function, you would do:
// func TestCases(t *testing.T) {
// r := New(t, "Example Cases")
// cases := []Case{
// NewCase("case1", 1, 1, false, nil),
// NewCase("case2", 2, 3, false, nil),
// }
// r.Cases(cases, func(c Case, tt *testing.T) {
// if c.Input() == c.Want() {
// r.Pass("input equals want")
// } else {
// r.Fail("input not equal want")
// }
// })
// }
func (*R) Fail ¶
Fail logs a failed assertion with a red X mark. Use this method to indicate that a test condition has failed. This method will mark the test as failed but will not stop execution.
Parameters:
- format: A format string describing the failed assertion
- args: Arguments for the format string
Example:
r.Fail("User authentication should have succeeded")
r.Fail("Value %d is outside expected range", 100)
Example ¶
// This example shows how to use Fail method
// In a real test function, you would do:
// func TestFail(t *testing.T) {
// r := New(t, "Example Fail")
// r.Fail("failed: %s", "error")
// }
fmt.Println("Test Case => Example Fail")
fmt.Println("\t✗ failed: error")
Output: Test Case => Example Fail ✗ failed: error
func (*R) FailNow ¶
FailNow checks a boolean condition and stops test execution if it fails. If the condition is true, it logs a pass message and continues. If the condition is false, it logs a fail message and immediately stops the test. This is useful for critical assertions that should halt the test if they fail.
Parameters:
- cond: The boolean condition to check
- desc: A description of what is being tested
- args: Arguments for the description format string
Example:
r.FailNow(db.IsConnected(), "Database connection is required for this test") r.FailNow(config.IsValid(), "Configuration must be valid to continue")
func (*R) Fatal ¶
Fatal logs a fatal error and immediately stops test execution. This method is equivalent to calling Fail() followed by t.FailNow(). Use this when a test cannot continue due to a critical failure.
Parameters:
- format: A format string describing the fatal error
- args: Arguments for the format string
Example:
r.Fatal("Database connection failed - cannot continue test")
r.Fatal("Critical system component %s is not available", "auth-service")
func (*R) GoroutineCount ¶
GoroutineCount logs the current goroutine count
func (*R) Pass ¶
Pass logs a successful assertion with a green checkmark. Use this method to indicate that a test condition has passed.
Parameters:
- format: A format string describing the successful assertion
- args: Arguments for the format string
Example:
r.Pass("User authentication succeeded")
r.Pass("Value %d is within expected range", 42)
Example ¶
// This example shows how to use Pass method
// In a real test function, you would do:
// func TestPass(t *testing.T) {
// r := New(t, "Example Pass")
// r.Pass("passed: %s", "ok")
// }
fmt.Println("Test Case => Example Pass")
fmt.Println("\t✓ passed: ok")
Output: Test Case => Example Pass ✓ passed: ok
func (*R) Require ¶
Require is a convenient assertion method that checks a boolean condition. If the condition is true, it logs a pass message; otherwise, it logs a fail message. This is the most commonly used assertion method for simple boolean checks.
Parameters:
- cond: The boolean condition to check
- desc: A description of what is being tested
- args: Arguments for the description format string
Example:
r.Require(user.IsAuthenticated(), "User should be authenticated") r.Require(len(items) > 0, "Items list should not be empty") r.Require(result == expected, "Result %d should equal %d", result, expected)
Example ¶
// This example shows how to use Require method
// In a real test function, you would do:
// func TestRequire(t *testing.T) {
// r := New(t, "Example Require")
// r.Require(true, "should pass")
// r.Require(false, "should fail")
// }
fmt.Println("Test Case => Example Require")
fmt.Println("\t✓ should pass")
fmt.Println("\t✗ should fail")
Output: Test Case => Example Require ✓ should pass ✗ should fail
func (*R) Run ¶
Run executes a subtest with the given name and function. It wraps testing.T.Run to provide a convenient way to run subtests while maintaining the fluent API pattern.
Parameters:
- name: The name of the subtest
- f: The test function to execute
Returns:
- *R: The runner instance for method chaining
Example:
r.Run("Database Connection", func(t *testing.T) {
// Test database connection
conn, err := connectDB()
r.NoErrf(err, "Database connection should succeed")
})
func (*R) RunParallel ¶
RunParallel runs tests in parallel
func (*R) SkipUnless ¶
SkipUnless skips the test unless the condition is true