GithubHelp home page GithubHelp logo

aaahs / go-snaps Goto Github PK

View Code? Open in Web Editor NEW

This project forked from gkampitakis/go-snaps

0.0 0.0 0.0 935 KB

Jest-like snapshot testing in Golang ๐Ÿ“ธ

Home Page: https://pkg.go.dev/github.com/gkampitakis/go-snaps

License: MIT License

Go 99.39% Makefile 0.61%

go-snaps's Introduction

Go Snaps

Go Go Report Card Go Reference

Jest-like snapshot testing in Golang


Logo


App Preview Diff App Preview New

matchJSON and matchers are still under development that means their API can change. Use with caution and please share feedback for improvements.

Highlights

Installation

To install go-snaps, use go get:

go get github.com/gkampitakis/go-snaps

Import the go-snaps/snaps package into your code:

package example

import (
  "testing"

  "github.com/gkampitakis/go-snaps/snaps"
)

func TestExample(t *testing.T) {

  snaps.MatchSnapshot(t ,"Hello World")

}

MatchSnapshot

MatchSnapshot can be used to capture any type of data structured or unstructured.

You can pass multiple parameters to MatchSnapshot or call MatchSnapshot multiple times inside the same test. The difference is in the latter, it will create multiple entries in the snapshot file.

// test_simple.go

func TestSimple(t *testing.T) {
  t.Run("should make multiple entries in snapshot", func(t *testing.T) {
    snaps.MatchSnapshot(t, 5, 10, 20, 25)
    snaps.MatchSnapshot(t, "some value")
  })
}

go-snaps saves the snapshots in __snapshots__ directory and the file name is the test file name with extension .snap.

So for example if your test is called test_simple.go when you run your tests, a snapshot file will be created at ./__snapshots__/test_simple.snaps.

MatchJSON

MatchJSON can be used to capture data that can represent a valid json.

You can pass a valid json in form of string or []byte or whatever value can be passed successfully on json.Marshal.

func TestJSON(t *testing.T) {
  type User struct {
    Age int
    Email string
  }

  snaps.MatchJSON(t, `{"user":"mock-user","age":10,"email":"[email protected]"}`)
  snaps.MatchJSON(t, []byte(`{"user":"mock-user","age":10,"email":"[email protected]"}`))
  snaps.MatchJSON(t, User{10, "mock-email"})
}

JSON will be saved in snapshot in pretty format for more readability and deterministic diffs.

Matchers

MatchJSON's third argument can accept a list of matchers. Matchers are functions that can act as property matchers and test values.

You can pass a path of the property you want to match and test.

The path syntax is a series of keys separated by a dot. The dot and colon can be escaped with \.

Currently go-snaps has two build in matchers

  • match.Any
  • match.Custom
  • match.Type[ExpectedType]

match.Any

Any matcher acts as a placeholder for any value. It replaces any targeted path with a placeholder string.

Any("user.name")
// or with multiple paths
Any("user.name", "user.email")

Any matcher provides some methods for setting options

match.Any("user.name").
  Placeholder(value). // allows to define a different placeholder value from the default "<Any Value>"
  ErrOnMissingPath(bool) // determines whether the matcher will err in case of a missing, default true

match.Custom

Custom matcher allows you to bring your own validation and placeholder value

match.Custom("user.age", func(val interface{}) (interface{}, error) {
		age, ok := val.(float64)
		if !ok {
				return nil, fmt.Errorf("expected number but got %T", val)
		}

		return "some number", nil
})

The callback parameter value for JSON can be on of these types:

bool // for JSON booleans
float64 // for JSON numbers
string // for JSON string literals
nil // for JSON null
map[string]interface{} // for JSON objects
[]interface{} // for JSON arrays

If Custom matcher returns an error the snapshot test will fail with that error.

Custom matcher provides a method for setting an option

match.Custom("path",myFunc).
  Placeholder(value). // allows to define a different placeholder value from the default "<Any Value>"
  ErrOnMissingPath(bool) // determines whether the matcher will err in case of a missing path, default true

