{"id":22211392,"url":"https://github.com/luttik/pytest-locker","last_synced_at":"2025-07-27T11:32:19.522Z","repository":{"id":45924444,"uuid":"267027332","full_name":"Luttik/pytest-locker","owner":"Luttik","description":"The fastest way to check for unexpected changes between test runs.","archived":false,"fork":false,"pushed_at":"2021-11-27T22:03:50.000Z","size":929,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-11-13T00:32:32.796Z","etag":null,"topics":["pytest","pytest-fixtures","python","testing"],"latest_commit_sha":null,"homepage":"https://pytest-locker.daanluttik.nl/","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Luttik.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-26T11:43:00.000Z","updated_at":"2024-05-08T14:08:35.000Z","dependencies_parsed_at":"2022-09-24T18:50:56.166Z","dependency_job_id":null,"html_url":"https://github.com/Luttik/pytest-locker","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Luttik%2Fpytest-locker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Luttik%2Fpytest-locker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Luttik%2Fpytest-locker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Luttik%2Fpytest-locker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Luttik","download_url":"https://codeload.github.com/Luttik/pytest-locker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":227800063,"owners_count":17821765,"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":["pytest","pytest-fixtures","python","testing"],"created_at":"2024-12-02T20:31:27.815Z","updated_at":"2024-12-02T20:31:28.994Z","avatar_url":"https://github.com/Luttik.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# PyTest-Locker\n\n\u003cimg src=\"https://raw.githubusercontent.com/Luttik/pytest-locker/master/docs/assets/images/logo-with-text.svg\" style=\"width: 100%; margin: 32pt 0\" alt=\"Example\"\u003e\n\n\u003cp align=\"center\"\u003e\n    PyTest-Locker: The fastest way to check for unexpected changes between test runs\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n    \u003ca href=\"https://github.com/Luttik/pytest-locker/actions?query=workflow%3ACI+branch%3Amaster\"\u003e\n        \u003cimg src=\"https://github.com/luttik/pytest-locker/workflows/CI/badge.svg\" alt=\"actions batch\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://pypi.org/project/pytest-locker/\"\u003e\n        \u003cimg src=\"https://badge.fury.io/py/pytest-locker.svg\" alt=\"pypi\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://pypi.org/project/pytest-locker/\"\u003e\n        \u003cimg src=\"https://shields.io/pypi/pyversions/pytest-locker\" alt=\"python versions\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://codecov.io/gh/luttik/pytest-locker\"\u003e\n        \u003cimg src=\"https://codecov.io/gh/Luttik/pytest-locker/branch/master/graph/badge.svg\" alt=\"codecov\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://xgithub.com/Luttik/pytest-locker/blob/master/LICENSE\"\u003e\n        \u003cimg src=\"https://shields.io/github/license/luttik/pytest-locker\" alt=\"License: MIT\"\u003e\n    \u003c/a\u003e\n    \u003ca href=\"https://github.com/psf/black\"\u003e\n        \u003cimg src=\"https://img.shields.io/badge/code%20style-black-000000.svg\" alt=\"Code style: black\"\u003e\n    \u003c/a\u003e\n\u003c/p\u003e\n\n## The general concept\nIn essense Pytest-Locker changes the basis of testing from having to assert everything that is relevant about an object\nto only having to assert that an object should not change unexpectedly (i.e. the object is locked).\n\nThis, of course, implies that the pytest-locker approach makes a lot of sense\nwhen the assertion logic becomes complex. I found it especially handy when testing if I'm sending the right API calls.\n\nSince objects can be just about anything in python\n(output, state, or even function calls via [mocking](https://docs.python.org/3/library/unittest.mock.html))\nyou can use this approach for just about everything.\n\nSince you need to validate if the object to lock is correct, both in the first run and after desired modifications,\nthe test flow is slightly different:\n\n\u003cimg class=\"invert-in-dark-mode\" src=\"https://raw.githubusercontent.com/Luttik/pytest-locker/master/docs/assets/images/pytest-locker-diagram.svg\" alt=\"pytest-locker's flow diagram\"/\u003e\n\n\n## Why use PyTest-Locker\n\n- Time efficient: No need to hard code expected responses. (Especially usefull for data heavy unittests)\n- Easy to verify changes:\n\n    - Seperates the logic of the test from the expected values.\n    - The lock files (containing the expected values), and changes to them, are easy to interpret. This makes it really\n      simple to evaluate changes during testing, in commits and in pull request.\n\n## Install\n\nrun `pip install pytest-locker`\n\n## Usage\n\n### Configuring the project and writing your first test.\n\n1. Add `from pytest_locker import locker` to your\n   [conftest.py](https://docs.pytest.org/en/2.7.3/plugins.html?highlight=re)\n   file\n2. To access the locker by adding it to the method parameters i.e. `def test_example(locker)`\n\n[comment]: \u003c\u003e (Also write todo for non-string types.)\n\n4. Use `locker.lock(your_string, optional_name)` to lock the data (of-course you can also lock other types).\n5. Ensure that the [pytest rootdir](https://docs.pytest.org/en/latest/customize.html) is fixed.\n     See [the pytest customize documentation](https://docs.pytest.org/en/latest/customize.html) for all the options (one\n     is adding a `pytest.ini` to the root folder)\n6. Ensure that `.pytest_locker/` is synced via git, to ensure that you, your team, and your CI/CD pipelines are working\n   with the same data.\n\nAnd you're all set!\n\n### Accepting the current behavior and checking fo changes in this behavior\n\nThere are two modes based on for locking. The first is\n\n1. When user input is allowed, i.e. when running pytest with\n   `--capture  no` or `-s`\n\n     When user input is allowed and the given data does not correspond to the data in the lock the *user is prompted* if\n     the new data should be stored or if the tests should fail.\n\n2. When user input is captured which is default behavior for pytest\n\n     If user input is not allowed the tests will *automatically fail* if the expected lock file does not exist or if the\n     data does not correspond to the data in the lock file.\n\n## The Locker class\n\nYou can also use `pytest_locker.Locker` (i.e. the class of which the\n`locker` fixture returns an instance) directly to create fixtures that locks a (non-string) object without needing to\nturn the object into a string it.\n\n## Examples\n\nFor example of use look at the tests in\n[repr-utils](https://github.com/Luttik/repr-utils).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluttik%2Fpytest-locker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fluttik%2Fpytest-locker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fluttik%2Fpytest-locker/lists"}