Skip to content

Instantly share code, notes, and snippets.

@lazywithclass
Last active February 20, 2017 02:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save lazywithclass/bc0e0a6bfb0bf2f76dc1d04974631fb8 to your computer and use it in GitHub Desktop.
Save lazywithclass/bc0e0a6bfb0bf2f76dc1d04974631fb8 to your computer and use it in GitHub Desktop.
 Contract testing and free documentation

## Contract testing and free documentation

"There's no such thing as free documentation, that's pain. Pain and sorrow. And the definition of out of date."

I'll be going through why I think that could be changed.

How

Contract integration testing

This is something I first read of on Martin Fowler's website, his definition is:

An integration contract test is a test at the boundary of an external service verifying that it meets the contract expected by a consuming service.

The idea is to have the consumers express their needs via some contracts, these contracts are then run when the producer is built, to verify that the expectations are still met.

There are quite a few tools to do so, I chose the last one because it felt simple enough to get started, so I will be using it in this post.

Anatomy of a contract

Please refer to the project for a comprehensive explanation.

tl;dr a contract is formed by a request and a set of expectations (using joi).

### Example

Let's say that we have a producer like so:

var express = require('express'), app = express()

app.get('/greet', function (req, res) {
  res.send('hello!')
})

app.listen(3000, function () { console.log('listening on 3000') })

Let's also say we have a consumer that expects "hello" to be in the response as plain text, along with a 200 status code, we would write something like:

var Contract = require('consumer-contracts').Contract,
    Joi = require('consumer-contracts').Joi

module.exports = new Contract({
  name: 'A friendly greet',
  consumer: 'conversation-starter',
  request: {
    method: 'GET',
    url: 'http://localhost:3000/greet'
  },
  response: {
    statusCode: 200,
    body: Joi.string().valid('hello!')
  }
});

You can now run consumer-contracts run contract.js, if everything goes as expected then you got this output:

  ✓ conversation-starter – A friendly greet


  1 passing

Enter swaggins

swaggins is a library I wrote that extract useful information from http.request and uses it to create documentation, using Swagger.

To get this free documentation you just need to put this line in one of your contracts (I'm working on removing the need for this):

require('swaggins').probe()

What that does is proxy http.request and extract information from the res object.

Here you could see the Swagger JSON definition extract by running the contract we defined, with swaggins wired in.

Now if you follow these steps you will see the docs, simple (I still need to filter out some headers, but you got the idea):

$ npm install -g swaggins
$ swaggins doc # copies swagger-ui and puts the JSON definition in it
$ swaggins serve # serves the docs with a simple HTTP server

If you got any comments or anything related to this approach or the tools used feel free to tell me, either email / open issue / whatever.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment