Introduce feature-based test directory structure#509
Conversation
6e44821 to
9a05335
Compare
9a05335 to
435bdb3
Compare
|
Test failures due to Galaxy: |
| pass | ||
| else: | ||
| feature = rel_path.parts[0] | ||
| item.add_marker(pytest.mark.feature(feature)) |
There was a problem hiding this comment.
This automatic marking is probably the only part that is semi-magical. However, as a convention I think this is fine. I think we should document this convention in our testing.md file.
Then a question. What about "meta" features? e.g. content/rpm, content/pypi
There was a problem hiding this comment.
This automatic marking is probably the only part that is semi-magical. However, as a convention I think this is fine. I think we should document this convention in our
testing.mdfile.
I also considered the magic. However, there is validation on invalid features and if we have the proper testing matrix we should exercise all code both with and without the feature present.
Good call on documenting it.
Then a question. What about "meta" features? e.g.
content/rpm,content/pypi
I've tried to keep it simple to avoid introducing too much magic. In #511 I've toyed with hiding Pulp behind a feature and the testing is IMHO the biggest task on introducing additional flavors.
My preference is to have very light testing in foremanctl and then the actual end-to-end tests in smoker. So I'd avoid introducing more magic and keep it simple. Assuming we hide Pulp behind the katello feature and then for tests:
tests/feature/katello/pulp_test.pytests/feature/katello/content_rpm_test.pytests/feature/katello/content_pypi_test.py
They will all be guarded behind the katello feature because of the directory structure. The content tests can use pytestmark at the top of the file to guard on both the katello feature and specific content types.
This sets up a directory structure where an entire directory gets a feature mark. This makes it easy to skip entire feature tests.
This guards it behind the feature flag, allowing the tests to be skipped if the feature is disabled. For example, on a standalone foreman-proxy.
435bdb3 to
467b828
Compare
|
With this we have foreman-proxy marker applied to all tests in |
| feature_dir = config.rootdir / 'tests' / 'feature' | ||
| for item in items: | ||
| try: | ||
| rel_path = Path(item.fspath).relative_to(feature_dir) |
There was a problem hiding this comment.
i see fspath is deprecated,so good to use path instead https://docs.pytest.org/en/stable/deprecations.html#fspath-argument-for-node-constructors-replaced-with-pathlib-path
There was a problem hiding this comment.
Neat, didn't know that was already supported. This will save me an import too.
| rel_path = Path(item.fspath).relative_to(feature_dir) | |
| rel_path = item.path.relative_to(feature_dir) |
Keeping it open for now to allow for more comments
Technically You can certainly create a standalone file and if you have a bunch of tests it makes sense to create import pytest
pytestmark = pytest.mark.feature('bmc')
def test_x():
pass
def test_y():
passThis will be equivalent to (today) creating import pytest
pytestmark = [pytest.mark.feature('foreman-proxy'), pytest.mark.feature('bmc')]
def test_x():
pass
def test_y():
passBut you can also create import pytest
def test_base():
pass
@pytest.mark.feature('bmc')
def test_bmc():
passAll of these are functionally equivalent and it depends on how we want to organize it. |
|
Yes, I was thinking about marking the bmc feature dynamically, so when foreman-proxy is enabled, base_test.py runs the base proxy tests, and if bmc is also enabled, bmc_test.py runs the BMC-specific tests. Not blocking, just a thought to make things more dynamic |
|
As noted in #509 (comment), I've tried to avoid making things too dynamic and magical. I still remember https://code.djangoproject.com/wiki/RemovingTheMagic and think that's a good thing: I like it when things are easily predictable. |
Fair, thanks |
|
Lets give coderabbit a try @coderabbitai review |
|
✅ Actions performedReview triggered.
|
WalkthroughThis PR refactors pytest feature-marker application by introducing a pytest collection hook that automatically applies markers to test items based on directory location under Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested reviewers
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
♻️ Duplicate comments (1)
tests/conftest.py (1)
246-257:⚠️ Potential issue | 🟡 Minor | ⚡ Quick winUse
item.pathinstead of deprecateditem.fspath.Line 250 uses
Path(item.fspath)which is deprecated in pytest. As previously suggested, useitem.path.relative_to(feature_dir)instead, which will also eliminate the need for thePathimport on line 4.Apply the previously suggested fix
-from pathlib import Pathdef pytest_collection_modifyitems(config, items): feature_dir = config.rootdir / 'tests' / 'feature' for item in items: try: - rel_path = Path(item.fspath).relative_to(feature_dir) + rel_path = item.path.relative_to(feature_dir) except ValueError: # Not in the features directory passVerify the deprecation status:
Is pytest's item.fspath deprecated in favor of item.path?🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/conftest.py` around lines 246 - 257, Replace the deprecated use of item.fspath in pytest_collection_modifyitems with item.path: change rel_path = Path(item.fspath).relative_to(feature_dir) to rel_path = item.path.relative_to(feature_dir) (keep the existing try/except ValueError behavior), and remove the now-unused Path import at the top of the file; this targets the pytest_collection_modifyitems function and eliminates the deprecated item.fspath usage.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Duplicate comments:
In `@tests/conftest.py`:
- Around line 246-257: Replace the deprecated use of item.fspath in
pytest_collection_modifyitems with item.path: change rel_path =
Path(item.fspath).relative_to(feature_dir) to rel_path =
item.path.relative_to(feature_dir) (keep the existing try/except ValueError
behavior), and remove the now-unused Path import at the top of the file; this
targets the pytest_collection_modifyitems function and eliminates the deprecated
item.fspath usage.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5afb9ce7-cb45-4d3a-8559-bfc1b332a090
📒 Files selected for processing (29)
docs/developer/testing.mdtests/conftest.pytests/feature/__init__.pytests/feature/foreman-proxy/__init__.pytests/feature/foreman-proxy/base_test.pytests/feature/foreman/__init__.pytests/feature/foreman/api_test.pytests/feature/foreman/base_test.pytests/feature/foreman/compute_resources_test.pytests/feature/foreman/plugins_test.pytests/feature/hammer/__init__.pytests/feature/hammer/base_test.pytests/feature/iop/__init__.pytests/feature/iop/test_advisor.pytests/feature/iop/test_advisor_frontend.pytests/feature/iop/test_cvemap_downloader.pytests/feature/iop/test_engine.pytests/feature/iop/test_gateway.pytests/feature/iop/test_ingress.pytests/feature/iop/test_integration.pytests/feature/iop/test_inventory.pytests/feature/iop/test_inventory_frontend.pytests/feature/iop/test_kafka.pytests/feature/iop/test_puptoo.pytests/feature/iop/test_remediation.pytests/feature/iop/test_vmaas.pytests/feature/iop/test_vulnerability.pytests/feature/iop/test_vulnerability_frontend.pytests/feature/iop/test_yuptoo.py
💤 Files with no reviewable changes (16)
- tests/feature/iop/test_kafka.py
- tests/feature/iop/test_remediation.py
- tests/feature/iop/test_inventory.py
- tests/feature/iop/test_vulnerability_frontend.py
- tests/feature/iop/test_advisor.py
- tests/feature/iop/test_advisor_frontend.py
- tests/feature/iop/test_inventory_frontend.py
- tests/feature/iop/test_yuptoo.py
- tests/feature/iop/test_cvemap_downloader.py
- tests/feature/iop/test_ingress.py
- tests/feature/iop/test_puptoo.py
- tests/feature/iop/test_vulnerability.py
- tests/feature/iop/test_integration.py
- tests/feature/iop/test_gateway.py
- tests/feature/iop/test_vmaas.py
- tests/feature/iop/test_engine.py
@coderabbitai appears to be unable to track file moves so it sees this as a new tests. |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: Length of output: 266
✏️ Learnings added
|
Good to see AI accepting its mistakes gracefully 😄 |
Why are you introducing these changes? (Problem description, related links)
Inspired by #485, but building on top of #508.
What are the changes introduced in this pull request?
It introduces a directory structure that automatically marks anything under
tests/feature/$featurewith$feature. This prepares for additional flavors that disable various features, such as a plain foreman (without katello) and a plain foreman-proxy.How to test this pull request
Steps to reproduce:
Checklist