Documentation
¶
Index ¶
- type ClientTestResult
- type ClientTestResults
- type ExternalClientSuite
- func (suite *ExternalClientSuite) ExpectFail(results ClientTestResults, lineIndex int, out interface{}, ...)
- func (suite *ExternalClientSuite) ExpectFailStatus(results ClientTestResults, lineIndex int, status int)
- func (suite *ExternalClientSuite) ExpectPass(results ClientTestResults, lineIndex int, out interface{}, ...)
- func (suite *ExternalClientSuite) StartService(addr string, handler http.Handler)
- func (suite *ExternalClientSuite) StopService()
- type Sequence
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type ClientTestResult ¶
type ClientTestResult struct {
// Pass is true when the line started with "OK", false otherwise.
Pass bool
// Output is the raw characters output to stdout for this interaction.
Output []byte
}
ClientTestResult decodes a single output line of stdout from a client test runner. It parses "OK {...}" or "FAIL {...}" and makes it easier for your test assertion code to work with.
func (ClientTestResult) Decode ¶
func (res ClientTestResult) Decode(out interface{}) error
Decode overlays this output line's JSON on top of the 'out' parameter (i.e. the stuff after OK/FAIL).
func (ClientTestResult) String ¶
func (res ClientTestResult) String() string
String just regurgitates the original output line.
type ClientTestResults ¶
type ClientTestResults []ClientTestResult
ClientTestResults encapsulates all of the output lines from a client test runner.
func ParseClientTestOutput ¶
func ParseClientTestOutput(stdout []byte) ClientTestResults
ParseClientTestOutput accepts the entire stdout of RunClientTest and parses each line to determine how each interaction in the test case behaved. Here is a sample output of a runner that performed 5 client calls to the backend service; 3 that passed and 2 that failed.
OK {"result": 5}
FAIL {"message": "divide by zero", "status": 400}
OK {"result": 3.14}
OK {"result": 10, "remainder": 2}
FAIL {"message": "overflow", "status": 400}
All language runners should output in this format for this to work. It's a convention that allows us to build assertions in Go regardless of how the target language does its work.
func RunClientTest ¶
func RunClientTest(executable string, args ...string) (ClientTestResults, error)
RunClientTest executes the language-specific runner to execute a single test case in that language. The result of the runner's execution are written to stdout w/ each interaction on a separate line. This will delegate to ParseClientTestOutput() to turn it into an easily workable value that you can hit with your Go assertions.
type ExternalClientSuite ¶
ExternalClientSuite is a test suite that validates the behavior of service clients generated for languages other than Go. It relies on you having a "runner" executable in the client's target language that runs one of the test cases we want to test and parses stdout of that program to determine whether the test should pass/fail.
The suite contains the logic to fire up a local instance of the gateway for the client to hit on the desired port as well as the ability to shut it down after the test. You can then analyze each line of stdout to determine if each interaction behaved as expected and write your Go assertions based on that. There will be more detail in the Frodo architecture markdown docs as to how this all works.
func (*ExternalClientSuite) ExpectFail ¶
func (suite *ExternalClientSuite) ExpectFail(results ClientTestResults, lineIndex int, out interface{}, additionChecks ...func())
ExpectFail analyzes line N (zero-based) of the client runner's output and asserts that it was a failed interaction (e.g. output was "FAIL { ... some json ... }"). It will decode the right-hand-side JSON onto your 'out' parameter so that you can also run custom checks to fire after the decoding is complete to ensure that the actual output error is what you expect.
err := errors.RPCError{}
suite.ExpectFail(output, 0, &response, func() {
suite.Contains(err.Message, "divide by zero")
})
func (*ExternalClientSuite) ExpectFailStatus ¶
func (suite *ExternalClientSuite) ExpectFailStatus(results ClientTestResults, lineIndex int, status int)
ExpectFailStatus analyzes line N (zero-based) of the client runner's output and asserts that it was a failed interaction (e.g. output was "FAIL { ... some json ... }"). It assumes that the right-hand JSON conforms to Frodo's RPCError such that there's a 'status' and 'message' field and that the status is equivalent to the one you supply. This is a convenience on top of ExpectFail to reduce verbosity.
// Assumes the first case failed w/ a 403 status, the second w/ a 502, and the last with a 500. suite.ExpectFailStatus(output, 0, 403) suite.ExpectFailStatus(output, 1, 502) suite.ExpectFailStatus(output, 2, 500)
func (*ExternalClientSuite) ExpectPass ¶
func (suite *ExternalClientSuite) ExpectPass(results ClientTestResults, lineIndex int, out interface{}, additionalChecks ...func())
ExpectPass analyzes line N (zero-based) of the client runner's output and asserts that it was a successful interaction (e.g. output was "OK { ... some json ... }"). It will decode the right-hand-side JSON onto your 'out' parameter so that you can also run custom checks to fire after the decoding is complete to ensure that the actual output value is what you expect.
response := calc.AddResponse{}
suite.ExpectPass(output, 0, &response, func() {
suite.Equal(12, response.Result)
})
func (*ExternalClientSuite) StartService ¶
func (suite *ExternalClientSuite) StartService(addr string, handler http.Handler)
StartService runs an instance of the gateway on the given address/port (e.g. ":9100"). Once this function returns you can fire off your client runner to hit this service.
func (*ExternalClientSuite) StopService ¶
func (suite *ExternalClientSuite) StopService()
StopService shuts down the running service gateway for the current test. It's safe so that if the server never started or shut down unexpectedly during the test, this will silently fail since the work is still done.
type Sequence ¶ added in v1.1.1
type Sequence struct {
// contains filtered or unexported fields
}
Sequence is a convenient way to capture a series of values in a specified order that you can use to determine if code was fired in a specific sequence/order.
func (*Sequence) Append ¶ added in v1.1.1
Append writes the next value for the piece of code that executed.
func (*Sequence) Reset ¶ added in v1.1.1
func (seq *Sequence) Reset()
Reset erases all current values in the sequence, allowing you to re-use this sequence multiple times within the same test case.