Skip to content

Make tests order independent #932

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

Merged
merged 1 commit into from
Apr 20, 2020
Merged

Make tests order independent #932

merged 1 commit into from
Apr 20, 2020

Conversation

rhizoome
Copy link
Contributor

@rhizoome rhizoome commented Apr 14, 2020

  • Reset the global registry after each test (teardown)

  • Create a settings fixtures that returns graphene_settings and resets the graphene_settings after use (teardown)

  • Convert test_mutation tests from unittests.TestCase to pytest

  • Convert test_mutation PetType to a pet_type fixtures that reregisters the type

The core change is setup/teardown in conftest.py

@pytest.fixture(autouse=True)
def reset_registry_fixture(db):
yield None
reset_global_registry()
@pytest.fixture()
def settings():
settings = dict(graphene_settings.__dict__)
yield graphene_settings
graphene_settings.__dict__ = settings

@rhizoome rhizoome mentioned this pull request Apr 14, 2020
7 tasks
@rhizoome rhizoome changed the title Make tests order independent WIP: Make tests order independent Apr 16, 2020
@jkimbo
Copy link
Member

jkimbo commented Apr 16, 2020

@ganwell if you need to drop Python 2.7 support then why not create this PR against the v3 branch?

@rhizoome rhizoome changed the base branch from master to v3 April 16, 2020 13:59
@rhizoome rhizoome changed the title WIP: Make tests order independent Make tests order independent Apr 16, 2020
@rhizoome
Copy link
Contributor Author

@jkimbo I rebased to v3 and removed WIP

Copy link
Member

@jkimbo jkimbo left a comment

Choose a reason for hiding this comment

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

Looking good @ganwell . Left some comments

settings = dict(graphene_settings.__dict__)
yield None
reset_global_registry()
graphene_settings.__dict__ = settings
Copy link
Member

Choose a reason for hiding this comment

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

Why do you have to restore the graphene_settings dict?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

There are tests that change the settings and don't change it back.

There are several options:

  1. Provide a graphene_settings fixture (probably the best way). This fixture resets the settings after use

  2. Just reset the settings on every test, so it is impossible to leak any settings. I decided to use this approach because it is best for an environment where contributors often change.

  3. Manually reset the settings in the tests

We usually use 1. but we have regular contributors. Let me know what you prefer.

Uses of graphene_settings:

$> git grep graphene_settings | grep '/tests/'
graphene_django/forms/tests/test_mutation.py:from ...settings import graphene_settings
graphene_django/forms/tests/test_mutation.py:    graphene_settings.CAMELCASE_ERRORS = True
graphene_django/forms/tests/test_mutation.py:    graphene_settings.CAMELCASE_ERRORS = False
graphene_django/rest_framework/tests/test_mutation.py:from ...settings import graphene_settings
graphene_django/rest_framework/tests/test_mutation.py:    graphene_settings.CAMELCASE_ERRORS = True
graphene_django/rest_framework/tests/test_mutation.py:    graphene_settings.CAMELCASE_ERRORS = False
graphene_django/tests/test_converter.py:from ..settings import graphene_settings
graphene_django/tests/test_converter.py:    graphene_settings.DJANGO_CHOICE_FIELD_ENUM_V3_NAMING = True
graphene_django/tests/test_converter.py:    graphene_settings.DJANGO_CHOICE_FIELD_ENUM_V3_NAMING = False
graphene_django/tests/test_query.py:from ..settings import graphene_settings
graphene_django/tests/test_query.py:    graphene_settings.RELAY_CONNECTION_ENFORCE_FIRST_OR_LAST = True
graphene_django/tests/test_query.py:    graphene_settings.RELAY_CONNECTION_MAX_LIMIT = 100
graphene_django/tests/test_query.py:    graphene_settings.RELAY_CONNECTION_ENFORCE_FIRST_OR_LAST = False
graphene_django/tests/test_query.py:    graphene_settings.RELAY_CONNECTION_MAX_LIMIT = 100
graphene_django/tests/test_query.py:    graphene_settings.RELAY_CONNECTION_ENFORCE_FIRST_OR_LAST = False
graphene_django/tests/test_types.py:from ..settings import graphene_settings
graphene_django/tests/test_types.py:        graphene_settings.DJANGO_CHOICE_FIELD_ENUM_V3_NAMING = True
graphene_django/tests/test_types.py:        graphene_settings.DJANGO_CHOICE_FIELD_ENUM_V3_NAMING = False
graphene_django/tests/test_types.py:        graphene_settings.DJANGO_CHOICE_FIELD_ENUM_CUSTOM_NAME = (
graphene_django/tests/test_types.py:        graphene_settings.DJANGO_CHOICE_FIELD_ENUM_CUSTOM_NAME = None

Copy link
Member

Choose a reason for hiding this comment

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

I think a fixture would be good as well. If it's going to be too much work to change it all though I'm ok leaving it like this.

text = forms.CharField()
@pytest.fixture()
def my_form():
class MyForm(forms.Form):
Copy link
Member

Choose a reason for hiding this comment

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

Why do the forms need to be fixtures?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jkimbo I think only the types have to be fixtures, because they get registered in the global registry through some magic when python executes the class. I put everything into fixtures just for consistency.

If you like I can check what needs to be fixtures and only more these to fixtures.

Copy link
Member

Choose a reason for hiding this comment

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

I think that would be cleaner. As far as I'm aware only the Django models and Graphene-Django DjangoObjectType's register themselves into a registry.

assert result.errors[0].messages == ["This field is required."]
assert result.errors[1].messages == ["This field is required."]
assert "age" in fields_w_error
assert "name" in fields_w_error
Copy link
Member

Choose a reason for hiding this comment

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

Much prefer plain pytest tests rather than Django's TestCase 👍

pytest.ini Outdated
@@ -1,2 +1,3 @@
[pytest]
DJANGO_SETTINGS_MODULE = django_test_settings
addopts = --random-order
Copy link
Member

Choose a reason for hiding this comment

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

Pytest config shouldn't be defined in multiple places. I would remove the pytest.ini file and just define it in the setup.cfg file.

@rhizoome
Copy link
Contributor Author

@jkimbo I think I addressed all the issues.

@rhizoome rhizoome marked this pull request as draft April 17, 2020 09:22
@rhizoome rhizoome changed the title Make tests order independent WIP: Make tests order independent Apr 17, 2020
@rhizoome
Copy link
Contributor Author

@jkimbo I will split this PR into one that can be merge to master and the rest that can only be merged to v3. In about 2 hours.

@jkimbo
Copy link
Member

jkimbo commented Apr 17, 2020

If you feel it's important @ganwell . I'm fine with just merging this into v3

@rhizoome rhizoome changed the base branch from v3 to master April 19, 2020 17:48
@rhizoome rhizoome marked this pull request as ready for review April 19, 2020 18:19
@rhizoome rhizoome changed the title WIP: Make tests order independent Make tests order independent Apr 19, 2020
@rhizoome
Copy link
Contributor Author

@jkimbo I moved this PR to master again. It now contains everything except adding pytest-random-order and can therefore be merged to master.

@rhizoome
Copy link
Contributor Author

rhizoome commented Apr 19, 2020

@jkimbo Here is the part that only works on v3 11e1403 / #940

Sorry for making it so complicated I felt it is the right thing to do in case it takes longer to merge v3 to master.

I will checkin on #932 and #940 the next days. In case you think it is all too complicated just do what you think is best: ie commiting it yourself.

Copy link
Member

@jkimbo jkimbo left a comment

Choose a reason for hiding this comment

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

This is looking good thanks, @ganwell . Just one thing before I think we should merge this.



@pytest.fixture()
def settings():
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 settings():
def graphene_settings():

Otherwise this will clash with the pytest django settings fixture: https://pytest-django.readthedocs.io/en/latest/helpers.html#settings

* Reset the global registry after each test (teardown)

* Create a settings fixtures that returns graphene_settings and resets
  the graphene_settings after use (teardown)

* Convert test_mutation tests from unittests.TestCase to pytest

* Convert test_mutation PetType to a pet_type fixtures that reregisters
  the type
@rhizoome
Copy link
Contributor Author

@jkimbo, I changed the fixture settings() to graphene_settings()

When you merge, could you please also merge master into v3 again, so I can update #940? It currently includes a merge, which makes it difficult to read the diff.

@jkimbo jkimbo merged commit b9f0e4f into graphql-python:master Apr 20, 2020
@jkimbo
Copy link
Member

jkimbo commented Apr 20, 2020

@ganwell v3 updated

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants