Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a pytest rules #464

Closed
wants to merge 1 commit into from
Closed

Conversation

AutomatedTester
Copy link
Contributor

PR Checklist

Please check if your PR fulfills the following requirements:

  • Does not include precompiled binaries, eg. .par files. See CONTRIBUTING.md for info
  • Tests for the changes have been added (for bug fixes / features)
  • Docs have been added / updated (for bug fixes / features)

PR Type

What kind of change does this PR introduce?

  • Bugfix
  • Feature (please, look at the "Scope of the project" section in the README.md file)
  • Code style update (formatting, local variables)
  • Refactoring (no functional changes, no api changes)
  • Build related changes
  • CI related changes
  • Documentation content changes
  • Other... Please describe:

What is the current behavior?

Issue Number: N/A

What is the new behavior?

Does this PR introduce a breaking change?

  • Yes
  • No

Other information

@google-cla google-cla bot added the cla: yes label Apr 23, 2021
Copy link

@thundergolfer thundergolfer left a comment

Choose a reason for hiding this comment

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

Thanks for kicking this off. Will be taking it for a spin in https://github.com/thundergolfer-playground/rules_python-pr-464

},
)

def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):

Choose a reason for hiding this comment

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

py_pytest_test, like Dropbox uses? I like that it preserves the standard py_ prefix.

load("@pip//:requirements.bzl", "requirement")

TEST_DEPS = [
requirement("pluggy"),

Choose a reason for hiding this comment

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

Where are these deps coming from? The relevant requirements.txt file is empty in the PR.

import sys
import pytest

args = ["-ra"] + %s + sys.argv[1:] + %s

Choose a reason for hiding this comment

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

Was going to request --long-args for readability but seems it's just -r chars provided by pytest, lame.


tests.append(test_name)

pytest_test(

Choose a reason for hiding this comment

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

Don't think we should have the 'generic py_test_suite delegate to a pytest test implementation. I think everything using pytest (which is a third-party dep and not stock python) should include "pytest" in the rule name.

)
native.test_suite(
name = name,
tests = tests,

Choose a reason for hiding this comment

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

If the tests attribute is unspecified or empty, the rule will default to including all test rules in the current BUILD file that are not tagged as manual. source

?? That's unexpected behaviour to me. I would have thought an empty list would do nothing or error. Do you have experience with _test_suite rules that wrap native.test_suite? Do rule authors keep this odd behaviour?

name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,

Choose a reason for hiding this comment

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

Think that users of the any _pytest_test rule should get pytest as a provided dependency, like here: https://github.com/dropbox/dbx_build_tools/blob/fe5c9e668a9e6951970c0595089742d8a0247b8c/build_tools/py/py.bzl#L1011

Is there an problem with that approach I'm not seeing?

Copy link
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

def pytest_test(name, srcs, deps = None, args = None, data = None, python_version = None, **kwargs):
runner_target = "%s-runner.py" % name

_pytest_runner(

Choose a reason for hiding this comment

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

What necessitates the creation of a separate executable? Can we just have a special py_test.main program? It looks like that's maybe what's happening as the py_test.main value is main = runner_target. The _pytest_runner target creates the runner file. But then why is the _pytest_runner itself executable?

@thundergolfer thundergolfer mentioned this pull request May 12, 2021
@joshua-cannon-techlabs
Copy link

Firstly, I would absolutely love to see pytest support in the stock bazel rules.

However, one thing that worries me is capturing the invisible dependency between test files and conftest.py files. Pytest-the-framework will load those to find customizations and fixtures which tests use without a paper-trail. (See pytest's doc).

So if the user is specifying the test, someone (is it them or the framework?) should be declaring those dependencies (conftest.py all the way up). I would argue the framework should, as it's painfully easy to get wrong from the user's perspective.

The same goes for the test suit rule.

Copy link
Contributor

@hrfuller hrfuller left a comment

Choose a reason for hiding this comment

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

I'd love to revive this PR. As a first pass we can't and shouldn't aim to support all the configurability of pytest, but we should let users passthrough pytest args to the stub script that invokes it.

Other things to consider are:

  • How to treat configuration files we find in the test sandbox, easiest thing at first would be to ignore custom configs.
  • we should amend the srcs of the underlying native.py_test to include a glob for
    **/conftest.py as someone mentioned in a comment.

expanded_args = [ctx.expand_location(arg, ctx.attr.data) for arg in ctx.attr.args]

runner = ctx.actions.declare_file(ctx.attr.name)
ctx.actions.write(
Copy link
Contributor

Choose a reason for hiding this comment

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

This should be a template substitution action.

name = name,
python_version = python_version,
srcs = srcs + [runner_target],
deps = deps,
Copy link
Contributor

Choose a reason for hiding this comment

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

Only issue I can think of involves which version of pytest to use. Presumably users need to have it in their requirements.txt, or we inject a default version if not. We should definitely add requirement("pytest") to deps if it doesn't exist.

Other related issues include user provided plugin version eg. pytest_coverage which need to resolve with pytest, and how / when to add those deps to the py_pytest_test rule.

@aignas
Copy link
Collaborator

aignas commented Dec 28, 2021

When someone comes back to this, consider adding extra arguments to change how pytest is changing the import path. I did some investigation as to why pytest tests where failing when I was using protobuf rules here: https://github.com/aignas/bazel_pytest_proto

@betaboon
Copy link
Contributor

betaboon commented May 21, 2022

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

@everyone else in here: what would be a minimal setup of changes required here to get this merged?

i see the following todo-list:

  • address (all) the review-comments
  • clear up if we want to implicitly supply a pytest and if so how

i would argue we shouldn't aim for adressing all eventualities at first, otherwise this would never get in in any form.

just for clarification: i would be willing to take this over under the condition that there is a willingness for constructive cooperation and eventually compromise.

@AutomatedTester
Copy link
Contributor Author

@AutomatedTester are you planning/willing to pick this up again, or would you prefer someone else taking it over?

Happy for someone to take this over, I haven't had time to do it.

@thundergolfer
Copy link

Heads up that #723 may supersede this.

@github-actions
Copy link

This Pull Request has been automatically marked as stale because it has not had any activity for 180 days. It will be closed if no further activity occurs in 30 days.
Collaborators can add an assignee to keep this open indefinitely. Thanks for your contributions to rules_python!

@github-actions github-actions bot added the Can Close? Will close in 30 days if there is no new activity label Dec 19, 2022
@github-actions
Copy link

This PR was automatically closed because it went 30 days without a reply since it was labeled "Can Close?"

@github-actions github-actions bot closed this Jan 18, 2023
@alexeagle
Copy link
Contributor

Note, https://docs.aspect.build/rules/aspect_rules_py/docs/rules#py_pytest_main provides missing glue for pytest, thanks to @mattem and @f0rmiga

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Can Close? Will close in 30 days if there is no new activity cla: yes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants