How do I correctly register a new Python test targ...
# plugins
a
How do I correctly register a new Python test target and rule? This is what I have having followed https://www.pantsbuild.org/2.19/docs/writing-plugins/common-plugin-tasks/run-tests and https://github.com/pantsbuild/pants/blob/main/src/python/pants/backend/python/goals/publish.py, but I am getting a huge graph failure error...
w
Looks like a typo:
nose_pex_request = Get(VenvPex, PexRequest, <http://nose.to|nose.to>_pex_request())
Also, I needed to add the following to NoseTestFieldSet
Copy code
xdist_concurrency: PythonTestsXdistConcurrencyField
batch_compatibility_tag: PythonTestsBatchCompatibilityTagField
One of the easier ways to debug something like this (at least, until an upcomign migration happens), is to comment out your rule, throw an error, and progressively uncomment more of the rule until you get a rule graph error:
Copy code
@rule(desc="Run Python test(s) with Nose")  # type: ignore
async def run_nose_test(
    batch: NoseRequest.Batch[NoseTestFieldSet, Any],
    nose: NoseTool,
    test_subsystem: TestSubsystem,
    global_options: GlobalOptions,
) -> TestResult:

    transitive_targets = await Get(
        TransitiveTargets, TransitiveTargetsRequest((batch.single_element.address,))
    )
    raise NotImplementedError()
    # ...
a
Thank you - that was indeed a silly typo... good tip on debugging like that too 👍
I've now changed it to
nose_pex_request = Get(VenvPex, PexRequest, <http://nose.to|nose.to>_pex_request())
, but now the following error occurs:
Copy code
20:25:57.85 [INFO] Initializing scheduler...
20:25:59.91 [INFO] Scheduler initialized.
20:25:59.98 [WARN] No applicable files or targets matched. The `test` goal works with these target types:

  * python_test

However, you only specified file arguments with these target types:

  * nose_test

Please specify relevant file and/or target arguments. Run `pants --filter-target-type=python_test list ::` to find all applicable targets in your project, or run `pants --filter-target-type=python_test filedeps ::` to find all applicable files.
I've hit this case in multiple attempts trying to write the plugin
(I've also added those fields, although not sure why they're needed)
g
Are you using your NoseTest target or do you want to run nose on an existing
python_test
target? The field sets says the latter, but you have your own target.
(N.b. your NoseTarget doesn't have the required PythonTestSourceField)
c
(Tom, I think it's on purpose to not use the PythonTestSourceField, in order to use nose instead of pytest.)
But indeed, the field set tells a different story, but I think that's part of the mistake here..
@aloof-airline-74337 I think you'd want to declare a new NoseTestSourcesField and use that in the field set and the nose test target (don't directly use SingleSourceField on a target but rather subclass it, as otherwise you won't be able to properly select your target based on the source field for you field sets..)
w
You know, that would be interesting if our
python_test
target took a runner, which allowed swapping in pytest, nose, and whatever Rust-based replacement Astral will eventually come out with
👍 2
a
Thank you all for your help, I've gotten past these issues 🙏 still wrapping my head around the mental models
@wide-midnight-78598 once I get this working with
nose_test
targets (it was suggested to me this would be more straightforward initially) I'd be interested in seeing how I could get
python_test
to not launch
pytest
but
nose
instead. I tried extending it with a
runner
field but didn't get very far
w
👍 Yeah, I wasn't even thinking to use a new target, I was trying to envision how to pass in the runner. However, using
nose_tests
where needed would DEFINITELY be faster in the short term... Then eventually, if we solve the much cooler problem of dynamic test runners, it would basically be a grep and replace. I have to look into pytest at some point, because I've just blindly used what we have already - but I can't imagine it's that hard to do - using a much less complicated version of what I did for C/C++ compilers, where it is either auto-selected, or you can select/define one
🙌 1
However, I'm sure there is much boilerplate to write, which I would recommend against in the short term 🙂
a
Yeah I even had trouble finding at which point Pytest reacts to / targets
python_tests
to see if I could divert somehow, but to no avail 🙂 I'll stick with
nose_test(s)
for now
w
Without looking into it, it's probably something like this in pytest_runner - and then follow the chain to see how that could be modded. But safer bet with nose_test
Copy code
async def setup_pytest_for_target(
    request: TestSetupRequest,
    pytest: PyTest,
    test_subsystem: TestSubsystem,
    coverage_config: CoverageConfig,
    coverage_subsystem: CoverageSubsystem,
    test_extra_env: TestExtraEnv,
) -> TestSetup:
👍 1