-
Notifications
You must be signed in to change notification settings - Fork 2.2k
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 tests: replace nose with pytest #2502
unit tests: replace nose with pytest #2502
Conversation
@tgamblin @scheibelp @becker33 The first commit is plain porting, and there are plenty of options to play with (I just activated a report for the 20 slowest tests, see Travis). How do you feel about trying to convert some tests with native |
Can you please give some motivational rationale behind this change? I'm sure there's a good reason, but it's not apparent in this PR so far. |
b524fe0
to
636374f
Compare
@tgamblin @becker33 @scheibelp @hegner I think you may want to have a look at the test What I roughly have in mind is:
The Does it make sense to you, at least from an high level perspective? |
5f8e557
to
6dd64da
Compare
spack test -h To have a list of the tests: spack test --collect-only To run just a few selected tests see the spack test -k spec will run any test that contains the word "spec" at module, class or function scope |
acfa83c
to
97b5f37
Compare
@tgamblin @becker33 @scheibelp Can you have a brief look at:
? While I am at it I am trying to port the code to native One of the benefit of doing this is that we can query or run basically everything we want with a very fine control other details. For instance: $ pytest --setup-plan -k test_user_defaults
=============================================================================================== test session starts ===============================================================================================
platform linux2 -- Python 2.7.6, pytest-3.0.5, py-1.4.31, pluggy-0.4.0
rootdir: /home/mculpo/PycharmProjects/spack, inifile: pytest.ini
plugins: cov-2.4.0
collected 452 items
lib/spack/spack/test/architecture.py
SETUP F monkeypatch
SETUP F mock_fetch_cache (fixtures used: monkeypatch)
SETUP F no_stdin_duplication (fixtures used: monkeypatch)
SETUP S tmpdir_factory
SETUP S linux_os
SETUP M configuration_files (fixtures used: linux_os, tmpdir_factory)
lib/spack/spack/test/architecture.py::test_user_defaults (fixtures used: configuration_files, linux_os, mock_fetch_cache, monkeypatch, no_stdin_duplication, tmpdir_factory)
TEARDOWN F no_stdin_duplication
TEARDOWN F mock_fetch_cache
TEARDOWN F monkeypatch
TEARDOWN M configuration_files
TEARDOWN S linux_os
TEARDOWN S tmpdir_factory
============================================================================================ slowest 20 test durations ============================================================================================
0.00s setup lib/spack/spack/test/architecture.py::test_user_defaults
0.00s teardown lib/spack/spack/test/architecture.py::test_user_defaults
============================================================================================== 451 tests deselected ===============================================================================================
========================================================================================= 451 deselected in 1.03 seconds ========================================================================================== shows what will be the plan for running a single test in |
572ef73
to
167f4e0
Compare
@tgamblin @becker33 I think this is ready to be reviewed. The PR is huge (and I couldn't do much to contain its size), but it's just porting of tests. From my side I would appreciate a thorough review of anything in:
The first two files contain the code that before was in the |
To everybody: description above updated. You are welcome to try the PR and leave feedbacks. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Generally speaking LGTM. My only concern is the general implicit availability of some fixtures (e.g. 'config' from conftest) - I'd prefer any test that wanted to use it would have to do:
@pytest.mark.usefixtures('config'
('foobar', 'unknown') | ||
] | ||
) | ||
def url_and_system(request, tmpdir): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer url_and_build_system
as "system" by itself is a bit generic
Also: as you said this seems to be a great example of the usefulness of fixtures - one can add new unit tests by specifying new parameter tuples.
] | ||
) | ||
def url_and_system(request, tmpdir): | ||
"""Return a url along with the correct build-system guess""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
and also sets up the resource to be pulled by the stage with the appropriate file name
return request.param | ||
|
||
|
||
@pytest.mark.usefixtures('config', 'builtin_mock') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Earlier these tests were referencing "config" defined in conftest in an implicit manner. I think this was updated in your most recent commit (i.e. this line is new). Is there anything preventing a user from referencing "config" in an implicit manner elsewhere? Brief reading suggests this can be prevented although I'm having trouble seeing how that is achieved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there anything preventing a user from referencing "config" in an implicit manner elsewhere?
I don't think so, and I wouldn't be worried about that. Arguments to tests are only fixtures: if an unknown argument is present pytest will quit with a very informative error message. Here I grouped the fixtures together because in the tests below they were used only for their side effects. In cases where you need the object returned by the fixture the only way possible is using the funcargs mechanism (i.e. referencing fixtures in an implicit manner).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if an unknown argument is present pytest will quit with a very informative error message
That is good, although I am more concerned with other potential issues with having a generically-named variable like "config" available in the global namespace. E.g. a user may create their own unit test, create their own instance of "config" then rename it and forget to change the reference. That's the sort of thing which may cause some frustration IMO. I suppose a more specific name would help like "global_config"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That is good, although I am more concerned with other potential issues with having a generically-named variable like "config" available in the global namespace.
I agree if we want to change the name of fixtures for something better. For 'config' if there's general agreement over something else I'll make the change (didn't do it now as it touches a lot of files and would like to have everybody agreeing on that).
Just to be sure this is clear to everybody reading the thread: the fixture config
is not available in the global namespace. pytest
has a dependency injection mechanism (commonly referred to as funcargs) which works more or less like this:
- the decorator
@pytest.fixture
registers a function as a fixture (this function will be used as a factory to create a fixture object when required) - since tests are automatically run by
pytest
they can only accept fixture arguments: if the name of an argument matches the name of a registered fixture, an object will be injected - fixtures can be overriden with these rules
167f4e0
to
c5f4763
Compare
Expected failures work as expected (see fc36376): now we have a nice way to document bugs in core and go TDD. |
fc36376
to
85daeeb
Compare
- Remove `conftest.py` magic and all the special case stuff in `bin/spack` - Spack commands can optionally take unknown arguments, if they want to handle them. - `spack test` is now a command like the others. - `spack test` now just delegates its arguments to `pytest`, but it does it by receiving unknown arguments and NOT taking an explicit help argument.
2de9b93
to
247d444
Compare
- Now supports an approximation of the old simple interface - Also supports full pytest options if you want them.
e5efcb7
to
a58867b
Compare
|
We can consolidate testing commands in a future PR, but to prepare for that I made the
|
@alalazo: I got rid of
See what you think. |
@tgamblin I just checked the PR, and everything seems fine to me. Thanks for taking the time of finalizing it! 👍 Given the size of this PR I think it's better to argue over minor points or cosmetic changes after this is merged and on smaller / more focused PRs. 😊 Miscellaneous replies:
The same answer says: As of 2014, pytest-cov seems to have changed hands. py.test --cov jedi test seems to be a useful command again (look at the comments). However, you don't need to use it. But in combination with xdist it can speed up your coverage reports. That was one of the two reasons why I went for I don't see this as a major issue though: people seem to like having a wrapper command for tests, and I suspect we won't be PyPI packageable for a long time...
As far as I understood handling multiprocessing libraries within your application should be a On top of that |
I forgot to advertize this to people following the PR: passing to
This will ensure that Travis won't go mad over a known bug, and will give developers a more focused way to work on an issue. |
Trying latest develop on new system gives: $ source spack/share/spack/setup-env.sh
Traceback (most recent call last):
File "/gpfs/homeb/pcp0/pcp0043/spack/bin/spack", line 55, in <module>
import nose
ImportError: No module named nose
Traceback (most recent call last):
File "/gpfs/homeb/pcp0/pcp0043/spack/bin/spack", line 55, in <module>
import nose
ImportError: No module named nose
................. I see that |
Nose was removed with #2502. Maybe somebody didn't get rid of all the
`import nose` statements?
…On Thu, Dec 29, 2016 at 12:31 PM, Pramod Kumbhar ***@***.***> wrote:
Trying latest develop on new system gives:
$ source spack/share/spack/setup-env.sh
Traceback (most recent call last):
File "/gpfs/homeb/pcp0/pcp0043/spack/bin/spack", line 55, in <module>
import nose
ImportError: No module named nose
Traceback (most recent call last):
File "/gpfs/homeb/pcp0/pcp0043/spack/bin/spack", line 55, in <module>
import nose
ImportError: No module named nose
.................
I see that nose module is not installed on the system. Is this mandatory?
If not, could you take a look?
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#2502 (comment)>, or mute
the thread
<https://github.com/notifications/unsubscribe-auth/AB1cd2j973rHLh1M_jfsUi-RXLK6a-K0ks5rM-5WgaJpZM4LGinM>
.
|
TLDR
This PR changes the testing framework from nose to pytest for the reasons discussed in #2368.
Added benefits:
Modifications
lib/spack/external/
spack test
a wrapper aroundpytest
I left the port of tests that are written as plain
unittest.TestCase
for future PRs: this one is already huge as it is, and tests that just depend onunittest.TestCase
can be ported one module at a time.Miscellaneous Notes
pytest
is better run from spack root directoryspack test
is just a wrapper aroundpytest
that can be used everywherepytest --cov
, asspack test
will give wrong results (for any other thing the two commands are equivalent)Running
spack test
withoutpytest
:Running the entire test suite
Run a few tests selectively
Show the setup plan for a set of tests
Getting help on the ton of options that are not above