Coder Social home page Coder Social logo

cucumboa-go's Introduction

Cucumboa

Helpers for using cucumber to describe OpenAPI schemas in go


Why?

OpenApi schemas are great at describing the structure of your API. You can list all the possible response status codes for your endpoints and the data models they might return, but that's where it stops. They don't describe the API's behaviour. In what situations would a 404 status be returned? Which model from an anyOf schema will I receive if I pass an invalid query param?

Behavioural tests help to solve this problem. By using cucumber to describe the behaviours of the API service it allows us to document these behaviours in a way that is both easy to understand as a consumer but also easy to generate tests for to automatically validate the implementation.

Example

Scenario: Testing the GetPet endpoint

    Feature: Successfully retrieving a Pet
        Given pet '1234' exists
        When the 'Find pet by ID' operation is called with path params:
            | petId | 1234 |
        Then the response status will be '200'

    Feature: Invalid Id supplied
        When the 'Find pet by ID' operation is called with path params:
            | petId |  this_isnt_a_number |
        Then the response status will be '400'

    Feature: Requesting a nonexistant pet
        Given pet '9876' does not exist
        When the 'Find pet by ID' operation is called with path params:
            | petId |  9876 |
        Then the response status will be '404'

Installation

go get github.com/obfu5c8/cucumboa

Getting Started

// spec_test.go


// Load our OpenApi schema
var schema = cucumboa.MustLoadOpenApiSchemaFromFile("../../../api/openapi.yml")


func initializeScenario(ctx *godog.ScenarioContext) {

	// Create the API http.Handler from our server implementation
	httpHandler := myApi.NewHttpHandler()

	// Create a dispatcher to allow cucumboa to send requests to our API
	dispatcher := cucumboa.CreateHandlerDispatcher(httpHandler)

	// Initialise cucumboa against the scenario
	cucumboa.InitializeScenario(ctx, cucumboa.Options{
		Schema:     schema,
		Dispatcher: dispatcher,
	})
}

func TestApiSpec(t *testing.T) {

	suite := godog.TestSuite{
		ScenarioInitializer: InitializeScenario,
		Options: &godog.Options{
			Format:   "pretty",
			Paths:    []string{"./example.feature"},
			TestingT: t, // Testing instance that will run subtests.
		},
	}

	if suite.Run() != 0 {
		t.Fatal("non-zero status returned, failed to run feature tests")
	}
}

Built-in Steps

Request configuration

... the {name} operation is called

... the {name} operation is called with {param}: '{value}'

... the {name} operation is called with path params: <table>

Response Assertions

... the response status will be '{code}'

... the content will have values: <table>

Extending with a DSL

While cucumboa provides some great built-in steps for testing any generic OpenApi service, sometimes they can seem a bit verbose and clutter the view of the specification. To make the spec cleaner to read you can also extend the provided steps to create a DSL for your service.

Example

Scenario: Comparing DSL & vanilla steps
    
    Feature: Using the vanilla steps
        Given pet '1234' does not exist
        When the 'Find pet by ID' operation is called with path params:
            | petId | 1234 |
        Then the response status will be '404'
        And the content will contain values:
            | error.code | 0x234 |

    Feature: Wrapping in a custom DSL
        Given pet '1234' does not exist
        When the 'Find pet by ID' operation is called with id '1234'
        Then the response status will be '404'
        And the error code will be '0x234'
type DSL struct {
    c *cucumboa.Context
}

func (dsl *DSL) CallOperationWithIdPathParamStep(operation string, id string) error {
    dsl.c.SetOperation(operation)
    dsl.c.SetPathParams(map[string]string{
        petId: id
    })
    return nil
}

func (dsl *DSL) AssertResponseContentErrorCodeStep(code string) {
    dsl.c.AssertResponseContentContainsValues(map[string]string{
        code: code,
    })

}

cucumboa-go's People

Contributors

obfu5c8 avatar

Watchers

 avatar

Forkers

0xc0d3d00d

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.