Compare commits

...

197 Commits
3.5.0 ... 3.6.0

Author SHA1 Message Date
Bruno Oliveira
45e7703133 Move mark revamp note to the top of the CHANGELOG 2018-05-22 21:12:51 -03:00
Bruno Oliveira
d70e910b65 Preparing release version 3.6.0 2018-05-23 00:07:48 +00:00
Bruno Oliveira
c55db1faac Merge remote-tracking branch 'upstream/master' into release-3.6.0 2018-05-23 00:03:58 +00:00
Bruno Oliveira
16583a6d43 Add missing libs to tasks/requirements.txt 2018-05-23 00:03:47 +00:00
Bruno Oliveira
7985eff5b4 Merge pull request #3497 from hroncok/approx_compat_import
Import Mapping and Sequence from compat in python_api::approx
2018-05-22 20:57:29 -03:00
Miro Hrončok
5072226f69 Import Mapping and Sequence from compat in python_api::approx
Related to https://github.com/pytest-dev/pytest/issues/3339

Fixes a DeprecationWarning on Python 3.7

Adds Mapping to compat
2018-05-22 22:25:15 +02:00
Ronny Pfannschmidt
6c8d46d8ea Merge pull request #3487 from tgoodlet/detect_pytest_hook_prefix
Detect `pytest_` prefixed hooks
2018-05-22 21:36:58 +02:00
Bruno Oliveira
7d0c9837ce Merge pull request #3459 from RonnyPfannschmidt/mark-iter-name-filter
introduce name filtering for marker iteration again
2018-05-21 13:24:39 -03:00
Bruno Oliveira
8e17e32253 Merge pull request #3492 from timhughes/patch-1
fix typo in docs
2018-05-20 15:51:03 -03:00
Tim Hughes
f0b855369c fix typo 2018-05-20 19:14:06 +01:00
Ronny Pfannschmidt
4aa7ebaf52 Merge pull request #3490 from nicoddemus/merge-master-into-features
Merge master into features
2018-05-19 11:36:11 +02:00
Tyler Goodlet
486b786cb2 Add trivial changelog entry 2018-05-18 12:02:50 -04:00
Bruno Oliveira
674879976f Merge remote-tracking branch 'upstream/master' into merge-master-into-features 2018-05-18 12:30:08 -03:00
Tyler Goodlet
d4065a9166 Detect pytest_ prefixed hooks
`pluggy` is deprecating the `implprefix` argument in the next major
release so implement this detection in our derived plugin manager.

Relates to pytest-dev/pluggy#145
2018-05-17 20:38:54 -04:00
Bruno Oliveira
e7f75f69f2 Small grammar fix in CHANGELOG 2018-05-17 21:20:43 -03:00
Bruno Oliveira
5be85a1f55 Merge changelog marks refactoring changelog entries as discussed in review 2018-05-17 21:18:12 -03:00
Bruno Oliveira
bb626fe8a7 Fix typo in mark.rst 2018-05-17 16:06:00 -03:00
Ronny Pfannschmidt
45faaeca7a Merge pull request #3480 from nicoddemus/deprecated-deadlne-hypothesis
Attempt to fix CI problems related to Hypothesis
2018-05-17 20:18:27 +02:00
Bruno Oliveira
11fb384efb Fix link to skipif tutorial in ref docs 2018-05-17 10:15:47 -03:00
Bruno Oliveira
5edad01d4e Merge pull request #3476 from avirlrma/master
change doc copyright year to range and auto update year
2018-05-16 17:53:23 -03:00
Bruno Oliveira
f5361a302c Use a more recent hypothesis version on CI 2018-05-16 07:35:02 -03:00
Bruno Oliveira
94e62dfc50 Increase hypothesis deadline
The value is pretty close to the new default that will come out in
future hypothesis versions, which is generating a deprecation error
on CI.

Using a loose deadline because CI boxes are not reliable in how much
CPU power they have available
2018-05-16 07:34:53 -03:00
Bruno Oliveira
afe4800daf Fix deprecation notice in Node.get_marker 2018-05-15 21:47:40 -03:00
Bruno Oliveira
2cd159e8c5 Add section on how to update marks and add ref to the deprecation notice 2018-05-15 21:35:27 -03:00
Bruno Oliveira
718ba83600 Small adjustment to the CHANGELOG 2018-05-15 21:02:05 -03:00
Bruno Oliveira
1b2f4f4483 Small rewording to the CHANGELOG 2018-05-15 21:01:37 -03:00
Bruno Oliveira
f68bab06b4 Reword the changelog 2018-05-15 18:24:14 -03:00
Bruno Oliveira
a4425cb4af Merge pull request #3469 from scop/dropthedot
#dropthedot
2018-05-15 08:00:28 -03:00
Bruno Oliveira
01d2d81d1f Merge pull request #3468 from scop/spelling
Spelling and grammar fixes
2018-05-15 07:59:56 -03:00
aviral1701
f14e097635 added changelog and added my name to the authors 2018-05-15 12:54:48 +05:30
aviral1701
a59f677d93 change doc copyright year to range and auto update year 2018-05-15 12:48:04 +05:30
Bruno Oliveira
36614b0a3d Fix formatting in CHANGELOG entry 2018-05-14 09:56:36 -03:00
Ville Skyttä
b4370c08b9 #dropthedot 2018-05-13 12:09:47 +02:00
Ville Skyttä
aa51fcb2b6 Spelling and grammar fixes 2018-05-13 12:06:09 +02:00
Ronny Pfannschmidt
4914135fdf introduce name filtering for marker iteration again 2018-05-11 21:48:15 +02:00
Ronny Pfannschmidt
84b37e1b57 Merge pull request #3452 from nicoddemus/fix-flaky-xdist-test
Attempt to fix flaky test on Python 2
2018-05-05 20:18:06 +02:00
Bruno Oliveira
fa76a5c8fe Attempt to fix flaky test on Python 2
This test sometimes fails on AppVeyor with:

```
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.0 = <listiterator object at 0x0549DC50>
    leaked_types = sum(1 for _ in gc.garbage
>                   if 'PseudoFixtureDef' in str(_))
E   UnicodeEncodeError: 'ascii' codec can't encode character u'\u263a' in position 23: ordinal not in range(128)
test_request_garbage.py:19: UnicodeEncodeError
====================== 1 passed, 1 error in 1.39 seconds ======================
```

Use our internal "safe_repr" function to handle Encode errors: who knows
what objects are in garbage after all.
2018-05-04 17:56:51 -03:00
Ronny Pfannschmidt
27651f4032 Merge pull request #3444 from nicoddemus/escape-whitespace-diffs
Escape whitespace only strings when diffing them on failed assertions
2018-05-04 18:14:35 +02:00
Bruno Oliveira
413b1aa4e9 Rename internal function as suggested during review 2018-05-04 11:08:35 -03:00
Bruno Oliveira
dca77b2273 Escape whitespace only strings when diffing them on failed assertions
Fix #3443
2018-05-03 20:38:00 -03:00
Bruno Oliveira
35f53a7353 Merge pull request #3442 from RonnyPfannschmidt/fix-3441-markexpr-markstorage
Fix #3441 let mark expressions be populated from the modern marker storage
2018-05-03 19:27:07 -03:00
Ronny Pfannschmidt
e6a86e0f4c add tests for #3441 2018-05-03 17:33:59 +02:00
Bruno Oliveira
b03b387861 Merge pull request #3436 from brianmaissy/feature/enter_pdb_on_keyboard_interrupt
--pdb treats KeyboardInterrupt as exception
2018-05-03 12:20:43 -03:00
Ronny Pfannschmidt
a5cf55dd4a fix test_mark_option_custom - it used the legacy keyword storage for addign markers 2018-05-03 16:33:16 +02:00
Ronny Pfannschmidt
63ef46dd91 fix #3441 - use iter-marks to populate markexpr namespace 2018-05-03 16:28:47 +02:00
Ronny Pfannschmidt
7834b45002 Merge pull request #3437 from nicoddemus/mark-changelog
Improve changelog note about markers
2018-05-02 06:45:39 +02:00
Bruno Oliveira
ccaa979f27 Improve changelog note about markers
Also changed the title in the docs because the previous title had
the same level as the title, making it appear in a separate entry
in `contents.rst`
2018-05-01 19:27:53 -03:00
Bruno Oliveira
1a880be85b Remove unused import to fix linting 2018-05-01 19:08:29 -03:00
Brian Maissy
c258fe1459 --pdb treats KeyboardInterrupt as exception 2018-05-02 00:58:35 +03:00
Ronny Pfannschmidt
08aed1a6bf Merge pull request #3433 from nicoddemus/conda-forge-badge
Use conda-forge badge instead of anaconda's
2018-04-27 16:11:58 +02:00
Bruno Oliveira
b49e9191ac Use conda-forge badge instead of anaconda's
Just noticed that conda-forge has its own badge so let's use that
2018-04-27 10:23:28 -03:00
Bruno Oliveira
febccae037 Merge pull request #3431 from jdufresne/pypi
Update all pypi.python.org URLs to pypi.org
2018-04-26 13:15:46 -03:00
Jon Dufresne
d2bf0bf9bb Update all pypi.python.org URLs to pypi.org
For details on the new PyPI, see the blog post:

https://pythoninsider.blogspot.ca/2018/04/new-pypi-launched-legacy-pypi-shutting.html
2018-04-26 06:49:33 -07:00
Ronny Pfannschmidt
5ba0663827 Merge pull request #3428 from nicoddemus/merge-master-into-features
Merge master into features
2018-04-25 14:04:41 +02:00
Bruno Oliveira
63368e07ea Merge remote-tracking branch 'upstream/master' into merge-master-into-features 2018-04-24 21:26:45 -03:00
Bruno Oliveira
0b2b73c36a Remove CHANGELOG entries left by old bug in towncrier 2018-04-24 21:25:13 -03:00
Bruno Oliveira
69b1c2d4f6 Merge pull request #3424 from nicoddemus/release-3.5.1
Preparing release version 3.5.1
2018-04-24 19:30:54 -03:00
Bruno Oliveira
4a92011e6e Fix note about importing from collections.abc 2018-04-24 07:06:52 -03:00
Ronny Pfannschmidt
6e62fc98ff Merge pull request #2849 from ApaDoctor/disable-repeated-fixture
provide error fixture applied to the same func
2018-04-24 06:36:54 +02:00
Bruno Oliveira
132fb61eba Merge remote-tracking branch 'upstream/features' into ApaDoctor/disable-repeated-fixture 2018-04-23 22:24:53 -03:00
Bruno Oliveira
03850cf962 Add test for applying fixture twice
Fix #2334
2018-04-23 22:17:46 -03:00
Bruno Oliveira
f05230c679 Move #3221 to trivial section in the CHANGELOG 2018-04-23 19:27:07 -03:00
Bruno Oliveira
d61a7670a1 Merge pull request #3422 from rachel1792/master
updated doc to delete deprecated hook: Issue #3417
2018-04-23 19:24:52 -03:00
Bruno Oliveira
8d56641590 Preparing release version 3.5.1 2018-04-23 22:24:21 +00:00
Bruno Oliveira
2a480c59ae Merge pull request #3367 from brianmaissy/feature/indicative_error_for_parametrize_with_default_argument
added indicative error when parametrizing an argument with a default …
2018-04-23 11:04:36 -03:00
Rachel Kogan
6ea4c12da7 updated doc to delete deprecated hook 2018-04-22 21:56:18 -04:00
Bruno Oliveira
f0084608cc Merge pull request #3407 from rachel1792/master
Fix typo in caplog fixture documentation: Issue #3406
2018-04-20 17:41:04 -03:00
Bruno Oliveira
cefeba33ef Update changelog formatting 2018-04-20 17:40:19 -03:00
Bruno Oliveira
3318e53d01 Merge pull request #3382 from feuillemorte/3290-improve-monkeypatch
#3290 improve monkeypatch
2018-04-19 17:05:52 -03:00
Ronny Pfannschmidt
1cc79ffc10 Merge pull request #3408 from MarSoft/patch-2
Fix typo in the comment
2018-04-19 09:21:11 +02:00
Семён Марьясин
d8015764e6 Fix typo in the comment 2018-04-18 12:47:52 +03:00
Rachel Kogan
48c99f62e3 add changelog 2018-04-17 16:24:32 -04:00
Rachel Kogan
8ff8a82c51 Merge branch 'master' of github.com:pytest-dev/pytest 2018-04-17 16:21:04 -04:00
Rachel Kogan
bb8984f5ed fix error in caplog docs. 2018-04-17 16:17:29 -04:00
Bruno Oliveira
159cd39777 Merge pull request #3401 from kohr-h/underscore_fixtures
Mention omission of fixtures with leading '_', closes #3398
2018-04-16 13:25:10 -03:00
Brian Maissy
857098fe0f added indicative error when parametrizing an argument with a default value 2018-04-15 20:52:57 +03:00
feuillemorte
283ac8bbf4 #3290 Fix doc 2018-04-14 21:06:58 +03:00
Holger Kohr
6626d2aef9 Mention omission of fixtures with leading '_', closes #3398 2018-04-14 11:04:00 +02:00
feuillemorte
ba7cad3962 #3290 Fix comments 2018-04-13 16:00:07 +03:00
Ronny Pfannschmidt
36f6687b70 Merge pull request #3397 from darrenburns/patch-2
Fix some mistakes in contributing.rst
2018-04-13 13:20:31 +02:00
Darren Burns
86def48b25 Fix some mistakes in contributing.rst 2018-04-13 11:33:58 +01:00
Bruno Oliveira
0024b71f1c Merge pull request #3395 from darrenburns/patch-1
Update CONTRIBUTING.rst
2018-04-12 18:42:33 -03:00
Ronny Pfannschmidt
17a43dc4a5 firther enhance the links in contributing.rst 2018-04-12 22:06:06 +02:00
Darren Burns
958f146125 Update CONTRIBUTING.rst
Fixes a broken link in CONTRIBUTING.rst
2018-04-12 20:54:32 +01:00
Ronny Pfannschmidt
13a6f63cd9 Merge pull request #3390 from nicoddemus/atomic-pyc-writes
Attempt to solve race-condition which corrupts .pyc files on Windows
2018-04-12 13:57:39 +02:00
Bruno Oliveira
aa95a425d7 Attempt to solve race-condition which corrupts .pyc files on Windows
This uses of the `atomicwrites` library.

This is very hard to create a reliable test for.

Fix #3008
2018-04-12 08:19:28 -03:00
Bruno Oliveira
015626ce69 Merge pull request #3384 from nicoddemus/leak-frame
Reset reference to failed test frame before each test executes
2018-04-12 07:53:34 -03:00
Ronny Pfannschmidt
f9a908abb8 Merge pull request #3388 from nicoddemus/simplify-tox
Simplify tox to avoid repetition
2018-04-12 11:32:48 +02:00
Ronny Pfannschmidt
160c309371 Merge pull request #3391 from nicoddemus/project-urls
Add additional project urls to setup.py
2018-04-12 08:54:12 +02:00
Ronny Pfannschmidt
f79b0324fe Merge pull request #3387 from nicoddemus/merge-master-into-features
Merge master into features
2018-04-12 08:39:22 +02:00
Bruno Oliveira
37ee4fbc48 Add additional project urls to setup.py
According to:

https://packaging.python.org/tutorials/distributing-packages/#project-urls

Those URLs are displayed in the project page in Warehouse (new PyPI).
2018-04-11 23:46:17 -03:00
Bruno Oliveira
888fcbc4b4 Simplify tox to avoid repetition
Also took the opportunity to:

* Use more cores for py*-xdist environments
* Update freeze test to use py36
2018-04-11 18:30:15 -03:00
Bruno Oliveira
10a7160549 Merge remote-tracking branch 'upstream/master' into merge-master-into-features 2018-04-11 18:07:47 -03:00
feuillemorte
a4daac7eb0 #3290 Fix doc 2018-04-11 12:46:02 +03:00
feuillemorte
97be076f29 #3290 Added changelog file 2018-04-11 12:45:46 +03:00
feuillemorte
3d60f955f0 #3290 Added test 2018-04-11 12:45:37 +03:00
feuillemorte
659c044372 #3290 Improved monkeypatch to support some form of with statement 2018-04-11 12:45:26 +03:00
Bruno Oliveira
6e8e3c967a Add changelog entry for #2798 2018-04-10 21:09:57 -03:00
Bruno Oliveira
78c900448e Add acceptance test for #2798 2018-04-10 21:04:30 -03:00
Ronny Pfannschmidt
372bcdba0c Merge pull request #3380 from nicoddemus/marks-fixes
Add the list of issues fixed by the new marker implementation to the docs
2018-04-10 14:33:58 +02:00
Bruno Oliveira
d1ba19acad Add the list of issues fixed by the new marker implementation to the docs
This will help make users more understanding if their code breaks under the
new implementation.
2018-04-10 08:00:32 -03:00
Ronny Pfannschmidt
2241c98b18 Merge pull request #3331 from tonybaloney/breakpoint_support
Support for the new builtin breakpoint function in Python 3.7
2018-04-10 07:15:29 +02:00
Bruno Oliveira
715337011b Merge pull request #3317 from RonnyPfannschmidt/marker-pristine-node-storage
introduce a distinct searchable non-broken storage for markers
2018-04-09 19:40:12 -03:00
Bruno Oliveira
e012dbe346 Merge pull request #3373 from backbord/master
Fix issue #3372
2018-04-06 22:10:57 -03:00
Tim Strazny
5bd8561016 linting: unfortunate dedent be gone. 2018-04-06 17:36:35 +02:00
Tim Strazny
846d91fb95 Follow Ronny's advice and use `type in base_type`. 2018-04-06 16:23:04 +02:00
Tim Strazny
0cd74dc324 Ensure object is class before calling issubclass. 2018-04-06 14:40:30 +02:00
Tim Strazny
ec2d8223cf Fix issue #3372 2018-04-06 14:16:12 +02:00
Ronny Pfannschmidt
4df8f2b153 fix doc build, use noindex on the mark reference 2018-04-06 08:13:28 +02:00
Ronny Pfannschmidt
5d4fe87b72 Merge pull request #3371 from nicoddemus/remove-labels-descriptions
Remove label descriptions from development guide
2018-04-06 07:39:15 +02:00
Bruno Oliveira
f17dfa4292 Remove label descriptions from development guide
The descriptions have been moved directly to GitHub's new label description
slot.
2018-04-05 20:55:08 -03:00
Bruno Oliveira
ab91771efc Merge pull request #3370 from dchudz/patch-1
no-capture in sample code demo'ing plugin
2018-04-05 20:25:04 -03:00
Bruno Oliveira
ef34de960c Merge pull request #3360 from RonnyPfannschmidt/xml_property_yay
record_property is no longer experimental
2018-04-05 20:03:22 -03:00
David Chudzicki
db24723b61 no-capture in sample code demo'ing plugin 2018-04-05 20:34:26 +02:00
Bruno Oliveira
e534cc81a3 Fix typos in docs 2018-04-05 14:45:30 -03:00
Ronny Pfannschmidt
3582e1f6be include more detail on the marker api issues 2018-04-05 18:46:33 +02:00
Ronny Pfannschmidt
a8ad89cdb3 fix documentation references 2018-04-05 18:39:57 +02:00
Bruno Oliveira
48bcc3419f Reword the docs on markers a bit 2018-04-05 12:39:21 -03:00
Ronny Pfannschmidt
1fcadeb2ce extend marker docs with reasons on marker iteration 2018-04-05 15:30:31 +02:00
Ronny Pfannschmidt
2018cf12b1 fix the record_property test 2018-04-05 14:05:26 +02:00
Bruno Oliveira
ba407b5eb6 Clear sys.last_* attributes before running an item
Otherwise we will keep the last failed exception around forever

Related to #2798
2018-04-04 20:36:07 -03:00
Ronny Pfannschmidt
ad0b4330e7 Merge pull request #3364 from sscherfke/more-itertools
Use correct spelling for "more-itertools"
2018-04-03 21:30:42 +02:00
Stefan Scherfke
9aa2a83785 Use correct spelling for "more-itertools" 2018-04-03 16:48:32 +02:00
Bruno Oliveira
0762666bd1 Remove unused pytestPDB import 2018-04-03 08:58:40 -03:00
Ronny Pfannschmidt
7c0c91a7a2 fix record_property test 2018-04-03 08:00:57 +02:00
Ronny Pfannschmidt
9326759a63 Merge pull request #3357 from nicoddemus/session-hooks-ref
Add reference docs for pytest_sessionstart/finish and update their docstrings
2018-04-03 07:08:47 +02:00
Anthony Shaw
4d847593b3 remove a test that would fail because pytest is being used to test itself 2018-04-03 10:40:56 +10:00
Bruno Oliveira
9a62ebf490 Merge pull request #3355 from irmen/py37deprfixes
change collections.abc import to fix deprecation warnings on python 3.7
2018-04-02 20:31:26 -03:00
Ronny Pfannschmidt
211f3c47b5 record_property is no longer experimental 2018-04-01 15:39:43 +02:00
Ronny Pfannschmidt
a2974dd067 fix doc building 2018-03-30 16:48:27 +02:00
Floris Bruynooghe
77128ee2dc Merge pull request #3356 from nicoddemus/remove-stale-changelog-entries
Remove stale CHANGELOG entries
2018-03-30 14:19:38 +02:00
Ronny Pfannschmidt
7454a381e2 update configuration examples to new mark api 2018-03-30 08:36:58 +02:00
Ronny Pfannschmidt
e4a52c1795 prevent doubleing of function level marks 2018-03-30 08:19:45 +02:00
Ronny Pfannschmidt
802da781c6 fix method reference to iter_markers in warning 2018-03-30 07:50:12 +02:00
Bruno Oliveira
3fc2c94b5e Switch imports based on python versions, my bad 2018-03-29 23:15:03 -03:00
Bruno Oliveira
daf1de0fed Add reference docs for pytest_sessionstart/finish and update their docstrings 2018-03-29 19:48:48 -03:00
Bruno Oliveira
e5eba8419a Remove stale CHANGELOG entries
Those were not removed in the last release because of a bug in
towncrier; I was about to fallback to don't use the .rst extension
for entries but just noticed that this was fixed in towncrier 17.8.0
so it should no longer be a problem.
2018-03-29 19:21:59 -03:00
Bruno Oliveira
6a81aae4f2 Move compatibility imports to compat.py and fix linting 2018-03-29 19:05:15 -03:00
Bruno Oliveira
8ca9321940 Move compatibility imports to compat.py and fix linting 2018-03-29 19:02:35 -03:00
Irmen de Jong
faded25ee8 chage collections.abc import to fix deprecation warnings on python 3.7 2018-03-29 20:02:00 +02:00
Ronny Pfannschmidt
dbb1b5a227 remove NodeMarkers, turn own_markers into a list and use iter_markers api exclusively 2018-03-29 18:24:10 +02:00
Ronny Pfannschmidt
8805036fd8 add node iteration apis
TODO: add tests
2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
ee51fa5881 add api to iterate over all marerks of a node 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
2cb7e725ce document the hack used to avoid duplicate markers due Instance collectors 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
02315c0489 remove unnecessary of in the code figuring the fixture names 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
a92a51b01b clarify find_markers return value 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
159ea9b7c0 turn Markinfo into atts clsas, and return correct instances of it from node.get_marker 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
775fb96ac3 first changelog entry 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
ced1316bc8 add docstrings for nodemarkers 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
5e56e9b4f6 refactor node markers, remove need to be aware of nodes 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
2d06ae0f65 base metafunc fixtureinfo on the functiondefinition to caputure its marks 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
99015bfc86 fix most of metafunc tests by mocking 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
180ae09202 deprecate markinfo and fix up most marker scoping access while completely breaking metafunc testing 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
e8feee0612 fix up the mark evaluator validity check 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
f1a1695aaa enable deep merging test - new structure fixed it 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
2707221559 port mark evaluation to the new storage and fix a bug in evaluation 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
360d608da4 introduce a own storage for markers 2018-03-29 17:52:01 +02:00
Ronny Pfannschmidt
f1c9efc358 Merge pull request #3353 from nicoddemus/fixture-param-marks-docs
Add docs about using pytest.param in parametrized fixtures
2018-03-29 10:57:28 +02:00
Bruno Oliveira
804392e5f2 Fix tests that check that breakpoint function is configured/restored
* Execute pytest in a subprocess in cases of tests which change global
  state
* Parametrize with --pdb and without the flag
2018-03-28 20:19:28 -03:00
Bruno Oliveira
0a3cd881f6 Add docs about using pytest.param in parametrized fixtures 2018-03-28 19:35:10 -03:00
Anthony Shaw
09e5a226dc add broken test 2018-03-29 09:03:20 +11:00
Ronny Pfannschmidt
2efaf39ed8 Merge pull request #3349 from jeffreyrack/3348-unknown-argument
3348: raise error on unknown arguments to raises
2018-03-28 21:45:59 +02:00
Bruno Oliveira
7656581302 Update changelog formatting 2018-03-28 07:31:26 -03:00
Bruno Oliveira
bfe773bfc8 Use shorter 'if kwargs' check as requested during review 2018-03-28 07:30:14 -03:00
Jeffrey Rackauckas
a5d9fbe2b0 Change pytest.raises to use match instead of matches 2018-03-27 20:24:15 -07:00
Jeffrey Rackauckas
34afded06d Update pytest.raises to raise a TypeError when an invalid keyword argument is passed. 2018-03-27 19:57:15 -07:00
Anthony Shaw
3998b70ff6 add test for custom environment variable 2018-03-28 09:02:37 +11:00
Bruno Oliveira
060f047a7e Use full link in CHANGELOG
Our rst-linter unfortunately doesn't accept `ref` directives in the CHANGELOG files
2018-03-27 18:35:47 -03:00
Bruno Oliveira
2962c7367c Merge pull request #3307 from KKoukiou/rhv-qe-fix
logging.py: Don't change log level of the root logger to bigger numeric value
2018-03-27 18:03:22 -03:00
Bruno Oliveira
0a4200bbb3 Improve docs formatting 2018-03-27 07:40:52 -03:00
Anthony Shaw
b45006e9a3 fix syntax 2018-03-27 21:26:55 +11:00
Anthony Shaw
671ab5a36c update documentation for new feature 2018-03-27 21:02:43 +11:00
Anthony Shaw
f1f4c8c104 updates for code review recommendations 2018-03-27 17:38:17 +11:00
Bruno Oliveira
6cfed00a61 Tweak changelog entry 2018-03-26 20:48:05 -03:00
Bruno Oliveira
ff3d13ed0e Update typo in fixture.rst 2018-03-26 11:20:33 -03:00
Katerina Koukiou
d895f5d6fc logging.py: Don't change log level of the root logger to bigger numeric value 2018-03-26 10:11:49 +02:00
Anthony Shaw
e97bd87ee2 fix assertion when hypothesis is installed (which is should be for developing in pytest) 2018-03-23 16:24:15 +11:00
Anthony Shaw
242fb7852b linting and removed double test 2018-03-23 15:39:34 +11:00
Anthony Shaw
1ec99132e6 add myself to authors 2018-03-23 15:31:57 +11:00
Anthony Shaw
dcbba381d4 add changelog entry 2018-03-23 15:31:16 +11:00
Anthony Shaw
db581eabcb add tests to validate that --pdbcls custom debugger classes will be called when breakpoint() is used 2018-03-23 15:30:05 +11:00
Anthony Shaw
0e83e4f292 conditional for resetting of sys.breakpointhook for cleanup where breakpoint() not supported 2018-03-23 14:26:16 +11:00
Anthony Shaw
21ada0fa23 add check for support of breakpoint() and use Custom Pdb class when system default is set 2018-03-23 14:20:10 +11:00
Anthony Shaw
a1ff758d0d "Added acceptance tests for configuration of sys.breakpointhook and resetting back when system default (pdb) is used"" 2018-03-23 14:18:56 +11:00
Bruno Oliveira
ed118d7f20 Merge remote-tracking branch 'upstream/features' 2018-03-22 21:06:09 -03:00
Bruno Oliveira
5ecff65285 Merge pull request #3327 from nicoddemus/release-3.5.0
Release 3.5.0
2018-03-22 20:58:15 -03:00
Ronny Pfannschmidt
fc4f769888 Merge pull request #3336 from nicoddemus/filter-warnings-ref-doc
Add missing reference doc for filterwarnings mark
2018-03-22 18:43:17 +01:00
Bruno Oliveira
f78953fd81 Add missing reference doc for filterwarnings mark 2018-03-22 13:02:30 -03:00
Ronny Pfannschmidt
d7d4afea17 Merge pull request #3330 from nicoddemus/remove-custom-flatten
Remove terminal.flatten function in favor of collapse from more_itertools
2018-03-22 14:22:47 +01:00
Anthony Shaw
5a53b9aabb move tests to test_pdb 2018-03-22 20:40:35 +11:00
Anthony Shaw
91d99affb7 assert that custom PDB class is used as breakpoint hook where supported 2018-03-22 17:40:14 +11:00
Anthony Shaw
3bca983a95 add a module global for whether the current runtime supports the builtin breakpoint function 2018-03-22 17:27:28 +11:00
Anthony Shaw
9edcb7edc6 start acceptance testing 2018-03-22 17:25:27 +11:00
Bruno Oliveira
6c2739d1e6 Add CHANGELOG for #3330 2018-03-21 20:23:17 -03:00
Bruno Oliveira
4e717eb626 Remove terminal.flatten function in favor of collapse from more_itertools 2018-03-21 20:20:46 -03:00
Bruno Oliveira
a7a39f1364 Update CHANGELOG formatting 2017-10-18 19:26:10 -02:00
ApaDoctor
cfd16d0dac provide error fixture applied to the same func
provide error fixture applied to the same func

provide error fixture applied to the same func
2017-10-18 12:01:08 +02:00
127 changed files with 1361 additions and 451 deletions

View File

@@ -17,11 +17,13 @@ Andreas Zeidler
Andrzej Ostrowski
Andy Freeland
Anthon van der Neut
Anthony Shaw
Anthony Sottile
Antony Lee
Armin Rigo
Aron Coyle
Aron Curzon
Aviral Verma
Aviv Palivoda
Barney Gale
Ben Webb
@@ -106,6 +108,7 @@ Jurko Gospodnetić
Justyna Janczyszyn
Kale Kundert
Katarzyna Jachim
Katerina Koukiou
Kevin Cox
Kodi B. Arfer
Kostis Anagnostopoulos
@@ -143,6 +146,7 @@ Michael Seifert
Michal Wajszczuk
Mihai Capotă
Mike Lundy
Miro Hrončok
Nathaniel Waisbrot
Ned Batchelder
Neven Mundar
@@ -188,6 +192,7 @@ Tareq Alayan
Ted Xiao
Thomas Grainger
Thomas Hisch
Tim Strazny
Tom Dalton
Tom Viner
Trevor Bekolay

View File

