diff --git a/README.md b/README.md index e5c4bba..e8810d4 100644 --- a/README.md +++ b/README.md @@ -9,12 +9,12 @@ Snapshot testing is a technique in which the output of the subject under test is This is useful to: * understand and put legacy code under test -* obtain high code coverage when starting to refactor legacy -* test complex outputs (objects, files, etc) +* obtain high code coverage when starting to refactor legacy code or code that has no tests +* test complex outputs such as objects, files or similar -> Current Status: verify, approval and golden master mode. Test name customization. +**Current Status**: Verify, approval and golden master mode. Test name customization. Unstable API. -Mostly ready for use, but use it at your own risk until it becomes stable. Not all planned features are ready yet. +**Usage advice**: Mostly ready for use, but use it at your own risk until it becomes stable, that will happen when v1.0.0 is reached. Take into account that not all planned features are ready yet. Also, API is pretty stable, but it could change as we are researching the best options. ### Installation @@ -24,7 +24,7 @@ Standard Go module installation: go get -u github.com/franiglesias/golden ``` -### Basic Usage +### Basic Usage: Verify against an auto-generated snapshot A snapshot test is pretty easy to write. Capture the output of the subject under test and pass it to `golden.Verify`. That's all. @@ -36,13 +36,11 @@ func TestSomething(t *testing.T) { } ``` -The first time you run the test, a snapshot file will be generated at `__snapshots/TestSomething.snap` in the same package of the test. +The first time you run the test, a snapshot file will be generated at `__snapshots/TestSomething.snap` in the same package of the test. And the test will pass. The file will contain the output generated by the subject under test, provided that it can be serialized as JSON. -You can inspect the snapshot to check that it contains the output you expect. If you consider that the snapshot is not correct, simply delete it. Golden has you covered with the `ToApprove` method, see below. - -If the snapshot is ok for you, commit it with the code, so it can be used as comparison criteria in future runs. +If the snapshot is ok for you, commit it with the code, so it can be used as comparison criteria in future runs. If not, delete the file and run again. #### Customize the snapshot name @@ -63,6 +61,56 @@ This is useful if you need: * More than one snapshot in the same test * Use an externally generated file as snapshot. For example, if you want your code to replicate the output of another system, provided that you have an example. +### Basic Usage: Approval mode + +**Warning**: We are considering an alternative API for approval mode. + +Approval mode is useful when you are writing new code. In this mode, the snapshot is generated and updated but the test never passes. Why? Because you will need to inspect the snapshot until you are happy with it, and you _approve_ it. Once you are satisfied with the contents of the snapshot, you replace the`golden.ToApprove` with `golden.Verify`. This way, you "approve" the current snapshot. + +```go +func TestSomething(t *testing.T) { + output := SomeFunction("param1", "param2") + + golden.ToApprove(t, output) +} +``` + +The first time you run the test, a snapshot file will be generated at `__snapshots/TestSomething.snap` in the same package of the test. And the test **will not pass**. + +The file will contain the output generated by the subject under test, provided that it can be serialized as JSON. + +If the snapshot is ok for you, replace the ToApprove call to Verify, so it can be used as comparison criteria in future runs. If not, modify the code and run it again until the snapshot is fine. + +You can use the same options as with `Verify`. + +### Basic Usage: Golden Master mode + +**Warning**: We are considering an alternative API for golden master mode. + +Golden Master mode is useful when you want to generate a lot of tests combining different values of the subject under test parameters. It will generate all possible combinations and, it will create a detailed snapshot with all the results. Here is an example testing a `Division` function. + +You will need to create a wrapper function that exercises the subject under test managing both parameters and all return values, including errors. Basically, you need to manage to return a `string` representing the outcome of the SUT. + +```go +t.Run("should manage the error", func(t *testing.T) { + setUp(t) + f := func(args ...any) any { + result, err := Division(args[0].(float64), args[1].(float64)) + if err != nil { + return err.Error() + } + return result + } + + dividend := []any{1.0, 2.0} + divisor := []any{0.0, -1.0, 1.0, 2.0} + + gld.Master(t, f, dividend, divisor) +}) +``` + +The first time you run the test, a snapshot file will be generated at `__snapshots/should_manage_the_error.snap.json` in the same package of the test. This will be a JSON file with a description of the inputs and outputs of each generated test. The test itself will pass. + ## What is Golden? Golden is a library inspired by projects like [Approval Testing](https://approvaltests.com/). There are some other similar libraries out there, such as [Approval Tests](https://github.com/approvals/go-approval-tests), [Go-snaps](https://github.com/gkampitakis/go-snaps) or [Cupaloy](https://github.com/bradleyjkemp/cupaloy). diff --git a/golden.go b/golden.go index dee9e27..da255bd 100644 --- a/golden.go +++ b/golden.go @@ -86,12 +86,12 @@ review and approve the current snapshot. When you are totally ok with the snapshot, replace ToApprove with Verify in the test. */ -func (g *Golden) ToApprove(t Failable, subject any) { +func (g *Golden) ToApprove(t Failable, subject any, options ...Option) { g.Lock() g.test.approve = true g.Unlock() - g.Verify(t, subject) + g.Verify(t, subject, options...) } /* diff --git a/golden_approval_test.go b/golden_approval_test.go index 3dfc957..d309d68 100644 --- a/golden_approval_test.go +++ b/golden_approval_test.go @@ -50,7 +50,6 @@ func TestToApprove(t *testing.T) { /* Simulates the process of running approval tests until you obtain approval for the generated snapshot - */ t.Run("should accept snapshot at Verify", func(t *testing.T) { setUp(t) @@ -66,4 +65,23 @@ func TestToApprove(t *testing.T) { gld.Verify(&tSpy, "updated subject.") helper.AssertPassTest(t, &tSpy) }) + + /* + Simulates the process of running approval tests until you obtain approval for + the generated snapshot, but with custom snapshot file name + */ + t.Run("should work with custom snapshot", func(t *testing.T) { + setUp(t) + + gld.ToApprove(&tSpy, "starting subject.", golden.Snapshot("approval_snapshot")) + tSpy.Reset() + + // After this run the snapshot will be approved by an expert + gld.ToApprove(&tSpy, "updated subject.", golden.Snapshot("approval_snapshot")) + tSpy.Reset() + + // Last snapshot was approved, so we can change the test to Verification + gld.Verify(&tSpy, "updated subject.", golden.Snapshot("approval_snapshot")) + helper.AssertPassTest(t, &tSpy) + }) }