• Stars
    star
    939
  • Rank 48,301 (Top 1.0 %)
  • Language
    Go
  • License
    GNU General Publi...
  • Created over 8 years ago
  • Updated over 6 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Markdown based document-driven RESTful API testing.

Silk logo

silk Build Status Go Report Card

Markdown based document-driven web API testing.

Learn more

Video of Mat Ryer speaking about Silk

(VIDEO) Watch the talk about Silk (with slides) or read about Silk in this blog post.

Example Silk test file

Markdown API

Tests are made up of documents written in Markdown.

  • # Group - Top level headings represent groups of requests
  • ## GET /path - Second level headings represent a request
  • Code blocks with three back tics represent bodies
  • * Field: value - Lists describe headers and assertions
  • * ?param=value - Request parameters
  • --- seperators break requests from responses
  • Comments (starting with //) allow you to capture variables
  • Plain text is ignored to allow you to add documentation
  • Inline back tics are ignored and are available for formatting

Document structure

A document is made up of:

  • A request
  • --- seperator
  • Assertions

Requests

A request starts with ## and must have an HTTP method, and a path:

## METHOD /path

Examples include:

## GET /people

## POST /people/1/comments

## DELETE /people/1/comments/2

Request body (optional)

To specify a request body (for example for POST requests) use a codeblock using backtics (```):

```
{"name": "Silk", "release_year": 2016}
```

Request headers (optional)

You may specify request headers using lists (prefixed with *):

* Content-Type: "application/json"
* X-Custom-Header: "123"

Request parameters (optional)

Adding parameters to the path (like GET /path?q=something) can be tricky, especially when you consider escaping etc. To address this, Silk supports parameters like lists:

* ?param=value

The parameters will be correctly added to the URL path before the request is made.

Cookies

Setting cookies on a request can be done using the HTTP header pattern:

* Cookie: "key=value"

Assertions

Following the --- separator, you can specify assertions about the response. At a minimum, it is recommended that you assert the status code to ensure the request succeeded:

* Status: 200

You may also specify response headers in the same format as request headers:

* Content-Type: "application/json"
* X-MyServer-Version: "v1.0"

If any of the headers do not match, the test will fail.

Capturing data

Silk allows you to capture values at the point of asserting them and reuse them in future requests and assertions. To capture a value, include a comment on the line that mentions a {placeholder}:

* Data.UserID: /.*/ // The user's unique {id}.

The value from UserID (e.g. 123) will be stored in a variable called id, and you can refer to it later:

## GET /users/{id}

The above would be a request to GET /users/123.

  • Captured values are only available when assertions are successful

Environment variables

You can access environment variables inside Silk tests using the {$NAME} format, where NAME is the environment name.

Asserting cookies

To assert that a cookie is present in a response, make a regex assertion against the Set-Cookie HTTP header:

* Set-Cookie: /key=value/
  • All cookie strings are present in a single Set-Cookie seperated by a pipe character.

Validating data

You can optionally include a verbatim body using code blocks surrounded by three back tics. If the response body does not exactly match, the test will fail:

```
Hello world!
```

You can flag expected response bodies as json directly after the three back tics. This will assert that the actual response contains the same value for each expected key (recursively) allowing for differences in whitespace and ordering as well as being lenient towards additional (unexpected) keys in the response.

```json
{
    "id": 1,
    "release_year": 2016,
    "name": "Silk"
}
```

You can use the flag json(strict) to enforce that no additional fields may be present while still allowing for differences in whitespace and key order.

You may also make any number of regex assertions against the body using the Body object:

* Body: /Hello world/
* Body: /This should be found too/
* Body: /and this/

Alternatively, you can specify a list (using *) of data fields to assert accessible via the Data object:

* Status: 201
* Content-Type: "application/json"
* Data.name: "Silk"
* Data.release_year: 2016
* Data.tags[0]: "testing"
* Data.tags[1]: "markdown"
* Data[0].name: "Mat"
* Data[1].name: "David"
  • NOTE: Currenly this feature is only supported for JSON APIs.

Regex

Values may be regex, if they begin and end with a forward slash: /. The assertion will pass if the value (after being turned into a string) matches the regex.

* Status: /^2.{2}$/
* Content-Type: /application/json/

The above will assert that:

  • The status looks like 2xx, and
  • The Content-Type contains application/json

Command line

The silk command runs tests against an HTTP endpoint.

Usage:

silk -silk.url="{endpoint}" {testfiles...}
  • {endpoint} the endpoint URL (e.g. http://localhost:8080)
  • {testfiles} list of test files (e.g. ./testfiles/one.silk.md ./testfiles/two.silk.md)

Notes:

  • Omit trailing slash from endpoint
  • {testfiles} can include a pattern (e.g. /path/*.silk.md) as this is expended by most terminals to a list of matching files

Golang

Silk is written in Go and integrates seamlessly into existing testing tools and frameworks. Import the runner package and use RunGlob to match many test files:

package project_test

import (
  "testing"
  "github.com/matryer/silk/runner"
)

func TestAPIEndpoint(t *testing.T) {
  // start a server
  s := httptest.NewServer(yourHandler)
  defer s.Close()

  // run all test files
  runner.New(t, s.URL).RunGlob(filepath.Glob("../testfiles/failure/*.silk.md"))
}

Credit

  • Special thanks to @dahernan for his contributions and criticisms of Silk
  • Silk logo by Chris Ryer

More Repositories

1

xbar

Put the output from any script or program into your macOS Menu Bar (the BitBar reboot)
Go
17,483
star
2

xbar-plugins

Plugin repository for xbar (the BitBar reboot)
Shell
2,441
star
3

moq

Interface mocking tool for go generate
Go
1,884
star
4

is

Professional lightweight testing mini-framework for Go.
Go
1,731
star
5

vice

Go channels at horizontal scale (powered by message queues)
Go
1,539
star
6

goblueprints

Source code for Go Programming Blueprints
Go
1,346
star
7

gopherize.me

Gopherize.me app
JavaScript
649
star
8

try

Simple idiomatic retry package for Go
Go
332
star
9

way

HTTP routing for Go 1.7
Go
194
star
10

drop

Dependency-less dependencies for Go.
Go
120
star
11

goscript

Goscript: Runtime execution of Go code.
Go
103
star
12

runner

Interruptable goroutines
Go
99
star
13

respond

Idiomatic API responses for Go.
Go
84
star
14

resync

sync.Once with Reset()
Go
71
star
15

anno

Go package for text annotation.
Go
70
star
16

crunchcrunchcrunchstack

This repo is a starting point for a Go + Svelte.js + TailwindCSS project.
Go
63
star
17

golanguk

Source code for Golang UK talk - August 21st 2015, London.
Go
42
star
18

httperr

HTTP error wrapper
Go
35
star
19

articles

Source code repository for articles on https://medium.com/@matryer
Go
34
star
20

m

Get and Set using JavaScript notation
Go
31
star
21

pangaea

Powerful pre-processor for any kind of text file - powered by JavaScript
Go
29
star
22

version

Command line tool for versioning projects
Go
28
star
23

gae-records

Active Record like wrapper for Google App Engine Datasource in Go
Go
28
star
24

present

Presentations repository
Go
26
star
25

codeform

Easy Go code generation using templates
Go
25
star
26

filedb

File based storage and querying package
Go
23
star
27

mix

Go http.Handler that mixes many files into one request.
Go
13
star
28

captainslog

Logging package for Go
Go
12
star
29

persist

Persist loads and saves Go objects to files
Go
11
star
30

appengine

Example application for Google App Engine (As of November 2018)
Go
10
star
31

gocmds

Template for Go commands
Go
7
star
32

flower

In-process task flow management
Go
6
star
33

PathKit

Path tools for iOS and SpriteKit
Objective-C
6
star
34

oo

oo is the worlds simplest JavaScript OO implementation; for when you need classes and nothing else.
JavaScript
4
star
35

github-downloads

Tool (and Go package) for counting GitHub downloads
Go
4
star
36

str

String parsing package for Go. Converts strings to best guess value type.
Go
4
star
37

isvalid

Ultra simple data parsing and validation in Go
Go
3
star
38

codeform-templates

Repository of Codeform templates
Smarty
3
star
39

funkjs

A sweet selection of JavaScript funktion extensions
JavaScript
2
star
40

tailwindcss-github-theme

TailwindCSS GitHub theme for building GitHub styled apps using Tailwind.
2
star
41

rapid-api

Code for 3.5 hour workshop project at infoShare 2016
1
star
42

testing-in-go

Tutorial repo for Testing in Go talk
1
star
43

berlin-devfest-workshop

Code created during Berlin DevFest Workshop
Go
1
star
44

gimme

old location for github.com/matryer/drop
1
star