@@ -8,6 +8,144 @@
.. towncrier release notes start
Pytest 3.6.0 (2018-05-23)
=========================
Features
--------
- Revamp the internals of the ``pytest.mark`` implementation with correct per
node handling which fixes a number of long standing bugs caused by the old
design. This introduces new ``Node.iter_markers(name)`` and
``Node.get_closest_mark(name)`` APIs. Users are **strongly encouraged** to
read the `reasons for the revamp in the docs
<https://docs.pytest.org/en/latest/mark.html#marker-revamp-and-iteration>`_,
or jump over to details about `updating existing code to use the new APIs
<https://docs.pytest.org/en/latest/mark.html#updating-code>`_. (`#3317
<https://github.com/pytest-dev/pytest/issues/3317>`_)
- Now when ``@pytest.fixture`` is applied more than once to the same function a
``ValueError`` is raised. This buggy behavior would cause surprising problems
and if was working for a test suite it was mostly by accident. (`#2334
<https://github.com/pytest-dev/pytest/issues/2334>`_)
- Support for Python 3.7's builtin ``breakpoint()`` method, see `Using the
builtin breakpoint function
<https://docs.pytest.org/en/latest/usage.html#breakpoint-builtin>`_ for
details. (`#3180 <https://github.com/pytest-dev/pytest/issues/3180>`_)
- ``monkeypatch`` now supports a ``context()`` function which acts as a context
manager which undoes all patching done within the ``with`` block. (`#3290
<https://github.com/pytest-dev/pytest/issues/3290>`_)
- The ``--pdb`` option now causes KeyboardInterrupt to enter the debugger,
instead of stopping the test session. On python 2.7, hitting CTRL+C again
exits the debugger. On python 3.2 and higher, use CTRL+D. (`#3299
<https://github.com/pytest-dev/pytest/issues/3299>`_)
- pytest not longer changes the log level of the root logger when the
``log-level`` parameter has greater numeric value than that of the level of
the root logger, which makes it play better with custom logging configuration
in user code. (`#3307 <https://github.com/pytest-dev/pytest/issues/3307>`_)
Bug Fixes
---------
- A rare race-condition which might result in corrupted ``.pyc`` files on
Windows has been hopefully solved. (`#3008
<https://github.com/pytest-dev/pytest/issues/3008>`_)
- Also use iter_marker for discovering the marks applying for marker
expressions from the cli to avoid the bad data from the legacy mark storage.
(`#3441 <https://github.com/pytest-dev/pytest/issues/3441>`_)
- When showing diffs of failed assertions where the contents contain only
whitespace, escape them using ``repr()`` first to make it easy to spot the
differences. (`#3443 <https://github.com/pytest-dev/pytest/issues/3443>`_)
Improved Documentation
----------------------
- Change documentation copyright year to a range which auto-updates itself each
time it is published. (`#3303
<https://github.com/pytest-dev/pytest/issues/3303>`_)
Trivial/Internal Changes
------------------------
- ``pytest`` now depends on the `python-atomicwrites
<https://github.com/untitaker/python-atomicwrites>`_ library. (`#3008
<https://github.com/pytest-dev/pytest/issues/3008>`_)
- Update all pypi.python.org URLs to pypi.org. (`#3431
<https://github.com/pytest-dev/pytest/issues/3431>`_)
- Detect `pytest_` prefixed hooks using the internal plugin manager since
``pluggy`` is deprecating the ``implprefix`` argument to ``PluginManager``.
(`#3487 <https://github.com/pytest-dev/pytest/issues/3487>`_)
- Import ``Mapping`` and ``Sequence`` from ``_pytest.compat`` instead of
directly from ``collections`` in ``python_api.py::approx``. Add ``Mapping``
to ``_pytest.compat``, import it from ``collections`` on python 2, but from
``collections.abc`` on Python 3 to avoid a ``DeprecationWarning`` on Python
3.7 or newer. (`#3497 <https://github.com/pytest-dev/pytest/issues/3497>`_)
Pytest 3.5.1 (2018-04-23)
=========================
Bug Fixes
---------
- Reset ``sys.last_type``, ``sys.last_value`` and ``sys.last_traceback`` before
each test executes. Those attributes are added by pytest during the test run
to aid debugging, but were never reset so they would create a leaking
reference to the last failing test's frame which in turn could never be
reclaimed by the garbage collector. (`#2798
<https://github.com/pytest-dev/pytest/issues/2798>`_)
- ``pytest.raises`` now raises ``TypeError`` when receiving an unknown keyword
argument. (`#3348 <https://github.com/pytest-dev/pytest/issues/3348>`_)
- ``pytest.raises`` now works with exception classes that look like iterables.
(`#3372 <https://github.com/pytest-dev/pytest/issues/3372>`_)
Improved Documentation
----------------------
- Fix typo in ``caplog`` fixture documentation, which incorrectly identified
certain attributes as methods. (`#3406
<https://github.com/pytest-dev/pytest/issues/3406>`_)
Trivial/Internal Changes
------------------------
- Added a more indicative error message when parametrizing a function whose
argument takes a default value. (`#3221
<https://github.com/pytest-dev/pytest/issues/3221>`_)
- Remove internal ``_pytest.terminal.flatten`` function in favor of
``more_itertools.collapse``. (`#3330
<https://github.com/pytest-dev/pytest/issues/3330>`_)
- Import some modules from ``collections.abc`` instead of ``collections`` as
the former modules trigger ``DeprecationWarning`` in Python 3.7. (`#3339
<https://github.com/pytest-dev/pytest/issues/3339>`_)
- record_property is no longer experimental, removing the warnings was
forgotten. (`#3360 <https://github.com/pytest-dev/pytest/issues/3360>`_)
- Mention in documentation and CLI help that fixtures with leading ``_`` are
printed by ``pytest --fixtures`` only if the ``-v`` option is added. (`#3398
<https://github.com/pytest-dev/pytest/issues/3398>`_)
Pytest 3.5.0 (2018-03-21)
=========================
@@ -62,7 +200,7 @@ Features
- Captured log messages are added to the ``<system-out>`` tag in the generated
junit xml file if the ``junit_logging`` ini option is set to ``system-out``.
If the value of this ini option is ``system-err`, the logs are written to
If the value of this ini option is ``system-err``, the logs are written to
``<system-err>``. The default value for ``junit_logging`` is ``no``, meaning
captured logs are not written to the output file. (`#3156
<https://github.com/pytest-dev/pytest/issues/3156>`_)
@@ -136,7 +274,7 @@ Trivial/Internal Changes
- Internal ``mark.py`` module has been turned into a package. (`#3250
<https://github.com/pytest-dev/pytest/issues/3250>`_)
- ``pytest`` now depends on the `more_itertools
- ``pytest`` now depends on the `more-itertools
<https://github.com/erikrose/more-itertools>`_ package. (`#3265
<https://github.com/pytest-dev/pytest/issues/3265>`_)
@@ -1154,7 +1292,7 @@ Changes
* Testcase reports with a ``url`` attribute will now properly write this to junitxml.
Thanks `@fushi`_ for the PR (`#1874`_).
* Remove common items from dict comparision output when verbosity=1. Also update
* Remove common items from dict comparison output when verbosity=1. Also update
the truncation message to make it clearer that pytest truncates all
assertion messages if verbosity < 2 (`#1512`_).
Thanks `@mattduck`_ for the PR
@@ -1166,7 +1304,7 @@ Changes
* fix `#2013`_: turn RecordedWarning into ``namedtuple``,
to give it a comprehensible repr while preventing unwarranted modification.
* fix `#2208`_: ensure a iteration limit for _pytest.compat.get_real_func.
* fix `#2208`_: ensure an iteration limit for _pytest.compat.get_real_func.
Thanks `@RonnyPfannschmidt`_ for the report and PR.
* Hooks are now verified after collection is complete, rather than right after loading installed plugins. This
@@ -1270,7 +1408,7 @@ Bug Fixes
Notably, importing the ``anydbm`` module is fixed. (`#2248`_).
Thanks `@pfhayes`_ for the PR.
* junitxml: Fix problematic case where system-out tag occured twice per testcase
* junitxml: Fix problematic case where system-out tag occurred twice per testcase
element in the XML report. Thanks `@kkoukiou`_ for the PR.
* Fix regression, pytest now skips unittest correctly if run with ``--pdb``
@@ -2866,7 +3004,7 @@ time or change existing behaviors in order to make them less surprising/more use
"::" node id specifications (copy pasted from "-v" output)
- fix issue544 by only removing "@NUM" at the end of "::" separated parts
and if the part has an ".py" extension
and if the part has a ".py" extension
- don't use py.std import helper, rather import things directly.
Thanks Bruno Oliveira.
@@ -3137,7 +3275,7 @@ time or change existing behaviors in order to make them less surprising/more use
would not work correctly because pytest assumes @pytest.mark.some
gets a function to be decorated already. We now at least detect if this
arg is an lambda and thus the example will work. Thanks Alex Gaynor
arg is a lambda and thus the example will work. Thanks Alex Gaynor
for bringing it up.
- xfail a test on pypy that checks wrong encoding/ascii (pypy does
@@ -3450,7 +3588,7 @@ Bug fixes:
rather use the post-2.0 parametrize features instead of yield, see:
http://pytest.org/latest/example/parametrize.html
- fix autouse-issue where autouse-fixtures would not be discovered
if defined in a a/conftest.py file and tests in a/tests/test_some.py
if defined in an a/conftest.py file and tests in a/tests/test_some.py
- fix issue226 - LIFO ordering for fixture teardowns
- fix issue224 - invocations with >256 char arguments now work
- fix issue91 - add/discuss package/directory level setups in example
@@ -4020,7 +4158,7 @@ Bug fixes:
- make path.bestrelpath(path) return ".", note that when calling
X.bestrelpath the assumption is that X is a directory.
- make initial conftest discovery ignore "--" prefixed arguments
- fix resultlog plugin when used in an multicpu/multihost xdist situation
- fix resultlog plugin when used in a multicpu/multihost xdist situation
(thanks Jakub Gustak)
- perform distributed testing related reporting in the xdist-plugin
rather than having dist-related code in the generic py.test

View File

@@ -48,8 +48,7 @@ fix the bug itself.
Fix bugs
--------
Look through the GitHub issues for bugs. Here is a filter you can use:
https://github.com/pytest-dev/pytest/labels/type%3A%20bug
Look through the `GitHub issues for bugs <https://github.com/pytest-dev/pytest/labels/type:%20bug>`_.
:ref:`Talk <contact>` to developers to find out how you can fix specific bugs.
@@ -60,8 +59,7 @@ Don't forget to check the issue trackers of your favourite plugins, too!
Implement features
------------------
Look through the GitHub issues for enhancements. Here is a filter you can use:
https://github.com/pytest-dev/pytest/labels/enhancement
Look through the `GitHub issues for enhancements <https://github.com/pytest-dev/pytest/labels/type:%20enhancement>`_.
:ref:`Talk <contact>` to developers to find out how you can implement specific
features.

View File

@@ -6,13 +6,13 @@
------
.. image:: https://img.shields.io/pypi/v/pytest.svg
:target: https://pypi.python.org/pypi/pytest
:target: https://pypi.org/project/pytest/
.. image:: https://anaconda.org/conda-forge/pytest/badges/version.svg
.. image:: https://img.shields.io/conda/vn/conda-forge/pytest.svg
:target: https://anaconda.org/conda-forge/pytest
.. image:: https://img.shields.io/pypi/pyversions/pytest.svg
:target: https://pypi.python.org/pypi/pytest
:target: https://pypi.org/project/pytest/
.. image:: https://img.shields.io/coveralls/pytest-dev/pytest/master.svg
:target: https://coveralls.io/r/pytest-dev/pytest

View File

@@ -14,7 +14,7 @@ cpy_compile = compile
class Source(object):
""" a immutable object holding a source code fragment,
""" an immutable object holding a source code fragment,
possibly deindenting it.
"""
_compilecounter = 0

View File

@@ -12,7 +12,9 @@ import struct
import sys
import types
import atomicwrites
import py
from _pytest.assertion import util
@@ -140,7 +142,7 @@ class AssertionRewritingHook(object):
# Probably a SyntaxError in the test.
return None
if write:
_make_rewritten_pyc(state, source_stat, pyc, co)
_write_pyc(state, co, source_stat, pyc)
else:
state.trace("found cached rewritten pyc for %r" % (fn,))
self.modules[name] = co, pyc
@@ -258,22 +260,21 @@ def _write_pyc(state, co, source_stat, pyc):
# sometime to be able to use imp.load_compiled to load them. (See
# the comment in load_module above.)
try:
fp = open(pyc, "wb")
except IOError:
err = sys.exc_info()[1].errno
state.trace("error writing pyc file at %s: errno=%s" % (pyc, err))
with atomicwrites.atomic_write(pyc, mode="wb", overwrite=True) as fp:
fp.write(imp.get_magic())
mtime = int(source_stat.mtime)
size = source_stat.size & 0xFFFFFFFF
fp.write(struct.pack("<ll", mtime, size))
if six.PY2:
marshal.dump(co, fp.file)
else:
marshal.dump(co, fp)
except EnvironmentError as e:
state.trace("error writing pyc file at %s: errno=%s" % (pyc, e.errno))
# we ignore any failure to write the cache file
# there are many reasons, permission-denied, __pycache__ being a
# file etc.
return False
try:
fp.write(imp.get_magic())
mtime = int(source_stat.mtime)
size = source_stat.size & 0xFFFFFFFF
fp.write(struct.pack("<ll", mtime, size))
marshal.dump(co, fp)
finally:
fp.close()
return True
@@ -338,20 +339,6 @@ def _rewrite_test(config, fn):
return stat, co
def _make_rewritten_pyc(state, source_stat, pyc, co):
"""Try to dump rewritten code to *pyc*."""
if sys.platform.startswith("win"):
# Windows grants exclusive access to open files and doesn't have atomic
# rename, so just write into the final file.
_write_pyc(state, co, source_stat, pyc)
else:
# When not on windows, assume rename is atomic. Dump the code object
# into a file specific to this process and atomically replace it.
proc_pyc = pyc + "." + str(os.getpid())
if _write_pyc(state, co, source_stat, proc_pyc):
os.rename(proc_pyc, pyc)
def _read_pyc(source, pyc, trace=lambda x: None):
"""Possibly read a pytest pyc containing rewritten code.

View File

@@ -5,7 +5,7 @@ import pprint
import _pytest._code
import py
import six
from collections import Sequence
from ..compat import Sequence
u = six.text_type
@@ -171,10 +171,22 @@ def _diff_text(left, right, verbose=False):
"""
from difflib import ndiff
explanation = []
def escape_for_readable_diff(binary_text):
"""
Ensures that the internal string is always valid unicode, converting any bytes safely to valid unicode.
This is done using repr() which then needs post-processing to fix the encompassing quotes and un-escape
newlines and carriage returns (#429).
"""
r = six.text_type(repr(binary_text)[1:-1])
r = r.replace(r'\n', '\n')
r = r.replace(r'\r', '\r')
return r
if isinstance(left, six.binary_type):
left = u(repr(left)[1:-1]).replace(r'\n', '\n')
left = escape_for_readable_diff(left)
if isinstance(right, six.binary_type):
right = u(repr(right)[1:-1]).replace(r'\n', '\n')
right = escape_for_readable_diff(right)
if not verbose:
i = 0 # just in case left or right has zero length
for i in range(min(len(left), len(right))):
@@ -197,6 +209,10 @@ def _diff_text(left, right, verbose=False):
left = left[:-i]
right = right[:-i]
keepends = True
if left.isspace() or right.isspace():
left = repr(str(left))
right = repr(str(right))
explanation += [u'Strings contain only whitespace, escaping them using repr()']
explanation += [line.strip('\n')
for line in ndiff(left.splitlines(keepends),
right.splitlines(keepends))]

View File

@@ -315,7 +315,7 @@ class CaptureFixture(object):
def safe_text_dupfile(f, mode, default_encoding="UTF8"):
""" return a open text file object that's a duplicate of f on the
""" return an open text file object that's a duplicate of f on the
FD-level if possible.
"""
encoding = getattr(f, "encoding", None)

View File

@@ -38,6 +38,14 @@ PY35 = sys.version_info[:2] >= (3, 5)
PY36 = sys.version_info[:2] >= (3, 6)
MODULE_NOT_FOUND_ERROR = 'ModuleNotFoundError' if PY36 else 'ImportError'
if _PY3:
from collections.abc import MutableMapping as MappingMixin # noqa
from collections.abc import Mapping, Sequence # noqa
else:
# those raise DeprecationWarnings in Python >=3.7
from collections import MutableMapping as MappingMixin # noqa
from collections import Mapping, Sequence # noqa
def _format_args(func):
return str(signature(func))
@@ -127,6 +135,14 @@ def getfuncargnames(function, is_method=False, cls=None):
return arg_names
def get_default_arg_names(function):
# Note: this code intentionally mirrors the code at the beginning of getfuncargnames,
# to get the arguments which were excluded from its result because they had default values
return tuple(p.name for p in signature(function).parameters.values()
if p.kind in (Parameter.POSITIONAL_OR_KEYWORD, Parameter.KEYWORD_ONLY) and
p.default is not Parameter.empty)
if _PY3:
STRING_TYPES = bytes, str
UNICODE_TYPES = str,
@@ -241,7 +257,7 @@ def safe_getattr(object, name, default):
def _is_unittest_unexpected_success_a_failure():
"""Return if the test suite should fail if a @expectedFailure unittest test PASSES.
"""Return if the test suite should fail if an @expectedFailure unittest test PASSES.
From https://docs.python.org/3/library/unittest.html?highlight=unittest#unittest.TestResult.wasSuccessful:
Changed in version 3.4: Returns False if there were any

View File

@@ -177,7 +177,7 @@ class PytestPluginManager(PluginManager):
"""
def __init__(self):
super(PytestPluginManager, self).__init__("pytest", implprefix="pytest_")
super(PytestPluginManager, self).__init__("pytest")
self._conftest_plugins = set()
# state related to local conftest plugins
@@ -231,6 +231,11 @@ class PytestPluginManager(PluginManager):
method = getattr(plugin, name)
opts = super(PytestPluginManager, self).parse_hookimpl_opts(plugin, name)
# collect unmarked hooks as long as they have the `pytest_' prefix
if opts is None and name.startswith("pytest_"):
opts = {}
if opts is not None:
for name in ("tryfirst", "trylast", "optionalhook", "hookwrapper"):
opts.setdefault(name, hasattr(method, name))

View File

@@ -2,14 +2,21 @@
from __future__ import absolute_import, division, print_function
import pdb
import sys
import os
from doctest import UnexpectedException
try:
from builtins import breakpoint # noqa
SUPPORTS_BREAKPOINT_BUILTIN = True
except ImportError:
SUPPORTS_BREAKPOINT_BUILTIN = False
def pytest_addoption(parser):
group = parser.getgroup("general")
group._addoption(
'--pdb', dest="usepdb", action="store_true",
help="start the interactive Python debugger on errors.")
help="start the interactive Python debugger on errors or KeyboardInterrupt.")
group._addoption(
'--pdbcls', dest="usepdb_cls", metavar="modulename:classname",
help="start a custom interactive Python debugger on errors. "
@@ -27,12 +34,20 @@ def pytest_configure(config):
if config.getvalue("usepdb"):
config.pluginmanager.register(PdbInvoke(), 'pdbinvoke')
# Use custom Pdb class set_trace instead of default Pdb on breakpoint() call
if SUPPORTS_BREAKPOINT_BUILTIN:
_environ_pythonbreakpoint = os.environ.get('PYTHONBREAKPOINT', '')
if _environ_pythonbreakpoint == '':
sys.breakpointhook = pytestPDB.set_trace
old = (pdb.set_trace, pytestPDB._pluginmanager)
def fin():
pdb.set_trace, pytestPDB._pluginmanager = old
pytestPDB._config = None
pytestPDB._pdb_cls = pdb.Pdb
if SUPPORTS_BREAKPOINT_BUILTIN:
sys.breakpointhook = sys.__breakpointhook__
pdb.set_trace = pytestPDB.set_trace
pytestPDB._pluginmanager = config.pluginmanager

View File

@@ -32,7 +32,9 @@ RESULT_LOG = (
)
MARK_INFO_ATTRIBUTE = RemovedInPytest4Warning(
"MarkInfo objects are deprecated as they contain the merged marks"
"MarkInfo objects are deprecated as they contain merged marks which are hard to deal with correctly.\n"
"Please use node.get_closest_marker(name) or node.iter_markers(name).\n"
"Docs: https://docs.pytest.org/en/latest/mark.html#updating-code"
)
MARK_PARAMETERSET_UNPACKING = RemovedInPytest4Warning(

View File

@@ -24,7 +24,7 @@ DOCTEST_REPORT_CHOICES = (
DOCTEST_REPORT_CHOICE_ONLY_FIRST_FAILURE,
)
# Lazy definiton of runner class
# Lazy definition of runner class
RUNNER_CLASS = None

View File

@@ -5,6 +5,7 @@ import inspect
import sys
import warnings
from collections import OrderedDict, deque, defaultdict
from more_itertools import flatten
import attr
import py
@@ -290,7 +291,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
def _getnextfixturedef(self, argname):
fixturedefs = self._arg2fixturedefs.get(argname, None)
if fixturedefs is None:
# we arrive here because of a a dynamic call to
# we arrive here because of a dynamic call to
# getfixturevalue(argname) usage which was naturally
# not known at parsing/collection time
parentid = self._pyfuncitem.parent.nodeid
@@ -371,10 +372,7 @@ class FixtureRequest(FuncargnamesCompatAttr):
:arg marker: a :py:class:`_pytest.mark.MarkDecorator` object
created by a call to ``pytest.mark.NAME(...)``.
"""
try:
self.node.keywords[marker.markname] = marker
except AttributeError:
raise ValueError(marker)
self.node.add_marker(marker)
def raiseerror(self, msg):
""" raise a FixtureLookupError with the given message. """
@@ -853,6 +851,11 @@ class FixtureFunctionMarker(object):
if isclass(function):
raise ValueError(
"class fixtures not supported (may be in the future)")
if getattr(function, "_pytestfixturefunction", False):
raise ValueError(
"fixture is being applied more than once to the same function")
function._pytestfixturefunction = self
return function
@@ -985,10 +988,9 @@ class FixtureManager(object):
argnames = getfuncargnames(func, cls=cls)
else:
argnames = ()
usefixtures = getattr(func, "usefixtures", None)
usefixtures = flatten(mark.args for mark in node.iter_markers(name="usefixtures"))
initialnames = argnames
if usefixtures is not None:
initialnames = usefixtures.args + initialnames
initialnames = tuple(usefixtures) + initialnames
fm = node.session._fixturemanager
names_closure, arg2fixturedefs = fm.getfixtureclosure(initialnames,
node)
@@ -1026,7 +1028,7 @@ class FixtureManager(object):
def getfixtureclosure(self, fixturenames, parentnode):
# collect the closure of all fixtures , starting with the given
# fixturenames as the initial set. As we have to visit all
# factory definitions anyway, we also return a arg2fixturedefs
# factory definitions anyway, we also return an arg2fixturedefs
# mapping so that the caller can reuse it and does not have
# to re-discover fixturedefs again for each fixturename
# (discovering matching fixtures for a given name/node is expensive)
@@ -1070,6 +1072,8 @@ class FixtureManager(object):
fixturedef = faclist[-1]
if fixturedef.params is not None:
parametrize_func = getattr(metafunc.function, 'parametrize', None)
if parametrize_func is not None:
parametrize_func = parametrize_func.combined
func_params = getattr(parametrize_func, 'args', [[None]])
func_kwargs = getattr(parametrize_func, 'kwargs', {})
# skip directly parametrized arguments

View File

@@ -7,7 +7,7 @@ from __future__ import absolute_import, division, print_function
def freeze_includes():
"""
Returns a list of module names used by py.test that should be
Returns a list of module names used by pytest that should be
included by cx_freeze.
"""
import py

View File

@@ -138,7 +138,8 @@ def showhelp(config):
tw.line("to see available markers type: pytest --markers")
tw.line("to see available fixtures type: pytest --fixtures")
tw.line("(shown according to specified file_or_dir or current dir "
"if not specified)")
"if not specified; fixtures with leading '_' are only shown "
"with the '-v' option")
for warningreport in reporter.stats.get('warnings', []):
tw.line("warning : " + warningreport.message, red=True)

View File

@@ -413,14 +413,15 @@ def pytest_fixture_post_finalizer(fixturedef, request):
def pytest_sessionstart(session):
""" before session.main() is called.
""" called after the ``Session`` object has been created and before performing collection
and entering the run test loop.
:param _pytest.main.Session session: the pytest session object
"""
def pytest_sessionfinish(session, exitstatus):
""" whole test run finishes.
""" called after whole test run finished, right before returning the exit status to the system.
:param _pytest.main.Session session: the pytest session object
:param int exitstatus: the status which pytest will return to the system

View File

@@ -245,11 +245,6 @@ def record_property(request):
def test_function(record_property):
record_property("example_key", 1)
"""
request.node.warn(
code='C3',
message='record_property is an experimental feature',
)
def append_property(name, value):
request.node.user_properties.append((name, value))
return append_property

View File

@@ -153,7 +153,7 @@ def catching_logs(handler, formatter=None, level=None):
root_logger.addHandler(handler)
if level is not None:
orig_level = root_logger.level
root_logger.setLevel(level)
root_logger.setLevel(min(orig_level, level))
try:
yield handler
finally:
@@ -289,9 +289,9 @@ def caplog(request):
Captured logs are available through the following methods::
* caplog.text() -> string containing formatted log output
* caplog.records() -> list of logging.LogRecord instances
* caplog.record_tuples() -> list of (logger_name, level, message) tuples
* caplog.text -> string containing formatted log output
* caplog.records -> list of logging.LogRecord instances
* caplog.record_tuples -> list of (logger_name, level, message) tuples
* caplog.clear() -> clear captured records and formatted log output string
"""
result = LogCaptureFixture(request.node)

View File

@@ -90,7 +90,7 @@ def pytest_addoption(parser):
def pytest_configure(config):
__import__('pytest').config = config # compatibiltiy
__import__('pytest').config = config # compatibility
def wrap_session(config, doit):
@@ -290,7 +290,7 @@ class Interrupted(KeyboardInterrupt):
class Failed(Exception):
""" signals an stop as failed test run. """
""" signals a stop as failed test run. """
class Session(nodes.FSCollector):
@@ -333,7 +333,7 @@ class Session(nodes.FSCollector):
def gethookproxy(self, fspath):
# check if we have the common case of running
# hooks with all conftest.py filesall conftest.py
# hooks with all conftest.py files
pm = self.config.pluginmanager
my_conftestmodules = pm._getconftestmodules(fspath)
remove_mods = pm._conftest_plugins.difference(my_conftestmodules)

View File

@@ -20,7 +20,8 @@ class MarkerError(Exception):
def param(*values, **kw):
"""Specify a parameter in a `pytest.mark.parametrize`_ call.
"""Specify a parameter in `pytest.mark.parametrize`_ calls or
:ref:`parametrized fixtures <fixture-parametrize-marks>`.
.. code-block:: python

View File

@@ -4,7 +4,6 @@ import sys
import platform
import traceback
from . import MarkDecorator, MarkInfo
from ..outcomes import fail, TEST_OUTCOME
@@ -28,22 +27,15 @@ class MarkEvaluator(object):
self._mark_name = name
def __bool__(self):
self._marks = self._get_marks()
return bool(self._marks)
# dont cache here to prevent staleness
return bool(self._get_marks())
__nonzero__ = __bool__
def wasvalid(self):
return not hasattr(self, 'exc')
def _get_marks(self):
keyword = self.item.keywords.get(self._mark_name)
if isinstance(keyword, MarkDecorator):
return [keyword.mark]
elif isinstance(keyword, MarkInfo):
return [x.combined for x in keyword]
else:
return []
return list(self.item.iter_markers(name=self._mark_name))
def invalidraise(self, exc):
raises = self.get('raises')

View File

@@ -5,8 +5,6 @@ we hope ot remove
import attr
import keyword
from . import MarkInfo, MarkDecorator
from _pytest.config import UsageError
@@ -18,11 +16,8 @@ class MarkMapping(object):
own_mark_names = attr.ib()
@classmethod
def from_keywords(cls, keywords):
mark_names = set()
for key, value in keywords.items():
if isinstance(value, MarkInfo) or isinstance(value, MarkDecorator):
mark_names.add(key)
def from_item(cls, item):
mark_names = set(mark.name for mark in item.iter_markers())
return cls(mark_names)
def __getitem__(self, name):
@@ -70,7 +65,7 @@ python_keywords_allowed_list = ["or", "and", "not"]
def matchmark(colitem, markexpr):
"""Tries to match on any marker names, attached to the given colitem."""
return eval(markexpr, {}, MarkMapping.from_keywords(colitem.keywords))
return eval(markexpr, {}, MarkMapping.from_item(colitem))
def matchkeyword(colitem, keywordexpr):

View File

@@ -1,12 +1,13 @@
from collections import namedtuple, MutableMapping as MappingMixin
import warnings
from operator import attrgetter
import inspect
import warnings
from collections import namedtuple
from operator import attrgetter
import attr
from ..deprecated import MARK_PARAMETERSET_UNPACKING
from ..compat import NOTSET, getfslineno
from six.moves import map
from ..deprecated import MARK_PARAMETERSET_UNPACKING, MARK_INFO_ATTRIBUTE
from ..compat import NOTSET, getfslineno, MappingMixin
from six.moves import map, reduce
EMPTY_PARAMETERSET_OPTION = "empty_parameter_set_mark"
@@ -113,11 +114,21 @@ class ParameterSet(namedtuple('ParameterSet', 'values, marks, id')):
@attr.s(frozen=True)
class Mark(object):
name = attr.ib()
args = attr.ib()
kwargs = attr.ib()
#: name of the mark
name = attr.ib(type=str)
#: positional arguments of the mark decorator
args = attr.ib(type="List[object]")
#: keyword arguments of the mark decorator
kwargs = attr.ib(type="Dict[str, object]")
def combined_with(self, other):
"""
:param other: the mark to combine with
:type other: Mark
:rtype: Mark
combines by appending aargs and merging the mappings
"""
assert self.name == other.name
return Mark(
self.name, self.args + other.args,
@@ -204,7 +215,7 @@ class MarkDecorator(object):
def get_unpacked_marks(obj):
"""
obtain the unpacked marks that are stored on a object
obtain the unpacked marks that are stored on an object
"""
mark_list = getattr(obj, 'pytestmark', [])
@@ -217,7 +228,7 @@ def get_unpacked_marks(obj):
def store_mark(obj, mark):
"""store a Mark on a object
"""store a Mark on an object
this is used to implement the Mark declarations/decorators correctly
"""
assert isinstance(mark, Mark), mark
@@ -233,7 +244,7 @@ def store_legacy_markinfo(func, mark):
raise TypeError("got {mark!r} instead of a Mark".format(mark=mark))
holder = getattr(func, mark.name, None)
if holder is None:
holder = MarkInfo(mark)
holder = MarkInfo.for_mark(mark)
setattr(func, mark.name, holder)
else:
holder.add_mark(mark)
@@ -260,23 +271,29 @@ def _marked(func, mark):
invoked more than once.
"""
try:
func_mark = getattr(func, mark.name)
func_mark = getattr(func, getattr(mark, 'combined', mark).name)
except AttributeError:
return False
return mark.args == func_mark.args and mark.kwargs == func_mark.kwargs
return any(mark == info.combined for info in func_mark)
@attr.s
class MarkInfo(object):
""" Marking object created by :class:`MarkDecorator` instances. """
def __init__(self, mark):
assert isinstance(mark, Mark), repr(mark)
self.combined = mark
self._marks = [mark]
_marks = attr.ib()
combined = attr.ib(
repr=False,
default=attr.Factory(lambda self: reduce(Mark.combined_with, self._marks),
takes_self=True))
name = alias('combined.name')
args = alias('combined.args')
kwargs = alias('combined.kwargs')
name = alias('combined.name', warning=MARK_INFO_ATTRIBUTE)
args = alias('combined.args', warning=MARK_INFO_ATTRIBUTE)
kwargs = alias('combined.kwargs', warning=MARK_INFO_ATTRIBUTE)
@classmethod
def for_mark(cls, mark):
return cls([mark])
def __repr__(self):
return "<MarkInfo {0!r}>".format(self.combined)
@@ -288,7 +305,7 @@ class MarkInfo(object):
def __iter__(self):
""" yield MarkInfo objects each relating to a marking-call. """
return map(MarkInfo, self._marks)
return map(MarkInfo.for_mark, self._marks)
class MarkGenerator(object):
@@ -365,3 +382,33 @@ class NodeKeywords(MappingMixin):
def __repr__(self):
return "<NodeKeywords for node %s>" % (self.node, )
@attr.s(cmp=False, hash=False)
class NodeMarkers(object):
"""
internal strucutre for storing marks belongong to a node
..warning::
unstable api
"""
own_markers = attr.ib(default=attr.Factory(list))
def update(self, add_markers):
"""update the own markers
"""
self.own_markers.extend(add_markers)
def find(self, name):
"""
find markers in own nodes or parent nodes
needs a better place
"""
for mark in self.own_markers:
if mark.name == name:
yield mark
def __iter__(self):
return iter(self.own_markers)

View File

@@ -4,6 +4,8 @@ from __future__ import absolute_import, division, print_function
import os
import sys
import re
from contextlib import contextmanager
import six
from _pytest.fixtures import fixture
@@ -106,6 +108,29 @@ class MonkeyPatch(object):
self._cwd = None
self._savesyspath = None
@contextmanager
def context(self):
"""
Context manager that returns a new :class:`MonkeyPatch` object which
undoes any patching done inside the ``with`` block upon exit:
.. code-block:: python
import functools
def test_partial(monkeypatch):
with monkeypatch.context() as m:
m.setattr(functools, "partial", 3)
Useful in situations where it is desired to undo some patches before the test ends,
such as mocking ``stdlib`` functions that might break pytest itself if mocked (for examples
of this see `#3290 <https://github.com/pytest-dev/pytest/issues/3290>`_.
"""
m = MonkeyPatch()
try:
yield m
finally:
m.undo()
def setattr(self, target, name, value=notset, raising=True):
""" Set attribute value on target, memorizing the old value.
By default raise AttributeError if the attribute did not exist.

View File

@@ -8,7 +8,7 @@ import attr
import _pytest
import _pytest._code
from _pytest.mark.structures import NodeKeywords
from _pytest.mark.structures import NodeKeywords, MarkInfo
SEP = "/"
@@ -90,6 +90,9 @@ class Node(object):
#: keywords/markers collected from all scopes
self.keywords = NodeKeywords(self)
#: the marker objects belonging to this node
self.own_markers = []
#: allow adding of extra keywords to use for matching
self.extra_keyword_matches = set()
@@ -178,15 +181,50 @@ class Node(object):
elif not isinstance(marker, MarkDecorator):
raise ValueError("is not a string or pytest.mark.* Marker")
self.keywords[marker.name] = marker
self.own_markers.append(marker)
def iter_markers(self, name=None):
"""
:param name: if given, filter the results by the name attribute
iterate over all markers of the node
"""
return (x[1] for x in self.iter_markers_with_node(name=name))
def iter_markers_with_node(self, name=None):
"""
:param name: if given, filter the results by the name attribute
iterate over all markers of the node
returns sequence of tuples (node, mark)
"""
for node in reversed(self.listchain()):
for mark in node.own_markers:
if name is None or getattr(mark, 'name', None) == name:
yield node, mark
def get_closest_marker(self, name, default=None):
"""return the first marker matching the name, from closest (for example function) to farther level (for example
module level).
:param default: fallback return value of no marker was found
:param name: name to filter by
"""
return next(self.iter_markers(name=name), default)
def get_marker(self, name):
""" get a marker object from this node or None if
the node doesn't have a marker with that name. """
val = self.keywords.get(name, None)
if val is not None:
from _pytest.mark import MarkInfo, MarkDecorator
if isinstance(val, (MarkDecorator, MarkInfo)):
return val
the node doesn't have a marker with that name.
.. deprecated:: 3.6
This function has been deprecated in favor of
:meth:`Node.get_closest_marker <_pytest.nodes.Node.get_closest_marker>` and
:meth:`Node.iter_markers <_pytest.nodes.Node.iter_markers>`, see :ref:`update marker code`
for more details.
"""
markers = list(self.iter_markers(name=name))
if markers:
return MarkInfo(markers)
def listextrakeywords(self):
""" Return a set of all extra keywords in self and any parents."""

View File

@@ -83,7 +83,7 @@ skip.Exception = Skipped
def fail(msg="", pytrace=True):
""" explicitly fail an currently-executing test with the given Message.
""" explicitly fail a currently-executing test with the given Message.
:arg pytrace: if false the msg represents the full failure information
and no python traceback will be reported.

View File

@@ -714,7 +714,7 @@ class Testdir(object):
"""
finalizers = []
try:
# When running py.test inline any plugins active in the main test
# When running pytest inline any plugins active in the main test
# process are already imported. So this disables the warning which
# will trigger to say they can no longer be rewritten, which is
# fine as they have already been rewritten.
@@ -725,7 +725,7 @@ class Testdir(object):
finalizers.append(revert_warn_already_imported)
AssertionRewritingHook._warn_already_imported = lambda *a: None
# Any sys.module or sys.path changes done while running py.test
# Any sys.module or sys.path changes done while running pytest
# inline should be reverted after the test run completes to avoid
# clashing with later inline tests run within the same pytest test,
# e.g. just because they use matching test module names.

View File

@@ -25,10 +25,10 @@ from _pytest.compat import (
isclass, isfunction, is_generator, ascii_escaped,
REGEX_TYPE, STRING_TYPES, NoneType, NOTSET,
get_real_func, getfslineno, safe_getattr,
safe_str, getlocation, enum,
safe_str, getlocation, enum, get_default_arg_names
)
from _pytest.outcomes import fail
from _pytest.mark.structures import transfer_markers
from _pytest.mark.structures import transfer_markers, get_unpacked_marks
# relative paths that we use to filter traceback entries from appearing to the user;
@@ -55,7 +55,7 @@ def filter_traceback(entry):
is_generated = '<' in raw_filename and '>' in raw_filename
if is_generated:
return False
# entry.path might point to an non-existing file, in which case it will
# entry.path might point to a non-existing file, in which case it will
# also return a str object. see #1133
p = py.path.local(entry.path)
return not p.relto(_pluggy_dir) and not p.relto(_pytest_dir) and not p.relto(_py_dir)
@@ -75,7 +75,8 @@ def pytest_addoption(parser):
group = parser.getgroup("general")
group.addoption('--fixtures', '--funcargs',
action="store_true", dest="showfixtures", default=False,
help="show available fixtures, sorted by plugin appearance")
help="show available fixtures, sorted by plugin appearance "
"(fixtures with leading '_' are only shown with '-v')")
group.addoption(
'--fixtures-per-test',
action="store_true",
@@ -117,11 +118,7 @@ def pytest_generate_tests(metafunc):
if hasattr(metafunc.function, attr):
msg = "{0} has '{1}', spelling should be 'parametrize'"
raise MarkerError(msg.format(metafunc.function.__name__, attr))
try:
markers = metafunc.function.parametrize
except AttributeError:
return
for marker in markers:
for marker in metafunc.definition.iter_markers(name='parametrize'):
metafunc.parametrize(*marker.args, **marker.kwargs)
@@ -212,11 +209,20 @@ class PyobjContext(object):
class PyobjMixin(PyobjContext):
_ALLOW_MARKERS = True
def __init__(self, *k, **kw):
super(PyobjMixin, self).__init__(*k, **kw)
def obj():
def fget(self):
obj = getattr(self, '_obj', None)
if obj is None:
self._obj = obj = self._getobj()
# XXX evil hack
# used to avoid Instance collector marker duplication
if self._ALLOW_MARKERS:
self.own_markers.extend(get_unpacked_marks(self.obj))
return obj
def fset(self, value):
@@ -363,9 +369,15 @@ class PyCollector(PyobjMixin, nodes.Collector):
cls = clscol and clscol.obj or None
transfer_markers(funcobj, cls, module)
fm = self.session._fixturemanager
fixtureinfo = fm.getfixtureinfo(self, funcobj, cls)
metafunc = Metafunc(funcobj, fixtureinfo, self.config,
cls=cls, module=module)
definition = FunctionDefinition(
name=name,
parent=self,
callobj=funcobj,
)
fixtureinfo = fm.getfixtureinfo(definition, funcobj, cls)
metafunc = Metafunc(definition, fixtureinfo, self.config, cls=cls, module=module)
methods = []
if hasattr(module, "pytest_generate_tests"):
methods.append(module.pytest_generate_tests)
@@ -524,6 +536,11 @@ class Class(PyCollector):
class Instance(PyCollector):
_ALLOW_MARKERS = False # hack, destroy later
# instances share the object with their parents in a way
# that duplicates markers instances if not taken out
# can be removed at node strucutre reorganization time
def _getobj(self):
return self.parent.obj()
@@ -723,15 +740,17 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
test function is defined.
"""
def __init__(self, function, fixtureinfo, config, cls=None, module=None):
def __init__(self, definition, fixtureinfo, config, cls=None, module=None):
#: access to the :class:`_pytest.config.Config` object for the test session
assert isinstance(definition, FunctionDefinition) or type(definition).__name__ == "DefinitionMock"
self.definition = definition
self.config = config
#: the module object where the test function is defined in.
self.module = module
#: underlying python test function
self.function = function
self.function = definition.obj
#: set of fixture names required by the test function
self.fixturenames = fixtureinfo.names_closure
@@ -789,6 +808,7 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
argnames, parameters = ParameterSet._for_parametrize(
argnames, argvalues, self.function, self.config)
del argvalues
default_arg_names = set(get_default_arg_names(self.function))
if scope is None:
scope = _find_parametrized_scope(argnames, self._arg2fixturedefs, indirect)
@@ -797,13 +817,16 @@ class Metafunc(fixtures.FuncargnamesCompatAttr):
valtypes = {}
for arg in argnames:
if arg not in self.fixturenames:
if isinstance(indirect, (tuple, list)):
name = 'fixture' if arg in indirect else 'argument'
if arg in default_arg_names:
raise ValueError("%r already takes an argument %r with a default value" % (self.function, arg))
else:
name = 'fixture' if indirect else 'argument'
raise ValueError(
"%r uses no %s %r" % (
self.function, name, arg))
if isinstance(indirect, (tuple, list)):
name = 'fixture' if arg in indirect else 'argument'
else:
name = 'fixture' if indirect else 'argument'
raise ValueError(
"%r uses no %s %r" % (
self.function, name, arg))
if indirect is True:
valtypes = dict.fromkeys(argnames, "params")
@@ -1103,6 +1126,8 @@ class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr):
Python test function.
"""
_genid = None
# disable since functions handle it themselfes
_ALLOW_MARKERS = False
def __init__(self, name, parent, args=None, config=None,
callspec=None, callobj=NOTSET, keywords=None, session=None,
@@ -1114,6 +1139,7 @@ class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr):
self.obj = callobj
self.keywords.update(self.obj.__dict__)
self.own_markers.extend(get_unpacked_marks(self.obj))
if callspec:
self.callspec = callspec
# this is total hostile and a mess
@@ -1123,6 +1149,7 @@ class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr):
# feel free to cry, this was broken for years before
# and keywords cant fix it per design
self.keywords[mark.name] = mark
self.own_markers.extend(callspec.marks)
if keywords:
self.keywords.update(keywords)
@@ -1181,3 +1208,15 @@ class Function(FunctionMixin, nodes.Item, fixtures.FuncargnamesCompatAttr):
def setup(self):
super(Function, self).setup()
fixtures.fillfixtures(self)
class FunctionDefinition(Function):
"""
internal hack until we get actual definition nodes instead of the
crappy metafunc hack
"""
def runtest(self):
raise RuntimeError("function definitions are not supposed to be used")
setup = runtest

View File

@@ -2,6 +2,7 @@ import math
import sys
import py
from six import binary_type, text_type
from six.moves import zip, filterfalse
from more_itertools.more import always_iterable
@@ -425,7 +426,7 @@ def approx(expected, rel=None, abs=None, nan_ok=False):
__ https://docs.python.org/3/reference/datamodel.html#object.__ge__
"""
from collections import Mapping, Sequence
from _pytest.compat import Mapping, Sequence
from _pytest.compat import STRING_TYPES as String
from decimal import Decimal
@@ -584,7 +585,8 @@ def raises(expected_exception, *args, **kwargs):
"""
__tracebackhide__ = True
for exc in filterfalse(isclass, always_iterable(expected_exception)):
base_type = (type, text_type, binary_type)
for exc in filterfalse(isclass, always_iterable(expected_exception, base_type)):
msg = ("exceptions must be old-style classes or"
" derived from BaseException, not %s")
raise TypeError(msg % type(exc))
@@ -597,6 +599,10 @@ def raises(expected_exception, *args, **kwargs):
message = kwargs.pop("message")
if "match" in kwargs:
match_expr = kwargs.pop("match")
if kwargs:
msg = 'Unexpected keyword arguments passed to pytest.raises: '
msg += ', '.join(kwargs.keys())
raise TypeError(msg)
return RaisesContext(expected_exception, message, match_expr)
elif isinstance(args[0], str):
code, = args

View File

@@ -105,6 +105,7 @@ def pytest_runtest_setup(item):
def pytest_runtest_call(item):
_update_current_test_var(item, 'call')
sys.last_type, sys.last_value, sys.last_traceback = (None, None, None)
try:
item.runtest()
except Exception:
@@ -114,7 +115,7 @@ def pytest_runtest_call(item):
sys.last_type = type
sys.last_value = value
sys.last_traceback = tb
del tb # Get rid of it in this namespace
del type, value, tb # Get rid of these in this frame
raise
@@ -175,7 +176,8 @@ def check_interactive_exception(call, report):
def call_runtest_hook(item, when, **kwds):
hookname = "pytest_runtest_" + when
ihook = getattr(item.ihook, hookname)
return CallInfo(lambda: ihook(item=item, **kwds), when=when)
return CallInfo(lambda: ihook(item=item, **kwds), when=when,
treat_keyboard_interrupt_as_exception=item.config.getvalue("usepdb"))
class CallInfo(object):
@@ -183,7 +185,7 @@ class CallInfo(object):
#: None or ExceptionInfo object.
excinfo = None
def __init__(self, func, when):
def __init__(self, func, when, treat_keyboard_interrupt_as_exception=False):
#: context of invocation: one of "setup", "call",
#: "teardown", "memocollect"
self.when = when
@@ -191,8 +193,11 @@ class CallInfo(object):
try:
self.result = func()
except KeyboardInterrupt:
self.stop = time()
raise
if treat_keyboard_interrupt_as_exception:
self.excinfo = ExceptionInfo()
else:
self.stop = time()
raise
except: # noqa
self.excinfo = ExceptionInfo()
self.stop = time()

View File

@@ -2,7 +2,6 @@
from __future__ import absolute_import, division, print_function
from _pytest.config import hookimpl
from _pytest.mark import MarkInfo, MarkDecorator
from _pytest.mark.evaluate import MarkEvaluator
from _pytest.outcomes import fail, skip, xfail
@@ -60,15 +59,12 @@ def pytest_configure(config):
def pytest_runtest_setup(item):
# Check if skip or skipif are specified as pytest marks
item._skipped_by_mark = False
skipif_info = item.keywords.get('skipif')
if isinstance(skipif_info, (MarkInfo, MarkDecorator)):
eval_skipif = MarkEvaluator(item, 'skipif')
if eval_skipif.istrue():
item._skipped_by_mark = True
skip(eval_skipif.getexplanation())
eval_skipif = MarkEvaluator(item, 'skipif')
if eval_skipif.istrue():
item._skipped_by_mark = True
skip(eval_skipif.getexplanation())
skip_info = item.keywords.get('skip')
if isinstance(skip_info, (MarkInfo, MarkDecorator)):
for skip_info in item.iter_markers(name='skip'):
item._skipped_by_mark = True
if 'reason' in skip_info.kwargs:
skip(skip_info.kwargs['reason'])

View File

@@ -12,6 +12,7 @@ import time
import pluggy
import py
import six
from more_itertools import collapse
import pytest
from _pytest import nodes
@@ -442,7 +443,7 @@ class TerminalReporter(object):
def _write_report_lines_from_hooks(self, lines):
lines.reverse()
for line in flatten(lines):
for line in collapse(lines):
self.write_line(line)
def pytest_report_header(self, config):
@@ -700,15 +701,6 @@ def repr_pythonversion(v=None):
return str(v)
def flatten(values):
for x in values:
if isinstance(x, (list, tuple)):
for y in flatten(x):
yield y
else:
yield x
def build_summary_stats_line(stats):
keys = ("failed passed skipped deselected "
"xfailed xpassed warnings error").split()

View File

@@ -60,8 +60,7 @@ def catch_warnings_for_item(item):
for arg in inifilters:
_setoption(warnings, arg)
mark = item.get_marker('filterwarnings')
if mark:
for mark in item.iter_markers(name='filterwarnings'):
for arg in mark.args:
warnings._setoption(arg)

View File

@@ -1 +0,0 @@
New ``--show-capture`` command-line option that allows to specify how to display captured output when tests fail: ``no``, ``stdout``, ``stderr``, ``log`` or ``all`` (the default).

View File

@@ -1 +0,0 @@
New ``--rootdir`` command-line option to override the rules for discovering the root directory. See `customize <https://docs.pytest.org/en/latest/customize.html>`_ in the documentation for details.

View File

@@ -1 +0,0 @@
Added a `reference <https://docs.pytest.org/en/latest/reference.html>`_ page to the docs.

View File

@@ -1 +0,0 @@
Suppress ``IOError`` when closing the temporary file used for capturing streams in Python 2.7.

View File

@@ -1 +0,0 @@
Fixtures are now instantiated based on their scopes, with higher-scoped fixtures (such as ``session``) being instantiated first than lower-scoped fixtures (such as ``function``). The relative order of fixtures of the same scope is kept unchanged, based in their declaration order and their dependencies.

View File

@@ -1,2 +0,0 @@
``record_xml_property`` renamed to ``record_property`` and is now compatible with xdist, markers and any reporter.
``record_xml_property`` name is now deprecated.

View File

@@ -1 +0,0 @@
``record_xml_property`` fixture is now deprecated in favor of the more generic ``record_property``.

View File

@@ -1 +0,0 @@
New ``--nf``, ``--new-first`` options: run new tests first followed by the rest of the tests, in both cases tests are also sorted by the file modified time, with more recent files coming first.

View File

@@ -1 +0,0 @@
Defining ``pytest_plugins`` is now deprecated in non-top-level conftest.py files, because they "leak" to the entire directory tree.

View File

@@ -1 +0,0 @@
New ``--last-failed-no-failures`` command-line option that allows to specify the behavior of the cache plugin's ```--last-failed`` feature when no tests failed in the last run (or no cache was found): ``none`` or ``all`` (the default).

View File

@@ -1 +0,0 @@
New ``--doctest-continue-on-failure`` command-line option to enable doctests to show multiple failures for each snippet, instead of stopping at the first failure.

View File

@@ -1 +0,0 @@
Captured log messages are added to the ``<system-out>`` tag in the generated junit xml file if the ``junit_logging`` ini option is set to ``system-out``. If the value of this ini option is ``system-err`, the logs are written to ``<system-err>``. The default value for ``junit_logging`` is ``no``, meaning captured logs are not written to the output file.

View File

@@ -1 +0,0 @@
Allow the logging plugin to handle ``pytest_runtest_logstart`` and ``pytest_runtest_logfinish`` hooks when live logs are enabled.

View File

@@ -1 +0,0 @@
Passing `--log-cli-level` in the command-line now automatically activates live logging.

View File

@@ -1 +0,0 @@
Add command line option ``--deselect`` to allow deselection of individual tests at collection time.

View File

@@ -1 +0,0 @@
Captured logs are printed before entering pdb.

View File

@@ -1 +0,0 @@
Deselected item count is now shown before tests are run, e.g. ``collected X items / Y deselected``.

View File

@@ -1 +0,0 @@
Change minimum requirement of ``attrs`` to ``17.4.0``.

View File

@@ -1 +0,0 @@
The builtin module ``platform`` is now available for use in expressions in ``pytest.mark``.

View File

@@ -1 +0,0 @@
Renamed example directories so all tests pass when ran from the base directory.

View File

@@ -1 +0,0 @@
Remove usage of deprecated ``metafunc.addcall`` in our own tests.

View File

@@ -1 +0,0 @@
Internal ``mark.py`` module has been turned into a package.

View File

@@ -1 +0,0 @@
The *short test summary info* section now is displayed after tracebacks and warnings in the terminal.

View File

@@ -1 +0,0 @@
``pytest`` now depends on the `more_itertools <https://github.com/erikrose/more-itertools>`_ package.

View File

@@ -1 +0,0 @@
Added warning when ``[pytest]`` section is used in a ``.cfg`` file passed with ``-c``

View File

@@ -1 +0,0 @@
``nodeids`` can now be passed explicitly to ``FSCollector`` and ``Node`` constructors.

View File

@@ -1 +0,0 @@
Internal refactoring of ``FormattedExcinfo`` to use ``attrs`` facilities and remove old support code for legacy Python versions.

View File

@@ -1 +0,0 @@
New ``--verbosity`` flag to set verbosity level explicitly.

View File

@@ -1 +0,0 @@
Refactoring to unify how verbosity is handled internally.

View File

@@ -1,2 +0,0 @@
Fixed ``clear()`` method on ``caplog`` fixture which cleared ``records``,
but not the ``text`` property.

View File

@@ -1 +0,0 @@
Internal refactoring to better integrate with argparse.

View File

@@ -1 +0,0 @@
Fix a python example when calling a fixture in doc/en/usage.rst

View File

@@ -1 +0,0 @@
``pytest.approx`` now accepts comparing a numpy array with a scalar.

View File

@@ -1,3 +0,0 @@
During test collection, when stdin is not allowed to be read, the
``DontReadFromStdin`` object still allow itself to be iterable and
resolved to an iterator without crashing.

View File

@@ -1,6 +1,6 @@
<h3>Useful Links</h3>
<ul>
<li><a href="https://pypi.python.org/pypi/pytest">pytest @ PyPI</a></li>
<li><a href="https://pypi.org/project/pytest/">pytest @ PyPI</a></li>
<li><a href="https://github.com/pytest-dev/pytest/">pytest @ GitHub</a></li>
<li><a href="http://plugincompat.herokuapp.com/">3rd party plugins</a></li>
<li><a href="https://github.com/pytest-dev/pytest/issues">Issue Tracker</a></li>

View File

@@ -6,6 +6,8 @@ Release announcements
:maxdepth: 2
release-3.6.0
release-3.5.1
release-3.5.0
release-3.4.2
release-3.4.1

View File

@@ -18,7 +18,7 @@ comes with the following fixes and features:
rather use the post-2.0 parametrize features instead of yield, see:
http://pytest.org/latest/example/parametrize.html
- fix autouse-issue where autouse-fixtures would not be discovered
if defined in a a/conftest.py file and tests in a/tests/test_some.py
if defined in an a/conftest.py file and tests in a/tests/test_some.py
- fix issue226 - LIFO ordering for fixture teardowns
- fix issue224 - invocations with >256 char arguments now work
- fix issue91 - add/discuss package/directory level setups in example

View File

@@ -14,7 +14,7 @@ few interesting new plugins saw the light last month:
And several others like pytest-django saw maintenance releases.
For a more complete list, check out
https://pypi.python.org/pypi?%3Aaction=search&term=pytest&submit=search.
https://pypi.org/search/?q=pytest
For general information see:

View File

@@ -23,14 +23,14 @@ a full list of details. A few feature highlights:
called if the corresponding setup method succeeded.
- integrate tab-completion on command line options if you
have `argcomplete <http://pypi.python.org/pypi/argcomplete>`_
have `argcomplete <https://pypi.org/project/argcomplete/>`_
configured.
- allow boolean expression directly with skipif/xfail
if a "reason" is also specified.
- a new hook ``pytest_load_initial_conftests`` allows plugins like
`pytest-django <http://pypi.python.org/pypi/pytest-django>`_ to
`pytest-django <https://pypi.org/project/pytest-django/>`_ to
influence the environment before conftest files import ``django``.
- reporting: color the last line red or green depending if

View File

@@ -52,7 +52,7 @@ Changes 2.6.1
"::" node id specifications (copy pasted from "-v" output)
- fix issue544 by only removing "@NUM" at the end of "::" separated parts
and if the part has an ".py" extension
and if the part has a ".py" extension
- don't use py.std import helper, rather import things directly.
Thanks Bruno Oliveira.

View File

@@ -0,0 +1,30 @@
pytest-3.5.1
=======================================
pytest 3.5.1 has just been released to PyPI.
This is a bug-fix release, being a drop-in replacement. To upgrade::
pip install --upgrade pytest
The full changelog is available at http://doc.pytest.org/en/latest/changelog.html.
Thanks to all who contributed to this release, among them:
* Brian Maissy
* Bruno Oliveira
* Darren Burns
* David Chudzicki
* Floris Bruynooghe
* Holger Kohr
* Irmen de Jong
* Jeffrey Rackauckas
* Rachel Kogan
* Ronny Pfannschmidt
* Stefan Scherfke
* Tim Strazny
* Семён Марьясин
Happy testing,
The pytest Development Team

View File

@@ -0,0 +1,41 @@
pytest-3.6.0
=======================================
The pytest team is proud to announce the 3.6.0 release!
pytest is a mature Python testing tool with more than a 1600 tests
against itself, passing on many different interpreters and platforms.
This release contains a number of bugs fixes and improvements, so users are encouraged
to take a look at the CHANGELOG:
http://doc.pytest.org/en/latest/changelog.html
For complete documentation, please visit:
http://docs.pytest.org
As usual, you can upgrade from pypi via:
pip install -U pytest
Thanks to all who contributed to this release, among them:
* Anthony Shaw
* ApaDoctor
* Brian Maissy
* Bruno Oliveira
* Jon Dufresne
* Katerina Koukiou
* Miro Hrončok
* Rachel Kogan
* Ronny Pfannschmidt
* Tim Hughes
* Tyler Goodlet
* Ville Skyttä
* aviral1701
* feuillemorte
Happy testing,
The Pytest Development Team

View File

@@ -12,7 +12,7 @@ For information on plugin hooks and objects, see :ref:`plugins`.
For information on the ``pytest.mark`` mechanism, see :ref:`mark`.
For information about fixtures, see :ref:`fixtures`. To see a complete list of available fixtures, type::
For information about fixtures, see :ref:`fixtures`. To see a complete list of available fixtures (add ``-v`` to also see fixtures with leading ``_``), type ::
$ pytest -q --fixtures
cache
@@ -77,9 +77,9 @@ For information about fixtures, see :ref:`fixtures`. To see a complete list of a
Captured logs are available through the following methods::
* caplog.text() -> string containing formatted log output
* caplog.records() -> list of logging.LogRecord instances
* caplog.record_tuples() -> list of (logger_name, level, message) tuples
* caplog.text -> string containing formatted log output
* caplog.records -> list of logging.LogRecord instances
* caplog.record_tuples -> list of (logger_name, level, message) tuples
* caplog.clear() -> clear captured records and formatted log output string
monkeypatch
The returned ``monkeypatch`` fixture provides these

View File

@@ -234,7 +234,7 @@ Inspecting Cache content
You can always peek at the content of the cache using the
``--cache-show`` command line option::
$ py.test --cache-show
$ pytest --cache-show
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y
rootdir: $REGENDOC_TMPDIR, inifile:

View File

@@ -20,6 +20,7 @@
import os
import sys
import datetime
from _pytest import __version__ as version
@@ -57,7 +58,8 @@ master_doc = 'contents'
# General information about the project.
project = u'pytest'
copyright = u'2015, holger krekel and pytest-dev team'
year = datetime.datetime.utcnow().year
copyright = u'2015{} , holger krekel and pytest-dev team'.format(year)

View File

@@ -15,12 +15,12 @@ Full pytest documentation
existingtestsuite
assert
fixture
mark
monkeypatch
tmpdir
capture
warnings
doctest
mark
skipping
parametrize
cache

View File

@@ -2,7 +2,7 @@
Development Guide
=================
Some general guidelines regarding development in pytest for core maintainers and general contributors. Nothing here
Some general guidelines regarding development in pytest for maintainers and contributors. Nothing here
is set in stone and can't be changed, feel free to suggest improvements or changes in the workflow.
@@ -10,7 +10,7 @@ Code Style
----------
* `PEP-8 <https://www.python.org/dev/peps/pep-0008>`_
* `flake8 <https://pypi.python.org/pypi/flake8>`_ for quality checks
* `flake8 <https://pypi.org/project/flake8/>`_ for quality checks
* `invoke <http://www.pyinvoke.org/>`_ to automate development tasks
@@ -37,72 +37,19 @@ Any question, feature, bug or proposal is welcome as an issue. Users are encoura
GitHub issues should use labels to categorize them. Labels should be created sporadically, to fill a niche; we should
avoid creating labels just for the sake of creating them.
Here is a list of labels and a brief description mentioning their intent.
Each label should include a description in the GitHub's interface stating its purpose.
Temporary labels
~~~~~~~~~~~~~~~~
**Type**
To classify issues for a special event it is encouraged to create a temporary label. This helps those involved to find
the relevant issues to work on. Examples of that are sprints in Python events or global hacking events.
* ``type: backward compatibility``: issue that will cause problems with old pytest versions.
* ``type: bug``: problem that needs to be addressed.
* ``type: deprecation``: feature that will be deprecated in the future.
* ``type: docs``: documentation missing or needing clarification.
* ``type: enhancement``: new feature or API change, should be merged into ``features``.
* ``type: feature-branch``: new feature or API change, should be merged into ``features``.
* ``type: infrastructure``: improvement to development/releases/CI structure.
* ``type: performance``: performance or memory problem/improvement.
* ``type: proposal``: proposal for a new feature, often to gather opinions or design the API around the new feature.
* ``type: question``: question regarding usage, installation, internals or how to test something.
* ``type: refactoring``: internal improvements to the code.
* ``type: regression``: indicates a problem that was introduced in a release which was working previously.
* ``temporary: EP2017 sprint``: candidate issues or PRs tackled during the EuroPython 2017
**Status**
Issues created at those events should have other relevant labels added as well.
* ``status: critical``: grave problem or usability issue that affects lots of users.
* ``status: easy``: easy issue that is friendly to new contributors.
* ``status: help wanted``: core developers need help from experts on this topic.
* ``status: needs information``: reporter needs to provide more information; can be closed after 2 or more weeks of inactivity.
**Topic**
* ``topic: collection``
* ``topic: fixtures``
* ``topic: parametrize``
* ``topic: reporting``
* ``topic: selection``
* ``topic: tracebacks``
**Plugin (internal or external)**
* ``plugin: cache``
* ``plugin: capture``
* ``plugin: doctests``
* ``plugin: junitxml``
* ``plugin: monkeypatch``
* ``plugin: nose``
* ``plugin: pastebin``
* ``plugin: pytester``
* ``plugin: tmpdir``
* ``plugin: unittest``
* ``plugin: warnings``
* ``plugin: xdist``
**OS**
Issues specific to a single operating system. Do not use as a means to indicate where an issue originated from, only
for problems that happen **only** in that system.
* ``os: linux``
* ``os: mac``
* ``os: windows``
**Temporary**
Used to classify issues for limited time, to help find issues related in events for example.
They should be removed after they are no longer relevant.
* ``temporary: EP2017 sprint``:
* ``temporary: sprint-candidate``:
Those labels should be removed after they are no longer relevant.
.. include:: ../../HOWTORELEASE.rst

View File

@@ -330,11 +330,10 @@ specifies via named environments::
"env(name): mark test to run only on named environment")
def pytest_runtest_setup(item):
envmarker = item.get_marker("env")
if envmarker is not None:
envname = envmarker.args[0]
if envname != item.config.getoption("-E"):
pytest.skip("test requires env %r" % envname)
envnames = [mark.args[0] for mark in item.iter_markers(name='env')]
if envnames:
if item.config.getoption("-E") not in envnames:
pytest.skip("test requires env in %r" % envnames)
A test file using this local plugin::
@@ -403,11 +402,9 @@ Below is the config file that will be used in the next examples::
import sys
def pytest_runtest_setup(item):
marker = item.get_marker('my_marker')
if marker is not None:
for info in marker:
print('Marker info name={} args={} kwars={}'.format(info.name, info.args, info.kwargs))
sys.stdout.flush()
for marker in item.iter_markers(name='my_marker'):
print(marker)
sys.stdout.flush()
A custom marker can have its argument set, i.e. ``args`` and ``kwargs`` properties, defined by either invoking it as a callable or using ``pytest.mark.MARKER_NAME.with_args``. These two methods achieve the same effect most of the time.
@@ -426,7 +423,7 @@ However, if there is a callable as the single positional argument with no keywor
The output is as follows::
$ pytest -q -s
Marker info name=my_marker args=(<function hello_world at 0xdeadbeef>,) kwars={}
Mark(name='my_marker', args=(<function hello_world at 0xdeadbeef>,), kwargs={})
.
1 passed in 0.12 seconds
@@ -460,11 +457,9 @@ test function. From a conftest file we can read it like this::
import sys
def pytest_runtest_setup(item):
g = item.get_marker("glob")
if g is not None:
for info in g:
print ("glob args=%s kwargs=%s" %(info.args, info.kwargs))
sys.stdout.flush()
for mark in item.iter_markers(name='glob'):
print ("glob args=%s kwargs=%s" %(mark.args, mark.kwargs))
sys.stdout.flush()
Let's run this without capturing output and see what we get::
@@ -494,11 +489,10 @@ for your particular platform, you could use the following plugin::
ALL = set("darwin linux win32".split())
def pytest_runtest_setup(item):
if isinstance(item, item.Function):
plat = sys.platform
if not item.get_marker(plat):
if ALL.intersection(item.keywords):
pytest.skip("cannot run on platform %s" %(plat))
supported_platforms = ALL.intersection(mark.name for mark in item.iter_markers())
plat = sys.platform
if supported_platforms and plat not in supported_platforms:
pytest.skip("cannot run on platform %s" % (plat))
then tests will be skipped if they were specified for a different platform.
Let's do a little test file to show how this looks like::
@@ -532,7 +526,7 @@ then you will see two tests skipped and two executed tests as expected::
test_plat.py s.s. [100%]
========================= short test summary info ==========================
SKIP [2] $REGENDOC_TMPDIR/conftest.py:13: cannot run on platform linux
SKIP [2] $REGENDOC_TMPDIR/conftest.py:12: cannot run on platform linux
=================== 2 passed, 2 skipped in 0.12 seconds ====================

View File

@@ -10,7 +10,7 @@ A basic example for specifying tests in Yaml files
--------------------------------------------------------------
.. _`pytest-yamlwsgi`: http://bitbucket.org/aafshar/pytest-yamlwsgi/src/tip/pytest_yamlwsgi.py
.. _`PyYAML`: http://pypi.python.org/pypi/PyYAML/
.. _`PyYAML`: https://pypi.org/project/PyYAML/
Here is an example ``conftest.py`` (extracted from Ali Afshnars special purpose `pytest-yamlwsgi`_ plugin). This ``conftest.py`` will collect ``test*.yml`` files and will execute the yaml-formatted content as custom tests:

View File

@@ -160,7 +160,7 @@ together with the actual data, instead of listing them separately.
A quick port of "testscenarios"
------------------------------------
.. _`test scenarios`: http://pypi.python.org/pypi/testscenarios/
.. _`test scenarios`: https://pypi.org/project/testscenarios/
Here is a quick port to run tests configured with `test scenarios`_,
an add-on from Robert Collins for the standard unittest framework. We
@@ -469,7 +469,7 @@ If you run this with reporting for skips enabled::
=================== 1 passed, 1 skipped in 0.12 seconds ====================
You'll see that we don't have a ``opt2`` module and thus the second test run
You'll see that we don't have an ``opt2`` module and thus the second test run
of our ``test_func1`` was skipped. A few notes:
- the fixture functions in the ``conftest.py`` file are "session-scoped" because we