match.Type

Type matcher evaluates types that are passed in a snapshot and it replaces any targeted path with a placeholder in the form of <Type:ExpectedType>.

match.Type[string]("user.info")
// or with multiple paths
match.Type[float64]("user.age", "data.items")

Type matcher provides a method for setting an option

match.Type[string]("user.info").
  ErrOnMissingPath(bool) // determines whether the matcher will err in case of a missing path, default true

You can see more examples.

Configuration

go-snaps allows passing configuration for overriding

  • the directory where snapshots are stored, relative or absolute path
  • the filename where snapshots are stored
t.Run("snapshot tests", func(t *testing.T) {
  snaps.WithConfig(snaps.Filename("my_custom_name"), snaps.Dir("my_dir")).MatchSnapshot(t, "Hello Word")

  s := snaps.WithConfig(
    snaps.Dir("my_dir"),
    snaps.Filename("json_file"),
  )

  s.MatchJSON(t, `{"hello":"world"}`)
})

You can see more on examples

Update Snapshots

You can update your failing snapshots by setting UPDATE_SNAPS env variable to true.

UPDATE_SNAPS=true go test ./...

If you don't want to update all failing snapshots, or you want to update one of them you can you use the -run flag to target the test/s you want.

For more information for go test flags you can run

go help testflag

Clean obsolete snapshots

Summary Obsolete Summary Removed

go-snaps can identify obsolete snapshots.

In order to enable this functionality you need to use the TestMain(t*testing.M) and call snaps.Clean(t). This will also print a Snapshot Summary. (if running tests with verbose flag -v)

If you want to remove the obsolete snap files and snapshots you can run tests with UPDATE_SNAPS=true env variable.

The reason for using TestMain, is because go-snaps needs to be sure that all tests are finished so it can keep track which snapshots were not called.

Example:

func TestMain(t *testing.M) {
  v := t.Run()

  // After all tests have run `go-snaps` can check for not used snapshots
  snaps.Clean(t)

  os.Exit(v)
}

For more information around TestMain.

Skipping Tests

If you want to skip one test using t.Skip, go-snaps can't keep track if the test was skipped or if it was removed. For that reason go-snaps exposes a wrapper for t.Skip, t.Skipf and t.SkipNow, which keep tracks of skipped files.

You can skip, or only run specific tests by using the -run flag. go-snaps can identify which tests are being skipped and parse only the relevant tests for obsolete snapshots.

No Color

go-snaps supports disabling color outputs by running your tests with the env variable NO_COLOR set to any value.

NO_COLOR=true go test ./...

For more information around NO_COLOR.

Snapshots Structure

Snapshots have the form

[ TestName - Number ]
<data>
---

TestID is the test name plus an increasing number ( allowing to do multiple calls of MatchSnapshot inside a test ).

[TestSimple/should_make_a_map_snapshot - 1]
map[string]interface {}{
    "mock-0": "value",
    "mock-1": int(2),
    "mock-2": func() {...},
    "mock-3": float32(10.399999618530273),
}
---

*.snap files are not meant to be edited manually, this might cause unexpected results.

Acknowledgments

This library used Jest Snapshoting and Cupaloy as inspiration.

  • Jest is a full-fledged Javascript testing framework and has robust snapshoting features.
  • Cupaloy is a great and simple Golang snapshoting solution.
  • The logo was made by MariaLetta.

Notes

  1. โš ๏ธ When running a specific test file by specifying a path go test ./my_test.go, go-snaps can't track the path so it will mistakenly mark snapshots as obsolete.

  2. The order in which tests are written might not be the same order that snapshots are saved in the file.

  3. If your snapshot data contain the termination characters --- at the start of a line and after a new line, go-snaps will "escape" them and save them as /-/-/-/. This should not cause any diff issues (false-positives).

  4. Snapshots should be treated as code. The snapshot artifact should be committed alongside code changes, and reviewed as part of your code review process

go-snaps's People

Contributors

gkampitakis avatar renovate-bot avatar parasyris avatar

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.