Skip to content

Conversation

@noirbizarre
Copy link
Member

@noirbizarre noirbizarre commented Dec 29, 2025

Description

This PR fixes all raised warnings during tests (making it easier to read actual errors).

Moving from 30 warnings and a duration of ~40s:

image

to no warnings for a duration of less than 10s:

image

The time gained is because we don't rely on sleep anymore.

Checklist

Code Changes

  • ignore our own expected deprecation warnings in pyproject.toml
  • Introduce a time-controlled util: UtilFixture helper (freeze time with FreezeGun once required):
    • exposes all git operations in a time-controlled manner (each git operation advance time by 1s).
    • exposes a cli(*args) helper also time-controlled (underlying git operations have the time frozen too). Reduce the amount of boilerplate to execute the cli during tests
  • use this fixture instead all imported git helpers, including wait_for_tag in test_changelog_command.py (the only one still depending on wait_for_tag)
  • add missing type annotation in test_changelog_command (all but those based on legacy pytest tmpdir/py.path.local type which is badly typed)
  • update regression files depending on an invalid mocked date (1970-01-01)

The fixtures has not yet replaced helpers in other tests to reduce the size of the PR (will be done in separate pull requests)

Documentation Changes

None

Expected Behavior

Faster (no sleep) and fully deterministic (full control over time) tests execution.
Cleaner output (no more pages of warnings)
Easier to maintain tests

Steps to Test This Pull Request

Execute poetry test on master and this branch to observe the differences of execution (speed and output).

Additional Context

This was a long task but this was also (IMHO) required to make it easier to maintain tests on long term.
I'll update other test files when this one is merged

Fixes #1623

@codecov
Copy link

codecov bot commented Dec 29, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 97.81%. Comparing base (120d514) to head (72047ac).
⚠️ Report is 899 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1746      +/-   ##
==========================================
+ Coverage   97.33%   97.81%   +0.47%     
==========================================
  Files          42       60      +18     
  Lines        2104     2604     +500     
==========================================
+ Hits         2048     2547     +499     
- Misses         56       57       +1     
Flag Coverage Δ
unittests 97.81% <ø> (+0.47%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@noirbizarre noirbizarre enabled auto-merge (rebase) December 29, 2025 18:51
Copy link
Member

@Lee-W Lee-W left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is awesome! Just browsed through it Left a few nits and need some time to take a deeper look

Comment on lines +146 to +161
def cli(self, *args: str):
"""Execute commitizen CLI with given args."""
self.mocker.patch.object(sys, "argv", ["cz", *args])
cli.main()
self.tick()

def patch_env(self):
"""Patch environment variables to sync with FreezeGun time."""
self.monkeypatch.setenv("DATE", datetime.now().isoformat())
self.monkeypatch.setenv("GIT_AUTHOR_DATE", datetime.now().isoformat())
self.monkeypatch.setenv("GIT_COMMITTER_DATE", datetime.now().isoformat())

def tick(self):
"""Advance time by 1 second."""
self.freezer.tick()
self.patch_env()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def cli(self, *args: str):
"""Execute commitizen CLI with given args."""
self.mocker.patch.object(sys, "argv", ["cz", *args])
cli.main()
self.tick()
def patch_env(self):
"""Patch environment variables to sync with FreezeGun time."""
self.monkeypatch.setenv("DATE", datetime.now().isoformat())
self.monkeypatch.setenv("GIT_AUTHOR_DATE", datetime.now().isoformat())
self.monkeypatch.setenv("GIT_COMMITTER_DATE", datetime.now().isoformat())
def tick(self):
"""Advance time by 1 second."""
self.freezer.tick()
self.patch_env()
def cli(self, *args: str) -> None:
"""Execute commitizen CLI with given args."""
self.mocker.patch.object(sys, "argv", ["cz", *args])
cli.main()
self.tick()
def patch_env(self) -> None:
"""Patch environment variables to sync with FreezeGun time."""
self.monkeypatch.setenv("DATE", datetime.now().isoformat())
self.monkeypatch.setenv("GIT_AUTHOR_DATE", datetime.now().isoformat())
self.monkeypatch.setenv("GIT_COMMITTER_DATE", datetime.now().isoformat())
def tick(self) -> None:
"""Advance time by 1 second."""
self.freezer.tick()
self.patch_env()

Since we're returning None above, let's do it consistently. Would love to know whether we can have a better name than patch_env. It's no easy to understand at the first glance

raise exceptions.GitCommandError(c.err)
self.tick()

def current_branch(self) -> str:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def current_branch(self) -> str:
def get_current_branch(self) -> str:

raise exceptions.CommitError(c.err)
self.tick()

def branch(self, name: str):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def branch(self, name: str):
def create_branch(self, name: str):

raise exceptions.GitCommandError(c.err)
return c.out

def tag(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def tag(
def create_tag(

raise exceptions.CommitError(c.err)
self.tick()

def cli(self, *args: str):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def cli(self, *args: str):
def run_cli(self, *args: str):

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Remove wait_for_tag from tests to speed up test

2 participants