View File

@@ -54,7 +54,7 @@ Keeping duplicate paths specified from command line
Default behavior of ``pytest`` is to ignore duplicate paths specified from the command line.
Example::
py.test path_a path_a
pytest path_a path_a
...
collected 1 item
@@ -65,7 +65,7 @@ Just collect tests once.
To collect duplicate tests, use the ``--keep-duplicates`` option on the cli.
Example::
py.test --keep-duplicates path_a path_a
pytest --keep-duplicates path_a path_a
...
collected 2 items
@@ -75,7 +75,7 @@ As the collector just works on directories, if you specify twice a single test f
still collect it twice, no matter if the ``--keep-duplicates`` is not specified.
Example::
py.test test_a.py test_a.py
pytest test_a.py test_a.py
...
collected 2 items

View File

@@ -358,7 +358,7 @@ get on the terminal - we are working on that)::
> int(s)
E ValueError: invalid literal for int() with base 10: 'qwe'
<0-codegen $PYTHON_PREFIX/lib/python3.5/site-packages/_pytest/python_api.py:609>:1: ValueError
<0-codegen $PYTHON_PREFIX/lib/python3.5/site-packages/_pytest/python_api.py:615>:1: ValueError
______________________ TestRaises.test_raises_doesnt _______________________
self = <failure_demo.TestRaises object at 0xdeadbeef>

