{"id":17216272,"url":"https://github.com/nerandell/seamus","last_synced_at":"2025-04-13T23:21:46.354Z","repository":{"id":57465059,"uuid":"48430522","full_name":"nerandell/seamus","owner":"nerandell","description":"Python library that makes testing refactored code super simple.","archived":false,"fork":false,"pushed_at":"2023-01-15T12:10:00.000Z","size":24,"stargazers_count":11,"open_issues_count":4,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-27T13:39:34.679Z","etag":null,"topics":["python","testing","unittest"],"latest_commit_sha":null,"homepage":"http://seamus.readthedocs.io/","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/nerandell.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-22T12:22:53.000Z","updated_at":"2024-12-08T22:17:07.000Z","dependencies_parsed_at":"2023-02-09T22:01:23.961Z","dependency_job_id":null,"html_url":"https://github.com/nerandell/seamus","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerandell%2Fseamus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerandell%2Fseamus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerandell%2Fseamus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nerandell%2Fseamus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nerandell","download_url":"https://codeload.github.com/nerandell/seamus/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248782280,"owners_count":21160716,"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":["python","testing","unittest"],"created_at":"2024-10-15T03:27:20.637Z","updated_at":"2025-04-13T23:21:46.325Z","avatar_url":"https://github.com/nerandell.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"seamus\n======\n.. image:: https://api.travis-ci.org/nerandell/seamus.svg?branch=master\n    :target: https://travis-ci.org/nerandell/seamus\n.. image:: https://badge.fury.io/py/seamus.svg\n    :target: https://pypi.python.org/pypi/seamus\n.. image:: https://coveralls.io/repos/nerandell/seamus/badge.svg?branch=master\u0026service=github \n    :target: https://coveralls.io/github/nerandell/seamus?branch=master\n.. image:: https://readthedocs.org/projects/seamus/badge/?version=latest\n    :target: http://seamus.readthedocs.org/en/latest/?badge=latest\n    :alt: Documentation Status\n\nPython library that makes testing refactored code super simple. Inspired by scientist_ from github. The goal of `seamus` is to make testing of refactored code easy. Let's say that you decide to refactor a method in your code.\nBut if your code is running in production environment, it is too risky to roll out the refactored code directly. `seamus` comes to rescue here. You can use it with plenty of options offered to strategically test your refactored code in background leaving your end users unaffected. Once you are sure that the refactored code is behaving as expected, then you can roll it out.\n\n.. _scientist: https://github.com/github/scientist\n\nRequirements\n------------\n- Python \u003e= 3.2\n\nInstallation\n------------\n\n`seamus` can be installed via pip\n\n.. code-block:: bash\n\n    $ pip install seamus\n\nIt can also be installed from source:\n\n.. code-block:: bash\n\n    $ git clone https://github.com/nerandell/seamus\n    $ cd seamus \u0026\u0026 python setup.py install\n    \nUsage\n-----\nHere is a simple example : \n\n.. code-block:: python\n\n    from seamus import Seamus\n    \n    class SeamusExample:\n    \n        def add_numbers(self, num1, num2):\n            seamus = Seamus()\n            seamus.use(self._original_func, num1, num2)\n            seamus.test(self._refactored_func, num1, num2)\n            result = seamus.run()\n            return result\n    \n        def _original_func(self, num1, num2):\n            return num1 + 2 * num2 - num2 \n    \n        def _refactored_func(self, num1, num2):\n            return num1 + num2\n    \nIt is that simple. The result returned is always the actual result. However the refactored code is run by `seamus` in background and variety of inferences can be made on the basis of information obtained.\n\nHowever there is still a lot of boilerplate code here. To make things simpler, you can also use the decorator:\n\n.. code-block:: python\n\n    from seamus import seamus\n    \n    class SeamusExample:\n    \n        def add_numbers(self, num1, num2):\n            result = self._original_func(num1, num2)\n            return result\n    \n        @seamus(refactored_func=_refactored_func)\n        def _original_func(self, num1, num2):\n            return num1 + 2 * num2 - num2 \n    \n        def _refactored_func(self, num1, num2):\n            return num1 + num2\n\nThis makes the code concise. However currenly, ``seamus`` doesn't do a lot with the result. To make some use of the result, you have to override the publish method provided by ``Seamus`` class. \n\n.. code-block:: python\n    \n    from seamus import Seamus\n    \n    class ExtendedSeamus(Seamus):\n\n        def publish(self, is_equal):\n            print(is_equal)\n    \n    class SeamusExample:\n\n        def add_numbers(self, num1, num2):\n            seamus = ExtendedSeamus()\n            seamus.use(self._original_func, num1, num2)\n            seamus.test(self._refactored_func, num1, num2)\n            result = seamus.run()\n            return result\n    \n        def _original_func(self, num1, num2):\n            return num1 + 2 * num2 - num2 \n    \n        def _refactored_func(self, num1, num2):\n            return num1 + num2\n\nYou can also use the decorator with ``factory`` argument. ``factory`` can be just about\nany callable which returns an extended ``Seamus`` class or atleast quack like ``Seamus`` class (at your own risk).\n\n.. code-block:: python\n\n    from seamus import Seamus\n    \n    class ExtendedSeamus(Seamus):\n\n        def publish(self, is_equal):\n            print(is_equal)\n    \n    class SeamusExample:\n    \n        def add_numbers(self, num1, num2):\n            result = self._original_func(num1, num2)\n            return result\n    \n        @seamus(refactored_func=_refactored_func, factory=ExtendedSeamus)\n        def _original_func(self, num1, num2):\n            return num1 + 2 * num2 - num2 \n    \n        def _refactored_func(self, num1, num2):\n            return num1 + num2\n            \nBy default, to compare the result returned by actual and the refactored function, ``seamus`` uses ``==`` operator. \nHowever you can easily override it by passing comparator as an argument and it can return a ``true`` or a ``false`` value based on your own logic.\n\n.. code-block:: python\n\n    from seamus import Seamus\n    \n    class SeamusExample:\n    \n        def add_numbers(self, num1, num2):\n            result = self._original_func(num1, num2)\n            return result\n    \n        @seamus(refactored_func=_refactored_func, comparator=lambda x, y: x + 1 == y)\n        def _original_func(self, num1, num2):\n            return num1 + 2 * num2 - num2 \n    \n        def _refactored_func(self, num1, num2):\n            return num1 + num2\n            \nBy default, both the functions are run everytime, but what if you have to run the refactored version only a few times?\nYou can do that by providing a strategy.\n\n.. code-block:: python\n\n    from seamus import Seamus\n    \n    class SeamusExample:\n    \n        def add_numbers(self, num1, num2):\n            result = self._original_func(num1, num2)\n            return result\n    \n        @seamus(refactored_func=_refactored_func, run_strategy=lambda: random() \u003e 0.5)\n        def _original_func(self, num1, num2):\n            return num1 + 2 * num2 - num2 \n    \n        def _refactored_func(self, num1, num2):\n            return num1 + num2\n\nIn the above exmaple, the refactored version will only run 50% of the time.\n\nDocumentation\n-------------\nDocumentation is available here_\n\n.. _here : http://seamus.readthedocs.org\n\nLicense\n-------\n``seamus`` is offered under the MIT license.\n\nSource code\n-----------\nThe latest developer version is available in a github repository:\nhttps://github.com/nerandell/seamus\n\nOrigin of Name\n-------\nThe name is derived from Pink Floyd's song \"Seamus\" from the 1971 album Meddle. \n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnerandell%2Fseamus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnerandell%2Fseamus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnerandell%2Fseamus/lists"}