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

unit test helper: big revamp #8894

Merged

Conversation

russoz
Copy link
Collaborator

@russoz russoz commented Sep 22, 2024

SUMMARY

Revamped the test helper to be able to support more than just run_command(). This PR makes the code more generic and expansible, allowing for easier tests in the future.

ISSUE TYPE
  • Test Pull Request
COMPONENT NAME

tests/unit/plugins/modules/conftest.py
tests/unit/plugins/modules/helper.py
tests/unit/plugins/modules/test_cpanm.py
tests/unit/plugins/modules/test_cpanm.yaml
tests/unit/plugins/modules/test_django_check.py
tests/unit/plugins/modules/test_django_check.yaml
tests/unit/plugins/modules/test_django_check.yaml.license
tests/unit/plugins/modules/test_django_command.py
tests/unit/plugins/modules/test_django_command.yaml
tests/unit/plugins/modules/test_django_createcachetable.py
tests/unit/plugins/modules/test_django_createcachetable.yaml
tests/unit/plugins/modules/test_facter_facts.py
tests/unit/plugins/modules/test_facter_facts.yaml
tests/unit/plugins/modules/test_gconftool2.py
tests/unit/plugins/modules/test_gconftool2.yaml
tests/unit/plugins/modules/test_gconftool2_info.py
tests/unit/plugins/modules/test_gconftool2_info.yaml
tests/unit/plugins/modules/test_gio_mime.py
tests/unit/plugins/modules/test_gio_mime.yaml
tests/unit/plugins/modules/test_opkg.py
tests/unit/plugins/modules/test_opkg.yaml
tests/unit/plugins/modules/test_puppet.py
tests/unit/plugins/modules/test_puppet.yaml
tests/unit/plugins/modules/test_snap.py
tests/unit/plugins/modules/test_xfconf.py
tests/unit/plugins/modules/test_xfconf.yaml
tests/unit/plugins/modules/test_xfconf_info.py
tests/unit/plugins/modules/test_xfconf_info.yaml

@ansibullbot ansibullbot added new_plugin New plugin tests tests unit tests/unit labels Sep 22, 2024
@russoz
Copy link
Collaborator Author

russoz commented Sep 22, 2024

The CI error seems to be unrelated with the change. @felixfontein could you please confirm? TIA

@ansibullbot ansibullbot added the needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR label Sep 22, 2024
@felixfontein felixfontein added check-before-release PR will be looked at again shortly before release and merged if possible. backport-9 Automatically create a backport for the stable-9 branch labels Sep 22, 2024
Copy link
Collaborator

@felixfontein felixfontein left a comment

Choose a reason for hiding this comment

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

It seems that somewhere the order of the tests comes from a dictionary. In Python 3.5 (where the tests fail) the order is 'random', while in Python 3.6+ it is insertion order. (No idea why it works in 2.7 since there it should be 'random' as well...)

tests/unit/plugins/modules/helper.py Outdated Show resolved Hide resolved
@russoz
Copy link
Collaborator Author

russoz commented Sep 22, 2024

It seems that somewhere the order of the tests comes from a dictionary. In Python 3.5 (where the tests fail) the order is 'random', while in Python 3.6+ it is insertion order. (No idea why it works in 2.7 since there it should be 'random' as well...)

I do recall something about that in 2.7 it was "random" but the seed to the random generator was kinda fixed, so the order of the keys was deterministic across multiple runs of the script. They improved that with 3.5, and I had not kept track, I did not know 3.6 onwards was using insertion order. Anyways, it is not something to rely on.

@russoz
Copy link
Collaborator Author

russoz commented Sep 27, 2024

hi @felixfontein anything else I need to adjust in this one? TIA

russoz and others added 13 commits September 28, 2024 14:25
- TestCaseContext fixture no longer need to autouse=True
- Helper.from_module() allows extra param to specify yaml file
- test_django_check: adjusted .py and .yaml
- now it works not only in parametrized functions but also directly with args
- improved encapsulation, class Helper no longer knows details about test cases
- test functions no longer parametrized, that allows using test case fixtures per test function
- renamed 'context' to 'mock'
Co-authored-by: Felix Fontein <felix@fontein.de>
@ansibullbot ansibullbot removed the needs_revision This PR fails CI tests or a maintainer has requested a review/revision of the PR label Sep 28, 2024
@russoz
Copy link
Collaborator Author

russoz commented Sep 28, 2024

It seems that somewhere the order of the tests comes from a dictionary. In Python 3.5 (where the tests fail) the order is 'random', while in Python 3.6+ it is insertion order. (No idea why it works in 2.7 since there it should be 'random' as well...)

Yup, I gave it another look. I think I know what it is: the order of the tests, in the code, is a list, but as the test functions are dynamically added to the module, they are included into the underlying dict that supports the module's attributes. Not sure it does explain it.

I chose not parameterizing the test function so that fixtures could be used (with pytest.mark.usefixtures) per test function, rather than for all test cases.

