Skip to content

Eun/go-hit

Folders and files

NameName
Last commit message
Last commit date
Apr 5, 2024
Feb 10, 2021
Feb 10, 2021
Feb 10, 2021
Oct 4, 2021
Oct 4, 2021
Mar 4, 2021
Nov 28, 2023
Oct 28, 2020
Oct 4, 2021
Jul 24, 2019
Nov 23, 2020
Oct 7, 2021
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Mar 4, 2021
Nov 23, 2020
Mar 4, 2021
Mar 4, 2021
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Mar 4, 2021
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Nov 23, 2020
Oct 28, 2020
Nov 23, 2020
Nov 23, 2020
Oct 28, 2020
Nov 1, 2020
Nov 1, 2020
Oct 28, 2020
Oct 28, 2020
Nov 25, 2020
Oct 28, 2020
Nov 1, 2020
Oct 28, 2020
Nov 18, 2020
Oct 28, 2020
Oct 28, 2020
Nov 23, 2020
Nov 23, 2020
Nov 18, 2020
Oct 28, 2020
Oct 28, 2020
Oct 28, 2020
Oct 28, 2020
Oct 28, 2020
Oct 28, 2020
Oct 28, 2020
Oct 28, 2020
Oct 28, 2020
Mar 4, 2021
Mar 4, 2021
Mar 4, 2021
Mar 4, 2021
Oct 28, 2020
Oct 28, 2020
Oct 28, 2020
Oct 28, 2020
Oct 28, 2020
Oct 28, 2020
Oct 28, 2020
Nov 1, 2020
Nov 1, 2020
Nov 1, 2020
Mar 4, 2021
Nov 18, 2020
Mar 4, 2021
Nov 18, 2020
Mar 4, 2021
Mar 4, 2021
Nov 1, 2020
Nov 1, 2020
Nov 1, 2020
Nov 1, 2020
Nov 1, 2020
Oct 28, 2020
Nov 1, 2020
Nov 18, 2020
Nov 1, 2020
Nov 1, 2020
Nov 1, 2020
Nov 1, 2020
Nov 1, 2020
Nov 23, 2020
Nov 28, 2023
Nov 28, 2023
Nov 23, 2020
Feb 10, 2021
Mar 4, 2021
Nov 25, 2020
Oct 28, 2020
Oct 28, 2020
Feb 10, 2021
Nov 18, 2020
Feb 10, 2021
Nov 25, 2020
Nov 25, 2020
Nov 25, 2020
Nov 25, 2020
Nov 25, 2020
Nov 25, 2020
Oct 28, 2020
Nov 18, 2020
Nov 25, 2020
Nov 25, 2020
Nov 18, 2020
Mar 4, 2021
Nov 25, 2020
Nov 1, 2020
Feb 10, 2021
Nov 1, 2020
Oct 4, 2021
Nov 2, 2020
Nov 1, 2020
Nov 23, 2020
Nov 1, 2020
Nov 18, 2020
Nov 23, 2020
Nov 1, 2020
Nov 1, 2020
Oct 28, 2020

Repository files navigation

go-hit

Actions Status Coverage Status PkgGoDev GoDoc go-report go1.15

hit is an http integration test framework written in golang.

It is designed to be flexible as possible, but to keep a simple to use interface for developers.

So lets get started!

go get -u github.com/Eun/go-hit

package main

import (
    "net/http"
    . "github.com/Eun/go-hit"
)

func main() {
    MustDo(
        Description("Post to httpbin.org"),
        Get("https://httpbin.org/post"),
        Expect().Status().Equal(http.StatusMethodNotAllowed),
        Expect().Body().String().Contains("Method Not Allowed"),
    )
}

Or use the Test() function:

package main_test
import (
    "testing"
    "net/http"
    . "github.com/Eun/go-hit"
)

func TestHttpBin(t *testing.T) {
    Test(t,
        Description("Post to httpbin.org"),
        Get("https://httpbin.org/post"),
        Expect().Status().Equal(http.StatusMethodNotAllowed),
        Expect().Body().String().Contains("Method Not Allowed"),
    )
}

Expect, Expect, Expect, ....

MustDo(
    Get("https://httpbin.org/post"),
    Expect().Status().Equal(http.StatusMethodNotAllowed),
    Expect().Headers("Content-Type").NotEmpty(),
    Expect().Body().String().Contains("Method Not Allowed"),
)

Sending Data

MustDo(
    Post("https://httpbin.org/post"),
    Send().Body().String("Hello HttpBin"),
    Expect().Status().Equal(http.StatusOK),
    Expect().Body().String().Contains("Hello HttpBin"), 
)

Sending And Expecting JSON

MustDo(
    Post("https://httpbin.org/post"),
    Send().Headers("Content-Type").Add("application/json"),
    Send().Body().JSON(map[string][]string{"Foo": []string{"Bar", "Baz"}}),
    Expect().Status().Equal(http.StatusOK),
    Expect().Body().JSON().JQ(".json.Foo[1]").Equal("Baz"),
)

Storing Data From The Response

var name string
var roles []string
MustDo(
    Post("https://httpbin.org/post"),
    Send().Headers("Content-Type").Add("application/json"),
    Send().Body().JSON(map[string]interface{}{"Name": "Joe", "Roles": []string{"Admin", "Developer"}}),
    Expect().Status().Equal(http.StatusOK),
    Store().Response().Body().JSON().JQ(".json.Name").In(&name),
    Store().Response().Body().JSON().JQ(".json.Roles").In(&roles),
)
fmt.Printf("%s has %d roles\n", name, len(roles))

Problems? Debug!

MustDo(
    Post("https://httpbin.org/post"),
    Debug(),
    Debug().Response().Body(),
)

Handling Errors

It is possible to handle errors in a custom way.

func login(username, password string) error {
    err := Do(
         Get("https://httpbin.org/basic-auth/joe/secret"),
         Send().Headers("Authorization").Add("Basic " + base64.StdEncoding.EncodeToString([]byte(username + ":" + password))),
         Expect().Status().Equal(http.StatusOK),
    )
    var hitError *Error
    if errors.As(err, &hitError) {
        if hitError.FailingStepIs(Expect().Status().Equal(http.StatusOK)) {
            return errors.New("login failed")
        }
    }
    return err
}

Build the request url manually

MustDo(
    Request().Method(http.MethodPost),
    Request().URL().Scheme("https"),
    Request().URL().Host("httpbin.org"),
    Request().URL().Path("/post"),
    Request().URL().Query("page").Add(1),
    Expect().Status().Equal(200),
    Send().Body().String("Hello World"),
    Expect().Body().String().Contains("Hello"),
)

Twisted!

Although the following is hard to read it is possible to do!

MustDo(
    Post("https://httpbin.org/post"),
    Expect().Status().Equal(200),
    Send().Body().String("Hello World"),
    Expect().Body().String().Contains("Hello"),
)

Custom Send And Expects

MustDo(
    Get("https://httpbin.org/get"),
    Send().Custom(func(hit Hit) error {
        hit.Request().Body().SetStringf("Hello %s", "World")
        return nil
    }),
    Expect().Custom(func(hit Hit) error {
        if len(hit.Response().Body().MustString()) <= 0 {
            return errors.New("expected the body to be not empty")
        }
        return nil
    }),
    Custom(AfterExpectStep, func(Hit) error {
        fmt.Println("everything done")
        return nil
    }),
)

Templates / Multiuse

template := CombineSteps(
    Post("https://httpbin.org/post"),
    Send().Headers("Content-Type").Add("application/json"),
    Expect().Headers("Content-Type").Equal("application/json"),
)
MustDo(
    template,
    Send().Body().JSON("Hello World"),
)

MustDo(
    template,
    Send().Body().JSON("Hello Universe"),
)

Clean Previous Steps

Sometimes it is necessary to remove some steps that were added before.

template := CombineSteps(
    Get("https://httpbin.org/basic-auth/joe/secret"),
    Expect().Status().Equal(http.StatusOK),
)
MustDo(
    Description("login with correct credentials"),
    template,
    Send().Headers("Authorization").Add("Basic " + base64.StdEncoding.EncodeToString([]byte("joe:secret"))),
)

Test(t,
    Description("login with incorrect credentials"),
    template,
    Clear().Expect().Status(),
    Expect().Status().Equal(http.StatusUnauthorized),
    Send().Headers("Authorization").Add("Basic " + base64.StdEncoding.EncodeToString([]byte("joe:joe"))),
)

More examples can be found in the examples directory

Changelog

0.5.0

  • Rehaul the api, make things more explicit
  • Fix some issues
  • Store() functionality
  • Generate Clear() paths
  • Infinite JQ() functionality
  • Test README.md and documentation parts

0.4.0

  • Fixed a double run bug in CombineSteps (#3)
  • Better Clear functionality, you can now clear any previous step by prepending Clear(), eg.
    Do(
        Get("https://example.com"),
        Expect().Body("Hello World"),
        Clear().Expect(),                        // remove all previous Expect() steps
        // Clear().Expect().Body("Hello World"), // remove only the Expect().Body("Hello World") step
    )
    
    // also works for CombineSteps
    Do(
        Post("https://example.com"),        
        CombineSteps(
            Send().Body().String("Hello World"),
            Expect().Body("Hello World"),
        ),
        Clear().Expect(),
    )
  • Simplified Expect().Header() use, no more Expect().Headers(), everything can now be done in the Expect().Header() function.
  • More documentation and examples
  • hit.Do and hit.MustDo for inline steps.
  • Removal of inline steps (use hit.Do and hit.MustDo)
    Do(
        Get("https://example.com"),
        Expect().Custon(func (hit Hit) {
            // Expect("Hello World") is invalid now
            // you must use MustDo() or Do()
            hit.MustDo(
                Expect("Hello World"),
            )
        }),
    )
  • hit.InsertSteps to insert steps during runtime