{"id":13809225,"url":"https://github.com/zachallaun/mneme","last_synced_at":"2025-04-12T14:55:54.330Z","repository":{"id":66338839,"uuid":"590950624","full_name":"zachallaun/mneme","owner":"zachallaun","description":"Snapshot testing for Elixir","archived":false,"fork":false,"pushed_at":"2024-10-29T13:13:18.000Z","size":13155,"stargazers_count":89,"open_issues_count":24,"forks_count":5,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-10-29T15:58:58.242Z","etag":null,"topics":["elixir","testing"],"latest_commit_sha":null,"homepage":"https://hex.pm/packages/mneme","language":"Elixir","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/zachallaun.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-01-19T15:40:17.000Z","updated_at":"2024-10-29T13:13:23.000Z","dependencies_parsed_at":"2023-03-10T23:50:53.295Z","dependency_job_id":"0d88103a-d56d-4c64-b08a-f9b1f2ecc716","html_url":"https://github.com/zachallaun/mneme","commit_stats":{"total_commits":190,"total_committers":1,"mean_commits":190.0,"dds":0.0,"last_synced_commit":"5cf2788ac4a264e74f04bca5a101710f3117ecf1"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachallaun%2Fmneme","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachallaun%2Fmneme/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachallaun%2Fmneme/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/zachallaun%2Fmneme/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/zachallaun","download_url":"https://codeload.github.com/zachallaun/mneme/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248586245,"owners_count":21128996,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["elixir","testing"],"created_at":"2024-08-04T01:02:11.409Z","updated_at":"2025-04-12T14:55:54.305Z","avatar_url":"https://github.com/zachallaun.png","language":"Elixir","funding_links":[],"categories":["Testing"],"sub_categories":[],"readme":"# /ˈniːmiː/ - Snapshot testing utilities for Elixir\n\n[![Hex.pm](https://img.shields.io/hexpm/v/mneme.svg)](https://hex.pm/packages/mneme)\n[![Docs](https://img.shields.io/badge/hexdocs-docs-8e7ce6.svg)](https://hexdocs.pm/mneme)\n[![CI](https://github.com/zachallaun/mneme/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/zachallaun/mneme/actions/workflows/ci.yml)\n\n\u003cp data-video\u003ehttps://gist.github.com/assets/503938/57073c2c-6243-4b17-a91f-b705f4524dc9\u003c/p\u003e\n\nMneme augments `ExUnit.Assertions` with a set of assertions that know how to update themselves.\nThis is sometimes called snapshot, approval, or golden master testing.\n\nWith Mneme, you write something like...\n\n```elixir\nauto_assert my_function()\n```\n\n...and next time you run your tests, Mneme:\n\n1. runs the code,\n2. generates a pattern from the result,\n3. prints a diff,\n4. and asks if you'd like the test updated.\n\nWhen you say yes, your test now looks like this:\n\n```elixir\nauto_assert %MyAwesomeValue{so: :cool} \u003c- my_function()\n```\n\nThis lets you quickly write lots of tests, and like ordinary tests, you'll see when they fail.\nBut, unlike ordinary tests, Mneme asks if you'd like the test updated for the new value.\n\n**Features:**\n\n  * **Auto-updating assertions:** maintain correct tests as behavior changes during development.\n  * **Alternatives to familiar assertions:** `auto_assert`, `auto_assert_raise`, `auto_assert_receive`, `auto_assert_received`.\n  * **Seamless integration with ExUnit:** no need to change your workflow, just run `mix test`.\n  * **Interactive prompts in your terminal** when a new assertion is added or an existing one changes.\n  * **Syntax-aware diffs** highlight the meaningful changes in a value.\n  * **Built-in test watcher:** see changes immediately with `mix mneme.watch`.\n\n## Getting started\n\n1.  Add `:mneme` as a dependency in your `mix.exs`.\n\n    ```elixir\n    defp deps do\n      [\n        {:mneme, \"\u003e= 0.0.0\", only: :test}\n      ]\n    end\n    ```\n\n2.  Fetch dependencies and run `mix mneme.install` with `MIX_ENV=test`.\n    You're prompted with a diff before any files are saved.\n\n    ```shell\n    $ mix deps.get\n\n    # If MIX_ENV=test is not set, you will see a \"task could not be found\" error\n    $ MIX_ENV=test mix mneme.install\n    ```\n\n3.  Add `use Mneme` wherever you `use ExUnit.Case`.\n\n    ```elixir\n    defmodule MyTest do\n      use ExUnit.Case, async: true\n      use Mneme\n\n      test \"arithmetic\" do\n        auto_assert 2 + 2\n      end\n    end\n    ```\n\n4.  Run `mix test` and type `y\u003cENTER\u003e` when prompted.\n    The `auto_assert` call should be updated to:\n\n    ```elixir\n    auto_assert 4 \u003c- 2 + 2\n    ```\n\n## Interactive tour\n\nIf you'd like to see Mneme in action, you can download and run [examples/tour_mneme.exs](https://github.com/zachallaun/mneme/blob/main/examples/tour_mneme.exs), a standalone tour that only requires that you have Elixir installed.\nGive it a try without installing Mneme into your own project.\n\n```shell\n$ curl -o tour_mneme.exs https://raw.githubusercontent.com/zachallaun/mneme/main/examples/tour_mneme.exs\n\n$ elixir tour_mneme.exs\n```\n\n\n## Requirements\n\n### Elixir\n\nMneme requires Elixir version 1.14 or later.\n\n### Formatter\n\n**If you do not use a formatter, the first auto-assertion will reformat the entire file,** introducing unrelated formatting changes.\nMneme rewrites your test scripts when updating an assertion using the formatter configuration for your project.\n\nIt's highly recommended to configure your editor to format Elixir files on-save.\n\nSupported formatters:\n\n  * [`Mix.Tasks.Format`](https://hexdocs.pm/mix/Mix.Tasks.Format.html) (Elixir's default formatter)\n  * [`FreedomFormatter`](https://github.com/marcandre/freedom_formatter)\n\n## Command line interface\n\nAuto-assertions are run with your normal tests when you run `mix test` and a terminal prompt is used whenever one needs to be updated.\nHere's what that might look like:\n\n![Screenshot of Mneme CLI](https://github.com/zachallaun/mneme/blob/main/docs/assets/images/demo_screenshot.png?raw=true)\n\nWhenever that happens, you have a few options:\n\n|Key|Action|Description|\n|-|-|-|\n|`y`|Accept|Accept the proposed change. The assertion will be re-run and should pass.|\n|`n`|Reject|Reject the proposed change and fail the test.|\n|`s`|Skip|Skip this assertion. The test will not fail, but the `mix test` process will exit with `1`.|\n|`k`|Next|If multiple patterns have been generated, cycle to the next one.|\n|`K`|Last|If multiple patterns have been generated, cycle to the last one.|\n|`j`|Previous|If multiple patterns have been generated, cycle to the previous one.|\n|`J`|First|If multiple patterns have been generated, cycle to the first one.|\n\nNote that the CLI is not available when tests are run in a CI environment.\n\n## Continuous Integration\n\nIn a CI environment, Mneme will not attempt to prompt and update any assertions, but will instead fail any tests that would update.\nThis behavior is enabled by the `CI` environment variable, which is set by convention by many continuous integration providers.\n\n```bash\nexport CI=true\n```\n\n## Links and acknowledgements\n\nSpecial thanks to:\n\n  * [_What if writing tests was a joyful experience?_](https://blog.janestreet.com/the-joy-of-expect-tests/), from the Jane Street Tech Blog, for inspiring this library.\n\n  * [_My Kind of REPL_](https://ianthehenry.com/posts/my-kind-of-repl/), an article by Ian Henry that shows how snapshot testing can change your workflow.\n\n  * [Sourceror](https://github.com/doorgan/sourceror), a library that makes complex code modifications simple.\n\n  * [Rewrite](https://github.com/hrzndhrn/rewrite), which makes updating source code a breeze.\n\n  * [Owl](https://github.com/fuelen/owl), which makes it much easier to build a pretty CLI.\n\n  * [Insta](https://insta.rs/), a snapshot testing tool for Rust, whose great documentation provided an excellent reference for snapshot testing.\n\n  * [assert_value](https://github.com/assert-value/assert_value_elixir), an existing Elixir project that provides similar functionality.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzachallaun%2Fmneme","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fzachallaun%2Fmneme","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fzachallaun%2Fmneme/lists"}