Anyways, whatever test code is performing this comparison between collected tests is clearly relying on the order provided by the module. I guess for the time being the only option I have is to create one single function and parameterize it. This will become a problem if developers use the test helper and create extra tests within the same test_module. Anyway I can skip Python 3.5?

@russoz
Copy link
Collaborator Author

russoz commented Sep 28, 2024

the problem lies in the pytest-xdist plugin used here:

https://pytest-xdist.readthedocs.io/en/stable/known-limitations.html#order-and-amount-of-test-must-be-consistent

I don't want to chase the rabbit down that hole, so I will revert to a parameterized test function.

@felixfontein
Copy link
Collaborator

hi @felixfontein anything else I need to adjust in this one? TIA

The tests were failing on Python 3.5, as you probably noticed :)

community.general 11.0.0 will drop support for Python 3.5 (though not for 2.7), and 12.0.0 will drop support for Python 2.7 as well, so at that point you can do this again :)

@felixfontein felixfontein merged commit 8ef77d8 into ansible-collections:main Sep 28, 2024
141 checks passed
Copy link

patchback bot commented Sep 28, 2024

Backport to stable-9: 💚 backport PR created

✅ Backport PR branch: patchback/backports/stable-9/8ef77d8664598154fdd51bf522c0afc62fe36b65/pr-8894

Backported as #8943

🤖 @patchback
I'm built with octomachinery and
my source is open — https://github.com/sanitizers/patchback-github-app.

@felixfontein felixfontein removed the check-before-release PR will be looked at again shortly before release and merged if possible. label Sep 28, 2024
@felixfontein
Copy link
Collaborator

@russoz thanks for your contribution!

patchback bot pushed a commit that referenced this pull request Sep 28, 2024
* initial commit

* multiple changes:

- TestCaseContext fixture no longer need to autouse=True
- Helper.from_module() allows extra param to specify yaml file
- test_django_check: adjusted .py and .yaml

* set fixtures per testcase

* set fixtures per testcase

* rollback to original state

* patch_ansible_module fixture

- now it works not only in parametrized functions but also directly with args

* tests/unit/plugins/modules/helper.py

- improved encapsulation, class Helper no longer knows details about test cases
- test functions no longer parametrized, that allows using test case fixtures per test function
- renamed 'context' to 'mock'

* enable Helper.from_list(), better param name 'ansible_module'

* adjusted test fiels to new helper

* remove unnecessary .license file

* fix bracket

* fix reference name

* Update tests/unit/plugins/modules/helper.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* revert to parametrized test func instead of multiple funcs

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 8ef77d8)
felixfontein pushed a commit that referenced this pull request Sep 28, 2024
…8943)

unit test helper: big revamp (#8894)

* initial commit

* multiple changes:

- TestCaseContext fixture no longer need to autouse=True
- Helper.from_module() allows extra param to specify yaml file
- test_django_check: adjusted .py and .yaml

* set fixtures per testcase

* set fixtures per testcase

* rollback to original state

* patch_ansible_module fixture

- now it works not only in parametrized functions but also directly with args

* tests/unit/plugins/modules/helper.py

- improved encapsulation, class Helper no longer knows details about test cases
- test functions no longer parametrized, that allows using test case fixtures per test function
- renamed 'context' to 'mock'

* enable Helper.from_list(), better param name 'ansible_module'

* adjusted test fiels to new helper

* remove unnecessary .license file

* fix bracket

* fix reference name

* Update tests/unit/plugins/modules/helper.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* revert to parametrized test func instead of multiple funcs

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 8ef77d8)

Co-authored-by: Alexei Znamensky <103110+russoz@users.noreply.github.com>
@russoz russoz deleted the generic_test_helper branch September 28, 2024 05:53
aioue pushed a commit to aioue/community.general that referenced this pull request Oct 1, 2024
* initial commit

* multiple changes:

- TestCaseContext fixture no longer need to autouse=True
- Helper.from_module() allows extra param to specify yaml file
- test_django_check: adjusted .py and .yaml

* set fixtures per testcase

* set fixtures per testcase

* rollback to original state

* patch_ansible_module fixture

- now it works not only in parametrized functions but also directly with args

* tests/unit/plugins/modules/helper.py

- improved encapsulation, class Helper no longer knows details about test cases
- test functions no longer parametrized, that allows using test case fixtures per test function
- renamed 'context' to 'mock'

* enable Helper.from_list(), better param name 'ansible_module'

* adjusted test fiels to new helper

* remove unnecessary .license file

* fix bracket

* fix reference name

* Update tests/unit/plugins/modules/helper.py

Co-authored-by: Felix Fontein <felix@fontein.de>

* revert to parametrized test func instead of multiple funcs

---------

Co-authored-by: Felix Fontein <felix@fontein.de>
@russoz russoz mentioned this pull request Oct 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backport-9 Automatically create a backport for the stable-9 branch new_plugin New plugin tests tests unit tests/unit
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants