(pytest_plugin)=
With libvcs's pytest plugin for pytest, you can easily create Git, SVN, and Mercurial repositories on the fly.
Looking for more flexibility, correctness, or power? Need different defaults? [Connect with us] on GitHub. We'd love to hear about your use case—APIs won't be stabilized until we're confident everything meets expectations.
[connect with us]: https://github.com/vcs-python/libvcs/discussions
Install libvcs using your preferred Python package manager:
$ pip install libvcsPytest will automatically detect the plugin, and its fixtures will be available.
This pytest plugin works by providing pytest fixtures. The plugin's fixtures ensure that a fresh Git, Subversion, or Mercurial repository is available for each test. It utilizes session-scoped fixtures to cache initial repositories, improving performance across tests.
(recommended-fixtures)=
When the plugin is enabled and pytest is run, these overridable fixtures are automatically used:
- Create temporary test directories for:
/home/({func}home_path)/home/${user}({func}user_path)
- Set the home directory:
- Patch
$HOMEto point to {func}user_pathusing ({func}set_home)
- Patch
- Create configuration files:
.gitconfigvia {func}gitconfig.hgrcvia {func}hgconfig
- Set default VCS configurations:
- Use {func}
hgconfigforHGRCPATHvia {func}set_hgconfig - Use {func}
gitconfigforGIT_CONFIGvia {func}set_gitconfig
- Use {func}
- Set default commit names and emails:
- Name: {func}
vcs_name - Email: {func}
vcs_email - User (e.g.
user <email@tld>): {func}vcs_user - For git only: {func}
git_commit_envvars
- Name: {func}
These ensure that repositories can be cloned and created without unnecessary warnings.
To configure the above fixtures with autouse=True, add them to your conftest.py file or test file, depending on the desired scope.
Why aren't these fixtures added automatically by the plugin? This design choice promotes explicitness, adhering to best practices for pytest plugins and Python packages.
To set a temporary home directory, use the {func}set_home fixture with autouse=True:
import pytest
@pytest.fixture(autouse=True)
def setup(set_home: None):
passYou can override the default author used in {func}git_remote_repo and other
fixtures via {func}vcs_name, {func}vcs_email, and {func}vcs_user:
@pytest.fixture(scope="session")
def vcs_name() -> str:
return "My custom name"
Use the {func}set_gitconfig fixture with autouse=True:
import pytest
@pytest.fixture(autouse=True)
def setup(set_gitconfig: None):
passSometimes, set_getconfig via GIT_CONFIG doesn't apply as expected. For those
cases, you can use {func}git_commit_envvars:
import pytest
@pytest.fixture
def my_git_repo(
create_git_remote_repo: CreateRepoPytestFixtureFn,
gitconfig: pathlib.Path,
git_commit_envvars: "_ENV",
) -> pathlib.Path:
"""Copy the session-scoped Git repository to a temporary directory."""
repo_path = create_git_remote_repo()
git_remote_repo_single_commit_post_init(
remote_repo_path=repo_path,
env=git_commit_envvars,
)
return repo_pathUse the {func}set_hgconfig fixture with autouse=True:
import pytest
@pytest.fixture(autouse=True)
def setup(set_hgconfig: None):
passFor async testing with pytest-asyncio, libvcs provides async fixture variants:
Add pytest-asyncio to your test dependencies and configure strict mode:
# pyproject.toml
[tool.pytest.ini_options]
asyncio_mode = "strict"
asyncio_default_fixture_loop_scope = "function"- {func}
async_git_repo- An {class}~libvcs.sync._async.git.AsyncGitSyncinstance ready for testing async_create_git_remote_repo- Factory to create temporary git repositories
import pytest
@pytest.mark.asyncio
async def test_async_repo_operations(async_git_repo):
"""Test async repository operations."""
# async_git_repo is an AsyncGitSync instance
status = await async_git_repo.cmd.status()
assert 'On branch' in status
# Update the repo
await async_git_repo.update_repo()import pytest
from libvcs.sync._async.git import AsyncGitSync
@pytest.mark.asyncio
async def test_clone_repo(tmp_path, create_git_remote_repo):
"""Test cloning a repository asynchronously."""
remote = create_git_remote_repo()
repo = AsyncGitSync(
url=f'file://{remote}',
path=tmp_path / 'clone',
)
await repo.obtain()
assert (tmp_path / 'clone' / '.git').exists()See {doc}/topics/asyncio for more async patterns.
For usage examples, refer to libvcs's own tests/.
.. automodule:: libvcs.pytest_plugin
:members:
:inherited-members:
:private-members:
:show-inheritance:
:member-order: bysource