View File

@@ -102,13 +102,13 @@ the command line arguments before they get processed:
# content of conftest.py
import sys
def pytest_cmdline_preparse(args):
def pytest_load_initial_conftests(args):
if 'xdist' in sys.modules: # pytest-xdist plugin
import multiprocessing
num = max(multiprocessing.cpu_count() / 2, 1)
args[:] = ["-n", str(num)] + args
If you have the `xdist plugin <https://pypi.python.org/pypi/pytest-xdist>`_ installed
If you have the `xdist plugin <https://pypi.org/project/pytest-xdist/>`_ installed
you will now always perform test runs using a number
of subprocesses close to your CPU. Running in an empty
directory with the above conftest.py::
@@ -389,7 +389,7 @@ Now we can profile which test functions execute the slowest::
========================= slowest 3 test durations =========================
0.30s call test_some_are_slow.py::test_funcslow2
0.20s call test_some_are_slow.py::test_funcslow1
0.16s call test_some_are_slow.py::test_funcfast
0.11s call test_some_are_slow.py::test_funcfast
========================= 3 passed in 0.12 seconds =========================
incremental testing - test steps
@@ -778,7 +778,7 @@ which test got stuck, for example if pytest was run in quiet mode (``-q``) or yo
output. This is particularly a problem if the problem helps only sporadically, the famous "flaky" kind of tests.
``pytest`` sets a ``PYTEST_CURRENT_TEST`` environment variable when running tests, which can be inspected
by process monitoring utilities or libraries like `psutil <https://pypi.python.org/pypi/psutil>`_ to discover which
by process monitoring utilities or libraries like `psutil <https://pypi.org/project/psutil/>`_ to discover which
test got stuck if necessary:
.. code-block:: python

