# Mercurial Test Helpers
![test tube logo](https://foss.heptapod.net/mercurial/testhelpers/-/blob/branch/default/img/test_tube_icon_200.png)
This is a collection of facilities to help writing integration tests
for Python code around Mercurial: core development and extensions or other
downstreams like forges and graphical user interfaces.
It also provides a `coverage` plugin, allowing to check statements according to
the current Mercurial version.
See the [Integration Tests Plan wiki page](https://www.mercurial-scm.org/wiki/IntegrationTestsPlan) for more details.
This project is tested with its own helpers, so that many of the provided tests
can also be used as examples.
It has a 100% coverage policy, enforced by pre-landing continuous integration.
## FAQ
### Goal of the project
The goal is to include these test helpers in Mercurial core.
Once that happens, this project will serve to provide backwards compatibility,
especially for extensions that need to be compatible with
Mercurial versions that predate inclusion in core.
### Is pytest mandatory?
These helpers are just shortcuts to create setups easily and handle Mercurial
repositories. They don't depend themselves on a testing framework.
Only their own tests do.
Tighter integration with pytest will be provided as a separate project:
[pytest-mercurial](https://pypi.org/project/pytest-mercurial)
### What are the Python and Mercurial versions supported?
CPython 2.7, 3.7 and 3.8 are supported.
PyPy should work if Mercurial does,
except maybe for the discovery of Mercurial extensions used for tests skips.
Mercurial versions are those listed in [tox.ini](tox.ini).
As of this writing, these are Mercurial 4.3 to 5.9 on Python 2 and
5.3 to 5.9 on Python 3.
### Why not a generic Mercurial library?
The choices made are oriented towards being efficient (in particular fast) for
the task of writing tests. Some features wouldn't be legitimate in a
general-purpose library, for example random commit messages and file content.
On the other hand, some of the extra care about corner cases is not necessary:
users always have the option to go lower level if the helpers behave badly in
their case. This is much more acceptable in tests than in main application
code: it's better to add a missing test right away and reap the benefits
(non-regression, basis for main code refactors) than to postpone it for
breaking rules (not to say that technical debt does not exist in tests).
### Compatibility and stability
This project is too young and simple to get a clear picture of what will
happen, but we have reasons to be optimistic.
It was first started on Mercurial 5.2 and
turned out to easy to port down to 4.3. Forward compatibility won't be
a problem anyway once it's landed in Mercurial core.
The reason is that it calls Mercurial at a high level, actually often
through the functions that are right behind the command line interface.
For the same reasons that compatibility seems to be easy, providing stability
to downstream users shouldn't be too hard once we're settled about the basic
names.
Also, the fact that `bytes` are not mandatory in the API of the test helpers
is intended directly to help with the `bytes` vs `str` changes that
may happen after the final dismissal of Python 2 in Mercurial
(e.g `dict` keys and the like). While it's certain that such changes will be
painful for Mercurial developers, be it in the core or elsewhere,
at least if the tests setups keep working, we can hope that it will help a bit.
## Using the coverage plugin
The plugin has to be [activated in `.coveragerc`](https://coverage.readthedocs.io/en/coverage-5.3/plugins.html#using-plug-ins):
```
[run]
plugins = coverage_mercurial
```
Statements can then annotated with comments describing the versions of Mercurial
that are expected to run it. Example:
```python
from mercurial import util
if util.versiontuple() < (5, 4):
do_something() # hg<5.4
```
With the comment above, the `do_something()` statement will be excluded from
coverage when running with, e.g, Mercurial 5.5.
Details:
- only simple comparisons with `<`, `>`, `=`, `<=`, and `>=` are supported.
- no whitespace is allowed anywhere in the annotation itself. Leading and
trailing words in the comment should be ignored.
- it's not possible to create more complex rules with and/or logical
connectors. Current behaviour when using several markers is unspecified
and will change in some future release – don't depend on it.
- supported Mercurial versions are of type `x.y`. Neither broader
specifications (e.g., `hg<5`) nor more precise ones (e.g., `hg>4.8.2`)
are understood. What happens with them is also unspecified, and can
change in any future version.
## Running the tests of these test helpers
The quickest way to get a test run is to use
[tox](https://pypi.org/project/tox/), as this package comes with a
tox [configuration file](tox.ini) that defines a bunch of Python and Mercurial
combinations.
0. Pre-requisites:
- target Python version, available on `$PATH` as `python2` or `python3`
- required dependencies to build Mercurial from source (Python development
files, usually in a package called `python$VERSION-dev` or
`python$VERSION-devel`)
1. install tox
Versions provided by package managers are usually fine.
- Debian and derivatives: `apt install tox`
- Fedora: `dnf install python3-tox`
- MacPorts/HomeBrew: ?
- generic: `$somepython -m pip install tox`. This `$somepython` can be
completely different from those actually running the tests. Also tox is
among other things a `virtualenv` manager.
2. run for a precise Python and Mercurial version: `tox -e py3-hg-5.6`.
The first run will build Mercurial, the subsequent ones will be much
faster.
3. run tox for all combinations: `tox`
While the first run will be looong, as it will build Mercurial for all
version combinations, the subsequent ones are pretty reasonable:
```
$ time tox
(...)
____________ summary ____________
py3-hg5.6: commands succeeded
py3-hg5.5: commands succeeded
py3-hg5.4: commands succeeded
py3-hg5.3: commands succeeded
py2-hg5.6: commands succeeded
py2-hg5.5: commands succeeded
py2-hg5.4: commands succeeded
py2-hg5.3: commands succeeded
py2-hg5.2: commands succeeded
py2-hg5.1: commands succeeded
py2-hg5.0: commands succeeded
py2-hg4.9: commands succeeded
py2-hg4.8: commands succeeded
py2-hg4.7: commands succeeded
py2-hg4.6: commands succeeded
py2-hg4.5: commands succeeded
py2-hg4.4: commands succeeded
py2-hg4.3: commands succeeded
congratulations :)
tox 39.53s user 5.27s system 99% cpu 45.044 total
```
## Included examples, and how to run them
### examples/core
These are actual tests from Mercurial core, translated (case of `.t` tests)
or not (Python tests).
They are run as part of the main suite. If you already had a `tox` test run,
then you've tried them already.
`tests/test_repo_wrapper.py` is also a source of examples to get an idea of
what can be done.
### examples/evolve
These are toy examples of testing with the `evolve` and `topic` extensions,
and how the `hg-evolve` project could extend on these helpers.
To run them, one has to use the `run-all-tests` script in a context where
Mercurial and hg-evolve are available. Example:
```
python3 -m venv venv_hg_evolve
venv_hg_evolve/bin/pip install Mercurial==5.5.2 hg-evolve
source venv_hg_evolve/bin/activate
pip install -r test-requirements.txt
./run-all-tests
```
Remarks:
- For Python 2, start with `virtualenv -p python2`, then it's the same.
- Often, `mercurial` is not importable right after installation in a
virtualenv. That's why the first `pip` above was before activation.
- It's also possible to run only the hg-evolve examples:
```
pytest examples/hg_evolve
```
### examples/hg-git
Another toy example, this time with an additional integration need (Git itself).
Prerequisite: `git` standard executable, available on `$PATH`.
To run the tests, one has to use the `run-all-tests` script in a context where
Mercurial and hg-git are available. Example:
```
python3 -m venv venv_hg_git
venv_hg_git/bin/pip install Mercurial==5.6 hg-git
source venv_hg_git/bin/activate
pip install -r test-requirements.txt
./run-all-tests
```
Remarks:
- For Python 2, start with `virtualenv -p python2`, then it's the same.
- Often, `mercurial` is not importable right after installation in a
virtualenv. That's why the first `pip` above was before activation.
- It's also possible to run only the hg-git examples:
```
pytest examples/hg_git
```
## Credits
Test tube logo by User:Townie on Wikimedia Commons,
License Creative Commons by-sa international 4.0
## Changelog
### version 0.6.0 (2021-10-21)
- !11: new `RepoWrapper.reload()` method
- coverage plugin: support Mercurial versions 6.x
### version 0.5.0 (2021-02-17)
- #2: options for `datetime` and timezones in methods creating commits
- #3: generic helper to call commands, even without repository
- #4: helper method to create merge commits
### version 0.4.0 (2020-12-20)
- #5: keeping original path on `RepoWrapper`
- #6: helper methods for repository configuration (in-memory) and
`.hg/hgrc` writer.
Raw data
{
"_id": null,
"home_page": null,
"name": "mercurial-testhelpers",
"maintainer": null,
"docs_url": null,
"requires_python": null,
"maintainer_email": null,
"keywords": "hg mercurial testing",
"author": "Georges Racinet",
"author_email": "georges.racinet@octobus.net",
"download_url": "https://files.pythonhosted.org/packages/96/eb/0d72dc0611f2d9c1319a60f39f557ab5da048e860e56da10f5c0dbeb87c1/mercurial-testhelpers-0.7.0.tar.gz",
"platform": null,
"description": "# Mercurial Test Helpers\n![test tube logo](https://foss.heptapod.net/mercurial/testhelpers/-/blob/branch/default/img/test_tube_icon_200.png)\n\nThis is a collection of facilities to help writing integration tests\nfor Python code around Mercurial: core development and extensions or other\ndownstreams like forges and graphical user interfaces.\n\nIt also provides a `coverage` plugin, allowing to check statements according to\nthe current Mercurial version.\n\nSee the [Integration Tests Plan wiki page](https://www.mercurial-scm.org/wiki/IntegrationTestsPlan) for more details.\n\nThis project is tested with its own helpers, so that many of the provided tests\ncan also be used as examples.\n\nIt has a 100% coverage policy, enforced by pre-landing continuous integration.\n\n## FAQ\n\n### Goal of the project\n\nThe goal is to include these test helpers in Mercurial core.\n\nOnce that happens, this project will serve to provide backwards compatibility,\nespecially for extensions that need to be compatible with\nMercurial versions that predate inclusion in core.\n\n### Is pytest mandatory?\n\nThese helpers are just shortcuts to create setups easily and handle Mercurial\nrepositories. They don't depend themselves on a testing framework.\nOnly their own tests do.\n\nTighter integration with pytest will be provided as a separate project:\n[pytest-mercurial](https://pypi.org/project/pytest-mercurial)\n\n### What are the Python and Mercurial versions supported?\n\nCPython 2.7, 3.7 and 3.8 are supported.\n\nPyPy should work if Mercurial does,\nexcept maybe for the discovery of Mercurial extensions used for tests skips.\n\nMercurial versions are those listed in [tox.ini](tox.ini).\nAs of this writing, these are Mercurial 4.3 to 5.9 on Python 2 and\n5.3 to 5.9 on Python 3.\n\n### Why not a generic Mercurial library?\n\nThe choices made are oriented towards being efficient (in particular fast) for\nthe task of writing tests. Some features wouldn't be legitimate in a\ngeneral-purpose library, for example random commit messages and file content.\n\nOn the other hand, some of the extra care about corner cases is not necessary:\nusers always have the option to go lower level if the helpers behave badly in\ntheir case. This is much more acceptable in tests than in main application\ncode: it's better to add a missing test right away and reap the benefits\n(non-regression, basis for main code refactors) than to postpone it for\nbreaking rules (not to say that technical debt does not exist in tests).\n\n### Compatibility and stability\n\nThis project is too young and simple to get a clear picture of what will\nhappen, but we have reasons to be optimistic.\n\nIt was first started on Mercurial 5.2 and\nturned out to easy to port down to 4.3. Forward compatibility won't be\na problem anyway once it's landed in Mercurial core.\nThe reason is that it calls Mercurial at a high level, actually often\nthrough the functions that are right behind the command line interface.\n\nFor the same reasons that compatibility seems to be easy, providing stability\nto downstream users shouldn't be too hard once we're settled about the basic\nnames.\n\nAlso, the fact that `bytes` are not mandatory in the API of the test helpers\nis intended directly to help with the `bytes` vs `str` changes that\nmay happen after the final dismissal of Python 2 in Mercurial\n(e.g `dict` keys and the like). While it's certain that such changes will be\npainful for Mercurial developers, be it in the core or elsewhere,\nat least if the tests setups keep working, we can hope that it will help a bit.\n\n## Using the coverage plugin\n\nThe plugin has to be [activated in `.coveragerc`](https://coverage.readthedocs.io/en/coverage-5.3/plugins.html#using-plug-ins):\n\n```\n[run]\nplugins = coverage_mercurial\n```\n\nStatements can then annotated with comments describing the versions of Mercurial\nthat are expected to run it. Example:\n\n```python\nfrom mercurial import util\n\nif util.versiontuple() < (5, 4):\n do_something() # hg<5.4\n```\n\nWith the comment above, the `do_something()` statement will be excluded from\ncoverage when running with, e.g, Mercurial 5.5.\n\nDetails:\n\n - only simple comparisons with `<`, `>`, `=`, `<=`, and `>=` are supported.\n - no whitespace is allowed anywhere in the annotation itself. Leading and\n trailing words in the comment should be ignored.\n - it's not possible to create more complex rules with and/or logical\n connectors. Current behaviour when using several markers is unspecified\n and will change in some future release \u2013 don't depend on it.\n - supported Mercurial versions are of type `x.y`. Neither broader\n specifications (e.g., `hg<5`) nor more precise ones (e.g., `hg>4.8.2`)\n are understood. What happens with them is also unspecified, and can\n change in any future version.\n\n## Running the tests of these test helpers\n\nThe quickest way to get a test run is to use\n[tox](https://pypi.org/project/tox/), as this package comes with a\ntox [configuration file](tox.ini) that defines a bunch of Python and Mercurial\ncombinations.\n\n0. Pre-requisites:\n - target Python version, available on `$PATH` as `python2` or `python3`\n - required dependencies to build Mercurial from source (Python development\n files, usually in a package called `python$VERSION-dev` or\n `python$VERSION-devel`)\n\n1. install tox\n\n Versions provided by package managers are usually fine.\n\n - Debian and derivatives: `apt install tox`\n - Fedora: `dnf install python3-tox`\n - MacPorts/HomeBrew: ?\n - generic: `$somepython -m pip install tox`. This `$somepython` can be\n completely different from those actually running the tests. Also tox is\n among other things a `virtualenv` manager.\n\n2. run for a precise Python and Mercurial version: `tox -e py3-hg-5.6`.\n\n The first run will build Mercurial, the subsequent ones will be much\n faster.\n\n3. run tox for all combinations: `tox`\n\n While the first run will be looong, as it will build Mercurial for all\n version combinations, the subsequent ones are pretty reasonable:\n\n ```\n $ time tox\n (...)\n ____________ summary ____________\n py3-hg5.6: commands succeeded\n py3-hg5.5: commands succeeded\n py3-hg5.4: commands succeeded\n py3-hg5.3: commands succeeded\n py2-hg5.6: commands succeeded\n py2-hg5.5: commands succeeded\n py2-hg5.4: commands succeeded\n py2-hg5.3: commands succeeded\n py2-hg5.2: commands succeeded\n py2-hg5.1: commands succeeded\n py2-hg5.0: commands succeeded\n py2-hg4.9: commands succeeded\n py2-hg4.8: commands succeeded\n py2-hg4.7: commands succeeded\n py2-hg4.6: commands succeeded\n py2-hg4.5: commands succeeded\n py2-hg4.4: commands succeeded\n py2-hg4.3: commands succeeded\n congratulations :)\n tox 39.53s user 5.27s system 99% cpu 45.044 total\n ```\n\n## Included examples, and how to run them\n\n### examples/core\n\nThese are actual tests from Mercurial core, translated (case of `.t` tests)\nor not (Python tests).\n\nThey are run as part of the main suite. If you already had a `tox` test run,\nthen you've tried them already.\n\n`tests/test_repo_wrapper.py` is also a source of examples to get an idea of\nwhat can be done.\n\n### examples/evolve\n\nThese are toy examples of testing with the `evolve` and `topic` extensions,\nand how the `hg-evolve` project could extend on these helpers.\n\nTo run them, one has to use the `run-all-tests` script in a context where\nMercurial and hg-evolve are available. Example:\n\n```\npython3 -m venv venv_hg_evolve\nvenv_hg_evolve/bin/pip install Mercurial==5.5.2 hg-evolve\nsource venv_hg_evolve/bin/activate\npip install -r test-requirements.txt\n./run-all-tests\n```\n\nRemarks:\n\n - For Python 2, start with `virtualenv -p python2`, then it's the same.\n - Often, `mercurial` is not importable right after installation in a\n virtualenv. That's why the first `pip` above was before activation.\n - It's also possible to run only the hg-evolve examples:\n\n ```\n pytest examples/hg_evolve\n ```\n\n### examples/hg-git\nAnother toy example, this time with an additional integration need (Git itself).\n\nPrerequisite: `git` standard executable, available on `$PATH`.\n\nTo run the tests, one has to use the `run-all-tests` script in a context where\nMercurial and hg-git are available. Example:\n\n```\npython3 -m venv venv_hg_git\nvenv_hg_git/bin/pip install Mercurial==5.6 hg-git\nsource venv_hg_git/bin/activate\npip install -r test-requirements.txt\n./run-all-tests\n```\n\nRemarks:\n\n - For Python 2, start with `virtualenv -p python2`, then it's the same.\n - Often, `mercurial` is not importable right after installation in a\n virtualenv. That's why the first `pip` above was before activation.\n - It's also possible to run only the hg-git examples:\n\n ```\n pytest examples/hg_git\n ```\n\n## Credits\n\nTest tube logo by User:Townie on Wikimedia Commons,\nLicense Creative Commons by-sa international 4.0\n\n\n## Changelog\n\n### version 0.6.0 (2021-10-21)\n\n- !11: new `RepoWrapper.reload()` method\n- coverage plugin: support Mercurial versions 6.x\n\n### version 0.5.0 (2021-02-17)\n\n- #2: options for `datetime` and timezones in methods creating commits\n- #3: generic helper to call commands, even without repository\n- #4: helper method to create merge commits\n\n### version 0.4.0 (2020-12-20)\n\n- #5: keeping original path on `RepoWrapper`\n- #6: helper methods for repository configuration (in-memory) and\n `.hg/hgrc` writer.\n",
"bugtrack_url": null,
"license": "GPLv2+",
"summary": "Helpers to write Python tests involving Python internals of Mercurial",
"version": "0.7.0",
"project_urls": {
"Source": "https://foss.heptapod.net/mercurial/testhelpers",
"Tracker": "https://foss.heptapod.net/mercurial/testhelpers/-/issues"
},
"split_keywords": [
"hg",
"mercurial",
"testing"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "96eb0d72dc0611f2d9c1319a60f39f557ab5da048e860e56da10f5c0dbeb87c1",
"md5": "c1e1e88f0bfe01b253126d5f2f320586",
"sha256": "a83f2882409103777721b783a33d013595dfa51ed79abb599c7f349fd21c1108"
},
"downloads": -1,
"filename": "mercurial-testhelpers-0.7.0.tar.gz",
"has_sig": false,
"md5_digest": "c1e1e88f0bfe01b253126d5f2f320586",
"packagetype": "sdist",
"python_version": "source",
"requires_python": null,
"size": 24632,
"upload_time": "2024-04-02T15:30:25",
"upload_time_iso_8601": "2024-04-02T15:30:25.485303Z",
"url": "https://files.pythonhosted.org/packages/96/eb/0d72dc0611f2d9c1319a60f39f557ab5da048e860e56da10f5c0dbeb87c1/mercurial-testhelpers-0.7.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-04-02 15:30:25",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "mercurial-testhelpers"
}