diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 75a0c81d..e98d52f8 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -77,13 +77,6 @@ jobs: path: .coverage.* if-no-files-found: ignore - - name: Run CodSpeed benchmarks - uses: CodSpeedHQ/action@v2 - with: - token: ${{ secrets.CODSPEED_TOKEN }} - run: pytest --codspeed - if: matrix.python-version == '3.12' - coverage: name: Combine & check coverage. runs-on: ubuntu-latest @@ -122,6 +115,25 @@ jobs: path: htmlcov if: ${{ failure() }} + + codspeed: + name: Run CodSpeed benchmarks + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-python@v5 + with: + python-version-file: .python-version-default + cache: pip + - run: python -Im pip install tox-uv + + - name: Run CodSpeed benchmarks + uses: CodSpeedHQ/action@v2 + with: + token: ${{ secrets.CODSPEED_TOKEN }} + run: tox run -e codspeed + + docs: name: Build docs & run doctests runs-on: ubuntu-latest diff --git a/tests/test_functional.py b/tests/test_functional.py index 141b6b58..d4feb6e6 100644 --- a/tests/test_functional.py +++ b/tests/test_functional.py @@ -106,12 +106,12 @@ class WithMetaSlots(metaclass=Meta): FromMakeClass = attr.make_class("FromMakeClass", ["x"]) -@pytest.mark.benchmark() class TestFunctional: """ Functional tests. """ + @pytest.mark.benchmark() @pytest.mark.parametrize("cls", [C2, C2Slots]) def test_fields(self, cls): """ @@ -146,6 +146,7 @@ class TestFunctional: ), ) == attr.fields(cls) + @pytest.mark.benchmark() @pytest.mark.parametrize("cls", [C1, C1Slots]) def test_asdict(self, cls): """ @@ -181,6 +182,7 @@ class TestFunctional: assert "C3(_x=1)" == repr(C3(x=1)) + @pytest.mark.benchmark() @given(booleans(), booleans()) def test_programmatic(self, slots, frozen): """ @@ -338,6 +340,7 @@ class TestFunctional: """ assert Meta == type(cls) + @pytest.mark.benchmark() def test_default_decorator(self): """ Default decorator sets the default and the respective method gets @@ -541,6 +544,7 @@ class TestFunctional: assert "itemgetter" == attr.fields(C).itemgetter.name assert "x" == attr.fields(C).x.name + @pytest.mark.benchmark() def test_auto_exc(self, slots, frozen): """ Classes with auto_exc=True have a Exception-style __str__, compare and @@ -735,6 +739,7 @@ class TestFunctional: assert "_setattr('y', y)" in src assert object.__setattr__ != D.__setattr__ + @pytest.mark.benchmark() def test_unsafe_hash(self, slots): """ attr.s(unsafe_hash=True) makes a class hashable. diff --git a/tox.ini b/tox.ini index e2dd63e4..f6c94b4a 100644 --- a/tox.ini +++ b/tox.ini @@ -48,6 +48,17 @@ commands = coverage report +[testenv:codspeed] +extras = tests +pass_env = + CODSPEED_TOKEN + CODSPEED_ENV + ARCH + PYTHONHASHSEED + PYTHONMALLOC +commands = pytest --codspeed -n auto + + [testenv:docs] # Keep base_python in-sync with ci.yml/docs and .readthedocs.yaml. base_python = py312