View File

@@ -30,14 +30,14 @@ and does not handle Deferreds returned from a test in pytest style.
If you are using trial's unittest.TestCase chances are that you can
just run your tests even if you return Deferreds. In addition,
there also is a dedicated `pytest-twisted
<http://pypi.python.org/pypi/pytest-twisted>`_ plugin which allows you to
<https://pypi.org/project/pytest-twisted/>`_ plugin which allows you to
return deferreds from pytest-style tests, allowing the use of
:ref:`fixtures` and other features.
how does pytest work with Django?
++++++++++++++++++++++++++++++++++++++++++++++
In 2012, some work is going into the `pytest-django plugin <http://pypi.python.org/pypi/pytest-django>`_. It substitutes the usage of Django's
In 2012, some work is going into the `pytest-django plugin <https://pypi.org/project/pytest-django/>`_. It substitutes the usage of Django's
``manage.py test`` and allows the use of all pytest features_ most of which
are not available from Django directly.

View File

@@ -111,11 +111,11 @@ with a list of available function arguments.
.. note::
You can always issue::
You can always issue ::
pytest --fixtures test_simplefactory.py
to see available fixtures.
to see available fixtures (fixtures with leading ``_`` are only shown if you add the ``-v`` option).
Fixtures: a prime example of dependency injection
---------------------------------------------------
@@ -141,7 +141,7 @@ automatically gets discovered by pytest. The discovery of
fixture functions starts at test classes, then test modules, then
``conftest.py`` files and finally builtin and third party plugins.
You can also use the ``conftest.py`` file to implement
You can also use the ``conftest.py`` file to implement
:ref:`local per-directory plugins <conftest.py plugins>`.
Sharing test data
@@ -154,7 +154,7 @@ This makes use of the automatic caching mechanisms of pytest.
Another good approach is by adding the data files in the ``tests`` folder.
There are also community plugins available to help managing this aspect of
testing, e.g. `pytest-datadir <https://github.com/gabrielcnr/pytest-datadir>`__
and `pytest-datafiles <https://pypi.python.org/pypi/pytest-datafiles>`__.
and `pytest-datafiles <https://pypi.org/project/pytest-datafiles/>`__.
.. _smtpshared:
@@ -294,7 +294,7 @@ The fixtures requested by ``test_foo`` will be instantiated in the following ord
1. ``s1``: is the highest-scoped fixture (``session``).
2. ``m1``: is the second highest-scoped fixture (``module``).
3. ``tempdir``: is a ``function``-scoped fixture, required by ``f1``: it needs to be instantiated at this point
3. ``tmpdir``: is a ``function``-scoped fixture, required by ``f1``: it needs to be instantiated at this point
because it is a dependency of ``f1``.
4. ``f1``: is the first ``function``-scoped fixture in ``test_foo`` parameter list.
5. ``f2``: is the last ``function``-scoped fixture in ``test_foo`` parameter list.
@@ -623,6 +623,40 @@ Running the above tests results in the following test IDs being used::
======================= no tests ran in 0.12 seconds =======================
.. _`fixture-parametrize-marks`:
Using marks with parametrized fixtures
--------------------------------------
:func:`pytest.param` can be used to apply marks in values sets of parametrized fixtures in the same way
that they can be used with :ref:`@pytest.mark.parametrize <@pytest.mark.parametrize>`.
Example::
# content of test_fixture_marks.py
import pytest
@pytest.fixture(params=[0, 1, pytest.param(2, marks=pytest.mark.skip)])
def data_set(request):
return request.param
def test_data(data_set):
pass
Running this test will *skip* the invocation of ``data_set`` with value ``2``::
$ pytest test_fixture_marks.py -v
=========================== test session starts ============================
platform linux -- Python 3.x.y, pytest-3.x.y, py-1.x.y, pluggy-0.x.y -- $PYTHON_PREFIX/bin/python3.5
cachedir: .pytest_cache
rootdir: $REGENDOC_TMPDIR, inifile:
collecting ... collected 3 items
test_fixture_marks.py::test_data[0] PASSED [ 33%]
test_fixture_marks.py::test_data[1] PASSED [ 66%]
test_fixture_marks.py::test_data[2] SKIPPED [100%]
=================== 2 passed, 1 skipped in 0.12 seconds ====================
.. _`interdependent fixtures`:
Modularity: using fixtures from a fixture function

View File

@@ -5,10 +5,10 @@ Installation and Getting Started
**Platforms**: Unix/Posix and Windows
**PyPI package name**: `pytest <http://pypi.python.org/pypi/pytest>`_
**PyPI package name**: `pytest <https://pypi.org/project/pytest/>`_
**Dependencies**: `py <http://pypi.python.org/pypi/py>`_,
`colorama (Windows) <http://pypi.python.org/pypi/colorama>`_,
**Dependencies**: `py <https://pypi.org/project/py/>`_,
`colorama (Windows) <https://pypi.org/project/colorama/>`_,
**Documentation as PDF**: `download latest <https://media.readthedocs.org/pdf/pytest/latest/pytest.pdf>`_
@@ -166,6 +166,8 @@ Find out what kind of builtin :ref:`pytest fixtures <fixtures>` exist with the c
pytest --fixtures # shows builtin and custom fixtures
Note that this command omits fixtures with leading ``_`` unless the ``-v`` option is added.
Continue reading
-------------------------------------

View File

@@ -145,7 +145,7 @@ Note that this layout also works in conjunction with the ``src`` layout mentione
.. note::
If ``pytest`` finds a "a/b/test_module.py" test file while
If ``pytest`` finds an "a/b/test_module.py" test file while
recursing into the filesystem it determines the import name
as follows:
@@ -168,9 +168,9 @@ Note that this layout also works in conjunction with the ``src`` layout mentione
to avoid surprises such as a test module getting imported twice.
.. _`virtualenv`: http://pypi.python.org/pypi/virtualenv
.. _`virtualenv`: https://pypi.org/project/virtualenv/
.. _`buildout`: http://www.buildout.org/
.. _pip: http://pypi.python.org/pypi/pip
.. _pip: https://pypi.org/project/pip/
.. _`use tox`:
@@ -205,7 +205,7 @@ Integrating with setuptools / ``python setup.py test`` / ``pytest-runner``
--------------------------------------------------------------------------
You can integrate test runs into your setuptools based project
with the `pytest-runner <https://pypi.python.org/pypi/pytest-runner>`_ plugin.
with the `pytest-runner <https://pypi.org/project/pytest-runner/>`_ plugin.
Add this to ``setup.py`` file:

View File

@@ -7,14 +7,14 @@
.. _`reStructured Text`: http://docutils.sourceforge.net
.. _`Python debugger`: http://docs.python.org/lib/module-pdb.html
.. _nose: https://nose.readthedocs.io/en/latest/
.. _pytest: http://pypi.python.org/pypi/pytest
.. _pytest: https://pypi.org/project/pytest/
.. _mercurial: http://mercurial.selenic.com/wiki/
.. _`setuptools`: http://pypi.python.org/pypi/setuptools
.. _`setuptools`: https://pypi.org/project/setuptools/
.. _`easy_install`:
.. _`distribute docs`:
.. _`distribute`: http://pypi.python.org/pypi/distribute
.. _`pip`: http://pypi.python.org/pypi/pip
.. _`virtualenv`: http://pypi.python.org/pypi/virtualenv
.. _`distribute`: https://pypi.org/project/distribute/
.. _`pip`: https://pypi.org/project/pip/
.. _`virtualenv`: https://pypi.org/project/virtualenv/
.. _hudson: http://hudson-ci.org/
.. _jenkins: http://jenkins-ci.org/
.. _tox: http://testrun.org/tox

View File

@@ -123,7 +123,7 @@ You can call ``caplog.clear()`` to reset the captured log records in a test::
assert ['Foo'] == [rec.message for rec in caplog.records]
The ``caplop.records`` attribute contains records from the current stage only, so
The ``caplog.records`` attribute contains records from the current stage only, so
inside the ``setup`` phase it contains only setup logs, same with the ``call`` and
``teardown`` phases.

View File

@@ -26,3 +26,114 @@ which also serve as documentation.
:ref:`fixtures <fixtures>`.
.. currentmodule:: _pytest.mark.structures
.. autoclass:: Mark
:members:
:noindex:
.. `marker-iteration`
Marker revamp and iteration
---------------------------
.. versionadded:: 3.6
pytest's marker implementation traditionally worked by simply updating the ``__dict__`` attribute of functions to add markers, in a cumulative manner. As a result of the this, markers would unintendely be passed along class hierarchies in surprising ways plus the API for retriving them was inconsistent, as markers from parameterization would be stored differently than markers applied using the ``@pytest.mark`` decorator and markers added via ``node.add_marker``.
This state of things made it technically next to impossible to use data from markers correctly without having a deep understanding of the internals, leading to subtle and hard to understand bugs in more advanced usages.
Depending on how a marker got declared/changed one would get either a ``MarkerInfo`` which might contain markers from sibling classes,
``MarkDecorators`` when marks came from parameterization or from a ``node.add_marker`` call, discarding prior marks. Also ``MarkerInfo`` acts like a single mark, when it in fact repressents a merged view on multiple marks with the same name.
On top of that markers where not accessible the same way for modules, classes, and functions/methods,
in fact, markers where only accessible in functions, even if they where declared on classes/modules.
A new API to access markers has been introduced in pytest 3.6 in order to solve the problems with the initial design, providing :func:`_pytest.nodes.Node.iter_markers` method to iterate over markers in a consistent manner and reworking the internals, which solved great deal of problems with the initial design.
.. _update marker code:
Updating code
~~~~~~~~~~~~~
The old ``Node.get_marker(name)`` function is considered deprecated because it returns an internal ``MarkerInfo`` object
which contains the merged name, ``*args`` and ``**kwargs**`` of all the markers which apply to that node.
In general there are two scenarios on how markers should be handled:
1. Marks overwrite each other. Order matters but you only want to think of your mark as a single item. E.g.
``log_level('info')`` at a module level can be overwritten by ``log_level('debug')`` for a specific test.
In this case replace use ``Node.get_closest_marker(name)``:
.. code-block:: python
# replace this:
marker = item.get_marker('log_level')
if marker:
level = marker.args[0]
# by this:
marker = item.get_closest_marker('log_level')
if marker:
level = marker.args[0]
2. Marks compose additive. E.g. ``skipif(condition)`` marks means you just want to evaluate all of them,
order doesn't even matter. You probably want to think of your marks as a set here.
In this case iterate over each mark and handle their ``*args`` and ``**kwargs`` individually.
.. code-block:: python
# replace this
skipif = item.get_marker('skipif')
if skipif:
for condition in skipif.args:
# eval condition
# by this:
for skipif in item.iter_markers('skipif'):
condition = skipif.args[0]
# eval condition
If you are unsure or have any questions, please consider opening
`an issue <https://github.com/pytest-dev/pytest/issues>`_.
Related issues
~~~~~~~~~~~~~~
Here is a non-exhaustive list of issues fixed by the new implementation:
* Marks don't pick up nested classes (`#199 <https://github.com/pytest-dev/pytest/issues/199>`_).
* markers stains on all related classes (`#568 <https://github.com/pytest-dev/pytest/issues/568>`_).
* combining marks - args and kwargs calculation (`#2897 <https://github.com/pytest-dev/pytest/issues/2897>`_).
* ``request.node.get_marker('name')`` returns ``None`` for markers applied in classes (`#902 <https://github.com/pytest-dev/pytest/issues/902>`_).
* marks applied in parametrize are stored as markdecorator (`#2400 <https://github.com/pytest-dev/pytest/issues/2400>`_).
* fix marker interaction in a backward incompatible way (`#1670 <https://github.com/pytest-dev/pytest/issues/1670>`_).
* Refactor marks to get rid of the current "marks transfer" mechanism (`#2363 <https://github.com/pytest-dev/pytest/issues/2363>`_).
* Introduce FunctionDefinition node, use it in generate_tests (`#2522 <https://github.com/pytest-dev/pytest/issues/2522>`_).
* remove named marker attributes and collect markers in items (`#891 <https://github.com/pytest-dev/pytest/issues/891>`_).
* skipif mark from parametrize hides module level skipif mark (`#1540 <https://github.com/pytest-dev/pytest/issues/1540>`_).
* skipif + parametrize not skipping tests (`#1296 <https://github.com/pytest-dev/pytest/issues/1296>`_).
* marker transfer incompatible with inheritance (`#535 <https://github.com/pytest-dev/pytest/issues/535>`_).
More details can be found in the `original PR <https://github.com/pytest-dev/pytest/pull/3317>`_.
.. note::
in a future major relase of pytest we will introduce class based markers,
at which points markers will no longer be limited to instances of :py:class:`Mark`

View File

@@ -61,6 +61,22 @@ so that any attempts within tests to create http requests will fail.
``compile``, etc., because it might break pytest's internals. If that's
unavoidable, passing ``--tb=native``, ``--assert=plain`` and ``--capture=no`` might
help although there's no guarantee.
.. note::
Mind that patching ``stdlib`` functions and some third-party libraries used by pytest
might break pytest itself, therefore in those cases it is recommended to use
:meth:`MonkeyPatch.context` to limit the patching to the block you want tested:
.. code-block:: python
import functools
def test_partial(monkeypatch):
with monkeypatch.context() as m:
m.setattr(functools, "partial", 3)
assert functools.partial == 3
See issue `#3290 <https://github.com/pytest-dev/pytest/issues/3290>`_ for details.
.. currentmodule:: _pytest.monkeypatch

View File

@@ -20,39 +20,39 @@ Here is a little annotated list for some popular plugins:
.. _`django`: https://www.djangoproject.com/
* `pytest-django <http://pypi.python.org/pypi/pytest-django>`_: write tests
* `pytest-django <https://pypi.org/project/pytest-django/>`_: write tests
for `django`_ apps, using pytest integration.
* `pytest-twisted <http://pypi.python.org/pypi/pytest-twisted>`_: write tests
* `pytest-twisted <https://pypi.org/project/pytest-twisted/>`_: write tests
for `twisted <http://twistedmatrix.com>`_ apps, starting a reactor and
processing deferreds from test functions.
* `pytest-cov <http://pypi.python.org/pypi/pytest-cov>`_:
* `pytest-cov <https://pypi.org/project/pytest-cov/>`_:
coverage reporting, compatible with distributed testing
* `pytest-xdist <http://pypi.python.org/pypi/pytest-xdist>`_:
* `pytest-xdist <https://pypi.org/project/pytest-xdist/>`_:
to distribute tests to CPUs and remote hosts, to run in boxed
mode which allows to survive segmentation faults, to run in
looponfailing mode, automatically re-running failing tests
on file changes.
* `pytest-instafail <http://pypi.python.org/pypi/pytest-instafail>`_:
* `pytest-instafail <https://pypi.org/project/pytest-instafail/>`_:
to report failures while the test run is happening.
* `pytest-bdd <http://pypi.python.org/pypi/pytest-bdd>`_ and
`pytest-konira <http://pypi.python.org/pypi/pytest-konira>`_
* `pytest-bdd <https://pypi.org/project/pytest-bdd/>`_ and
`pytest-konira <https://pypi.org/project/pytest-konira/>`_
to write tests using behaviour-driven testing.
* `pytest-timeout <http://pypi.python.org/pypi/pytest-timeout>`_:
* `pytest-timeout <https://pypi.org/project/pytest-timeout/>`_:
to timeout tests based on function marks or global definitions.
* `pytest-pep8 <http://pypi.python.org/pypi/pytest-pep8>`_:
* `pytest-pep8 <https://pypi.org/project/pytest-pep8/>`_:
a ``--pep8`` option to enable PEP8 compliance checking.
* `pytest-flakes <https://pypi.python.org/pypi/pytest-flakes>`_:
* `pytest-flakes <https://pypi.org/project/pytest-flakes/>`_:
check source code with pyflakes.
* `oejskit <http://pypi.python.org/pypi/oejskit>`_:
* `oejskit <https://pypi.org/project/oejskit/>`_:
a plugin to run javascript unittests in live browsers.
To see a complete list of all plugins with their latest testing
@@ -61,7 +61,7 @@ status against different pytest and Python versions, please visit
You may also discover more plugins through a `pytest- pypi.python.org search`_.
.. _`pytest- pypi.python.org search`: http://pypi.python.org/pypi?%3Aaction=search&term=pytest-&submit=search
.. _`pytest- pypi.python.org search`: https://pypi.org/search/?q=pytest-
.. _`available installable plugins`:

View File

@@ -32,40 +32,40 @@ Here are some examples of projects using ``pytest`` (please send notes via :ref:
* `PyPM <http://code.activestate.com/pypm/>`_ ActiveState's package manager
* `Fom <http://packages.python.org/Fom/>`_ a fluid object mapper for FluidDB
* `applib <https://github.com/ActiveState/applib>`_ cross-platform utilities
* `six <http://pypi.python.org/pypi/six/>`_ Python 2 and 3 compatibility utilities
* `six <https://pypi.org/project/six/>`_ Python 2 and 3 compatibility utilities
* `pediapress <http://code.pediapress.com/wiki/wiki>`_ MediaWiki articles
* `mwlib <http://pypi.python.org/pypi/mwlib>`_ mediawiki parser and utility library
* `mwlib <https://pypi.org/project/mwlib/>`_ mediawiki parser and utility library
* `The Translate Toolkit <http://translate.sourceforge.net/wiki/toolkit/index>`_ for localization and conversion
* `execnet <http://codespeak.net/execnet>`_ rapid multi-Python deployment
* `pylib <https://py.readthedocs.io>`_ cross-platform path, IO, dynamic code library
* `Pacha <http://pacha.cafepais.com/>`_ configuration management in five minutes
* `bbfreeze <http://pypi.python.org/pypi/bbfreeze>`_ create standalone executables from Python scripts
* `bbfreeze <https://pypi.org/project/bbfreeze/>`_ create standalone executables from Python scripts
* `pdb++ <http://bitbucket.org/antocuni/pdb>`_ a fancier version of PDB
* `py-s3fuse <http://code.google.com/p/py-s3fuse/>`_ Amazon S3 FUSE based filesystem
* `waskr <http://code.google.com/p/waskr/>`_ WSGI Stats Middleware
* `guachi <http://code.google.com/p/guachi/>`_ global persistent configs for Python modules
* `Circuits <http://pypi.python.org/pypi/circuits>`_ lightweight Event Driven Framework
* `Circuits <https://pypi.org/project/circuits/>`_ lightweight Event Driven Framework
* `pygtk-helpers <http://bitbucket.org/aafshar/pygtkhelpers-main/>`_ easy interaction with PyGTK
* `QuantumCore <http://quantumcore.org/>`_ statusmessage and repoze openid plugin
* `pydataportability <http://pydataportability.net/>`_ libraries for managing the open web
* `XIST <http://www.livinglogic.de/Python/xist/>`_ extensible HTML/XML generator
* `tiddlyweb <http://pypi.python.org/pypi/tiddlyweb>`_ optionally headless, extensible RESTful datastore
* `tiddlyweb <https://pypi.org/project/tiddlyweb/>`_ optionally headless, extensible RESTful datastore
* `fancycompleter <http://bitbucket.org/antocuni/fancycompleter/src>`_ for colorful tab-completion
* `Paludis <http://paludis.exherbo.org/>`_ tools for Gentoo Paludis package manager
* `Gerald <http://halfcooked.com/code/gerald/>`_ schema comparison tool
* `abjad <http://code.google.com/p/abjad/>`_ Python API for Formalized Score control
* `bu <http://packages.python.org/bu/>`_ a microscopic build system
* `katcp <https://bitbucket.org/hodgestar/katcp>`_ Telescope communication protocol over Twisted
* `kss plugin timer <http://pypi.python.org/pypi/kss.plugin.timer>`_
* `kss plugin timer <https://pypi.org/project/kss.plugin.timer/>`_
* `pyudev <https://pyudev.readthedocs.io/en/latest/tests/plugins.html>`_ a pure Python binding to the Linux library libudev
* `pytest-localserver <https://bitbucket.org/pytest-dev/pytest-localserver/>`_ a plugin for pytest that provides an httpserver and smtpserver
* `pytest-monkeyplus <http://pypi.python.org/pypi/pytest-monkeyplus/>`_ a plugin that extends monkeypatch
* `pytest-monkeyplus <https://pypi.org/project/pytest-monkeyplus/>`_ a plugin that extends monkeypatch
These projects help integrate ``pytest`` into other Python frameworks:
* `pytest-django <http://pypi.python.org/pypi/pytest-django/>`_ for Django
* `pytest-django <https://pypi.org/project/pytest-django/>`_ for Django
* `zope.pytest <http://packages.python.org/zope.pytest/>`_ for Zope and Grok
* `pytest_gae <http://pypi.python.org/pypi/pytest_gae/0.2.1>`_ for Google App Engine
* `pytest_gae <https://pypi.org/project/pytest_gae/0.2.1/>`_ for Google App Engine
* There is `some work <https://github.com/Kotti/Kotti/blob/master/kotti/testing.py>`_ underway for Kotti, a CMS built in Pyramid/Pylons

View File

@@ -118,7 +118,7 @@ all parameters marked as a fixture.
.. note::
The `pytest-lazy-fixture <https://pypi.python.org/pypi/pytest-lazy-fixture>`_ plugin implements a very
The `pytest-lazy-fixture <https://pypi.org/project/pytest-lazy-fixture/>`_ plugin implements a very
similar solution to the proposal below, make sure to check it out.
.. code-block:: python

View File

@@ -94,6 +94,33 @@ Marks can be used apply meta data to *test functions* (but not fixtures), which
fixtures or plugins.
.. _`pytest.mark.filterwarnings ref`:
pytest.mark.filterwarnings
~~~~~~~~~~~~~~~~~~~~~~~~~~
**Tutorial**: :ref:`filterwarnings`.
Add warning filters to marked test items.
.. py:function:: pytest.mark.filterwarnings(filter)
:keyword str filter:
A *warning specification string*, which is composed of contents of the tuple ``(action, message, category, module, lineno)``
as specified in `The Warnings filter <https://docs.python.org/3/library/warnings.html#warning-filter>`_ section of
the Python documentation, separated by ``":"``. Optional fields can be omitted.
For example:
.. code-block:: python
@pytest.mark.warnings("ignore:.*usage will be deprecated.*:DeprecationWarning")
def test_foo():
...
.. _`pytest.mark.parametrize ref`:
pytest.mark.parametrize
@@ -123,7 +150,7 @@ Unconditionally skip a test function.
pytest.mark.skipif
~~~~~~~~~~~~~~~~~~
**Tutorial**: :ref:`xfail`.
**Tutorial**: :ref:`skipif`.
Skip a test function if a condition is ``True``.
@@ -175,9 +202,9 @@ For example:
def test_function():
...
Will create and attach a :class:`MarkInfo <_pytest.mark.MarkInfo>` object to the collected
Will create and attach a :class:`Mark <_pytest.mark.structures.Mark>` object to the collected
:class:`Item <_pytest.nodes.Item>`, which can then be accessed by fixtures or hooks with
:meth:`Node.get_marker <_pytest.nodes.Node.get_marker>`. The ``mark`` object will have the following attributes:
:meth:`Node.iter_markers <_pytest.nodes.Node.iter_markers>`. The ``mark`` object will have the following attributes:
.. code-block:: python
@@ -502,6 +529,8 @@ Initialization hooks called for plugins and ``conftest.py`` files.
.. autofunction:: pytest_addhooks
.. autofunction:: pytest_configure
.. autofunction:: pytest_unconfigure
.. autofunction:: pytest_sessionstart
.. autofunction:: pytest_sessionfinish
Test running hooks
~~~~~~~~~~~~~~~~~~
@@ -660,18 +689,28 @@ MarkDecorator
.. autoclass:: _pytest.mark.MarkDecorator
:members:
MarkGenerator
~~~~~~~~~~~~~
.. autoclass:: _pytest.mark.MarkGenerator
:members:
MarkInfo
~~~~~~~~
.. autoclass:: _pytest.mark.MarkInfo
:members:
Mark
~~~~
.. autoclass:: _pytest.mark.structures.Mark
:members:
Metafunc
~~~~~~~~
@@ -906,8 +945,8 @@ passed multiple times. The expected format is ``name=value``. For example::
Allows to pick the action for empty parametersets in parameterization
* ``skip`` skips tests with a empty parameterset (default)
* ``xfail`` marks tests with a empty parameterset as xfail(run=False)
* ``skip`` skips tests with an empty parameterset (default)
* ``xfail`` marks tests with an empty parameterset as xfail(run=False)
.. code-block:: ini
@@ -991,7 +1030,7 @@ passed multiple times. The expected format is ``name=value``. For example::
.. code-block:: ini
[pytest]
log_cli_level = INFO
log_cli_level = INFO
For more information, see :ref:`live_logs`.

View File

@@ -21,7 +21,7 @@ The `pytest-cov`_ package may be installed with pip or easy_install::
pip install pytest-cov
easy_install pytest-cov
.. _`pytest-cov`: http://pypi.python.org/pypi/pytest-cov/
.. _`pytest-cov`: https://pypi.org/project/pytest-cov/
Uninstallation

Some files were not shown because too many files have changed in this diff Show More