3. THERE'S A LIBRARY FOR IT!THERE'S A LIBRARY FOR IT!
https://github.com/DATA-DOG/godog
4. ... AND THIS LIBRARY IS... AND THIS LIBRARY IS
AWESOME!AWESOME!
5.
6. ... BUT IT DOES SOME MAGIC... BUT IT DOES SOME MAGIC
7. ... BUT IT DOES SOME MAGIC... BUT IT DOES SOME MAGIC
it runs as an external program
8. ... BUT IT DOES SOME MAGIC... BUT IT DOES SOME MAGIC
it runs as an external program
creates a temporary main_test file
9. ... BUT IT DOES SOME MAGIC... BUT IT DOES SOME MAGIC
it runs as an external program
creates a temporary main_test file
it parses the temporary program's output
10. ... BUT IT DOES SOME MAGIC... BUT IT DOES SOME MAGIC
it runs as an external program
creates a temporary main_test file
it parses the temporary program's output
displays the ouput in gherkin's format
11. THERE'RE WEAKNESSES OF THISTHERE'RE WEAKNESSES OF THIS
SOLUTIONSOLUTION
doesn't use the standard testing package
12. THERE'RE WEAKNESSES OF THISTHERE'RE WEAKNESSES OF THIS
SOLUTIONSOLUTION
doesn't use the standard testing package
no good code coverage
13. THERE'RE WEAKNESSES OF THISTHERE'RE WEAKNESSES OF THIS
SOLUTIONSOLUTION
doesn't use the standard testing package
no good code coverage
no debugging the test code!
14. THERE'RE WEAKNESSES OF THISTHERE'RE WEAKNESSES OF THIS
SOLUTIONSOLUTION
doesn't use the standard testing package
no good code coverage
no debugging the test code!
no built-in features like build tags
15. THE GLOBAL STATE!THE GLOBAL STATE!
// Godogs available to eat
var Godogs int
// somewhere in the test
func FeatureContext(s *godog.Suite) {
s.Step(`^there are (d+) godogs$`, thereAreGodogs)
s.Step(`^I eat (d+)$`, iEat)
s.Step(`^there should be (d+) remaining$`, thereShoul
s.BeforeScenario(func(interface{}) {
Godogs = 0 // clean the state before every sce
})
}
16. THAT'S WHYTHAT'S WHY EXISTSEXISTS
Main goals:
GOBDDGOBDD
https://github.com/go-bdd/gobdd
17. THAT'S WHYTHAT'S WHY EXISTSEXISTS
Main goals:
no magic
GOBDDGOBDD
https://github.com/go-bdd/gobdd
18. THAT'S WHYTHAT'S WHY EXISTSEXISTS
Main goals:
no magic
easy to use
GOBDDGOBDD
https://github.com/go-bdd/gobdd
22. KEY FEATURES:KEY FEATURES:
uses gherkin syntax
uses standard testing package
allows debugging and profiling the application
uses context between steps
23. QUICK STARTQUICK START
go get github.com/go-bdd/gobdd
func TestScenarios(t *testing.T) {
suite := gobdd.NewSuite(t)
suite.AddStep(`I add (d+) and (d+)`, add)
suite.AddStep(`I the result should equal (d+)`, check
suite.Run()
}
# features/my.feature
Feature: math operations
Scenario: add two digits
When I add 1 and 2
Then I the result should equal 3
26. THE CONTEXTTHE CONTEXT
holds the data from previous steps
holds step's parameters fetched from the step’s
definition (may change)
27. THE CONTEXTTHE CONTEXT
holds the data from previous steps
holds step's parameters fetched from the step’s
definition (may change)
easier parallelism
28. THE CONTEXTTHE CONTEXT
holds the data from previous steps
holds step's parameters fetched from the step’s
definition (may change)
easier parallelism
The goal: hold every required information about the
step itself to be successfully executed.
29. THE CONTEXTTHE CONTEXT
Passing information between tests
// in the first step
ctx.Set(name{}, "John")
// in the second step
fmt.Printf("Hi %sn", ctx.GetString(name{})) // prints "Hi Joh
30. THE CONTEXTTHE CONTEXT
List of functions for getting the data
Context.GetInt(key interface{}, [defaultValue]) int
Context.GetFloat32(key interface{}, [defaultValue])
float32
Context.GetFloat64(key interface{}, [defaultValue])
float64
Context.GetString(key interface{}, [defaultValue])
string
31. CREATING STEPSCREATING STEPS (MAY CHANGE)(MAY CHANGE)
Create a step by implementing the interface
Example:
type StepFunc func(ctx context.Context) error
func add(ctx context.Context) error {
res := ctx.GetIntParam(0) + ctx.GetIntParam(1)
ctx.Set("sumRes", res)
return nil
}
32. THE CHANGESTHE CHANGES
Example:
type StepFunc func(ctx context.Context, args ...interface{}) e
func add(ctx context.Context, var1, var2 int) error {
res := var1 + var2
ctx.Set("sumRes", res)
return nil
}
33. HANDING ERRORSHANDING ERRORS
every step returns an error
panics are always recovered and transformed to
error
if a parameter is not defined - the test fails
func (ctx Context) Get(key interface{}, defaultValue ...interf
if _, ok := ctx.values[key]; !ok {
if len(defaultValue) == 1 {
return defaultValue[0]
}
panic(fmt.Sprintf("the key %s does not exist",
}
return ctx.values[key]
}
34. TESTING THE API - THETESTING THE API - THE
TESTHTTP PACKAGETESTHTTP PACKAGE
Initialization
router := http.NewServeMux()
testhttp.Build(s, router)
36. EXAMPLEEXAMPLE
Feature: HTTP requests
Scenario: test GET request
When I make a GET request to "/health"
Then the response code equals 200
Scenario: not existing URI
When I make a GET request to "/not-exists"
Then the response code equals 404
Scenario: testing JSON validation
When I make a GET request to "/json"
Then the response contains a valid JSON
And the response is "{"valid": "json"}"
37. PRE-DEFINED STEPSPRE-DEFINED STEPS
I make a
(GET|POST|PUT|DELETE|OPTIONS)
request to "([^"]*)
the response code equals (d+)
the response contains a valid JSON
the response is "(.*)"
38. A SMALL PACKAGE -A SMALL PACKAGE -
Available assertions:
Equals
NotEquals
ObjectsAreEqual
Nil
NotNil
ASSERTASSERT
39. ASSERTASSERT
func TestEqual(t *testing.T) {
if err := assert.Equals(1, 2); err == nil {
t.Error(err)
}
if err := assert.Equals(1, func() {}); err == nil {
t.Error("it shouldn't validate func in the par
}
if err := assert.Equals(5, 5); err != nil {
t.Error(err)
}
}
46. WHAT NEXT?WHAT NEXT?
improving the testhttp package
write more packages (queues, reals API calls etc)
implement output formats (TeamCity, JUnit etc)
47. WHAT NEXT?WHAT NEXT?
improving the testhttp package
write more packages (queues, reals API calls etc)
implement output formats (TeamCity, JUnit etc)
support for concurrent test execution
48. WHAT NEXT?WHAT NEXT?
improving the testhttp package
write more packages (queues, reals API calls etc)
implement output formats (TeamCity, JUnit etc)
support for concurrent test execution
command line parameters
49. WHAT NEXT?WHAT NEXT?
improving the testhttp package
write more packages (queues, reals API calls etc)
implement output formats (TeamCity, JUnit etc)
support for concurrent test execution
command line parameters
whatever will come to my mind :)