Skip to content

Repository files navigation

Shutter

A birdie and insta inspired snapshot testing library for Go.

Snapshot review TUI

Installation

go get github.com/ptdewey/shutter

The review TUI is included in the module and can be installed as a standalone executable:

# executable is installed as `shutter`
go install github.com/ptdewey/shutter/cmd/shutter@latest

Usage

Basic Usage

package package_test
funcTestSomething(t*testing.T) {
result:=SomeFunction("foo")
shutter.Snap(t, "test title", result)
}

Snapshotting Multiple Values

Use SnapMany() when you need to snapshot multiple related values together:

funcTestMultipleValues(t*testing.T) {
request:=buildRequest()
response:=handleRequest(request)
// Snapshot both request and response togethershutter.SnapMany(t, "title", []any{request, response})
}

Advanced Usage: Scrubbers and Ignore Patterns

shutter supports data scrubbing and field filtering to handle dynamic or sensitive data in snapshots.

Scrubbers

Scrubbers transform content before snapshotting, typically to replace dynamic or sensitive data with placeholders:

funcTestUserAPI(t*testing.T) {
user:=api.GetUser("123")
// Replace UUIDs and timestamps with placeholdersshutter.Snap(t, "user", user,
shutter.ScrubUUID(),
shutter.ScrubTimestamp(),
)
}

Built-in Scrubbers:

  • ScrubUUID() - Replaces UUIDs with <UUID>
  • ScrubTimestamp() - Replaces ISO8601 timestamps with <TIMESTAMP>
  • ScrubEmail() - Replaces email addresses with <EMAIL>
  • ScrubIP() - Replaces IPv4 addresses with <IP>
  • ScrubJWT() - Replaces JWT tokens with <JWT>
  • ScrubCreditCard() - Replaces credit card numbers with <CREDIT_CARD>
  • ScrubAPIKey() - Replaces API keys with <API_KEY>
  • ScrubDate() - Replaces various date formats with <DATE>
  • ScrubUnixTimestamp() - Replaces Unix timestamps with <UNIX_TS>

Custom Scrubbers:

// Using regex patternsshutter.ScrubRegex(`user-\d+`, "<USER_ID>")
// Using exact string matchingshutter.ScrubExact("secret_value", "<REDACTED>")
// Using custom functionsshutter.ScrubWith(func(contentstring) string {
returnstrings.ReplaceAll(content, "localhost", "<HOST>")
})

Ignore Patterns

Ignore patterns remove specific fields from JSON structures before snapshotting:

funcTestAPIResponse(t*testing.T) {
response:=api.GetData()
jsonBytes, _:=json.Marshal(response)
// Ignore sensitive fields and null valuesshutter.SnapJSON(t, "response", string(jsonBytes),
shutter.IgnoreSensitive(),
shutter.IgnoreNull(),
shutter.IgnoreKey("created_at", "updated_at"),
)
}

Built-in Ignore Patterns:

  • IgnoreSensitive() - Ignores common sensitive keys (password, token, api_key, etc.)
  • IgnoreEmpty() - Ignores fields with empty string values
  • IgnoreNull() - Ignores fields with null values

Custom Ignore Patterns:

// Ignore specific keysshutter.IgnoreKey("id", "timestamp", "version")
// Ignore key-value pairsshutter.IgnoreKeyValue("status", "pending")
// Ignore keys matching a regex patternshutter.IgnoreKeyMatching(`^_.*`) // Ignore all keys starting with underscore// Ignore specific valuesshutter.IgnoreValue("null", "undefined", "")
// Using custom functionsshutter.IgnoreWith(func(key, valuestring) bool {
returnstrings.HasPrefix(key, "temp_")
})

Combining Options

You can combine multiple scrubbers and ignore patterns:

funcTestComplexData(t*testing.T) {
data:=generateTestData()
jsonBytes, _:=json.Marshal(data)
shutter.SnapJSON(t, "data", string(jsonBytes),
// First, remove unwanted fieldsshutter.IgnoreSensitive(),
shutter.IgnoreKey("debug_info"),
shutter.IgnoreNull(),
// Then, scrub dynamic values in remaining fieldsshutter.ScrubUUID(),
shutter.ScrubTimestamp(),
shutter.ScrubEmail(),
)
}

Note: Ignore patterns only work with SnapJSON(). Use scrubbers with Snap(), SnapMany(), or SnapString().

API Reference

Snapshot Functions:

// For single values (structs, maps, slices, etc.)shutter.Snap(t, "title", value, options...)
// For multiple related valuesshutter.SnapMany(t, "title", []any{value1, value2, value3}, options...)
// For JSON strings (supports both scrubbers and ignore patterns)shutter.SnapJSON(t, "title", jsonString, options...)
// For plain stringsshutter.SnapString(t, "title", content, options...)

Reviewing Snapshots

To review a set of snapshots, run (CLI version -- not recommended):

go run github.com/ptdewey/shutter/cmd/cli review

Shutter can also be used programmatically:

// Example: tools/shutter/main.gopackage main
import"github.com/ptdewey/shutter"funcmain() {
// This will start the CLI review toolshutter.Review()
}

Which can then be run with:

go run tools/shutter/main.go

Shutter also includes (in a separate Go module) a Bubbletea TUI in cmd/tui/main.go. (The TUI is shipped in a separate module to make the added dependencies optional)

TUI Usage

After installing the TUI:

shutter

Interactive Controls

  • a - Accept current snapshot
  • r - Reject current snapshot
  • s - Skip current snapshot
  • A - Accept all remaining snapshots
  • R - Reject all remaining snapshots
  • S - Skip all remaining snapshots
  • q - Quit

Alternative Commands

# Accept all new snapshots without review
shutter accept-all
# Reject all new snapshots without review
shutter reject-all

Other Libraries

About

Approval-based snapshot testing library for Go

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages