@@ -18,10 +18,10 @@ Here is a basic pattern to achieve this:
18
18
# content of test_sample.py
19
19
def test_answer (cmdopt ):
20
20
if cmdopt == " type1" :
21
- print (" first" )
21
+ print (" first" )
22
22
elif cmdopt == " type2" :
23
- print (" second" )
24
- assert 0 # to see what was printed
23
+ print (" second" )
24
+ assert 0 # to see what was printed
25
25
26
26
27
27
For this to work we need to add a command line option and
@@ -32,9 +32,12 @@ provide the ``cmdopt`` through a :ref:`fixture function <fixture function>`:
32
32
# content of conftest.py
33
33
import pytest
34
34
35
+
35
36
def pytest_addoption (parser ):
36
- parser.addoption(" --cmdopt" , action = " store" , default = " type1" ,
37
- help = " my option: type1 or type2" )
37
+ parser.addoption(
38
+ " --cmdopt" , action = " store" , default = " type1" , help = " my option: type1 or type2"
39
+ )
40
+
38
41
39
42
@pytest.fixture
40
43
def cmdopt (request ):
@@ -102,9 +105,12 @@ the command line arguments before they get processed:
102
105
103
106
# content of conftest.py
104
107
import sys
108
+
109
+
105
110
def pytest_load_initial_conftests (args ):
106
- if ' xdist' in sys.modules: # pytest-xdist plugin
111
+ if " xdist" in sys.modules: # pytest-xdist plugin
107
112
import multiprocessing
113
+
108
114
num = max (multiprocessing.cpu_count() / 2 , 1 )
109
115
args[:] = [" -n" , str (num)] + args
110
116
@@ -136,9 +142,13 @@ line option to control skipping of ``pytest.mark.slow`` marked tests:
136
142
# content of conftest.py
137
143
138
144
import pytest
145
+
146
+
139
147
def pytest_addoption (parser ):
140
- parser.addoption(" --runslow" , action = " store_true" ,
141
- default = False , help = " run slow tests" )
148
+ parser.addoption(
149
+ " --runslow" , action = " store_true" , default = False , help = " run slow tests"
150
+ )
151
+
142
152
143
153
def pytest_collection_modifyitems (config , items ):
144
154
if config.getoption(" --runslow" ):
@@ -206,10 +216,13 @@ Example:
206
216
207
217
# content of test_checkconfig.py
208
218
import pytest
219
+
220
+
209
221
def checkconfig (x ):
210
222
__tracebackhide__ = True
211
223
if not hasattr (x, " config" ):
212
- pytest.fail(" not configured: %s " % (x,))
224
+ pytest.fail(" not configured: %s " % (x,))
225
+
213
226
214
227
def test_something ():
215
228
checkconfig(42 )
@@ -240,13 +253,16 @@ this to make sure unexpected exception types aren't hidden:
240
253
import operator
241
254
import pytest
242
255
256
+
243
257
class ConfigException (Exception ):
244
258
pass
245
259
260
+
246
261
def checkconfig (x ):
247
- __tracebackhide__ = operator.methodcaller(' errisinstance' , ConfigException)
262
+ __tracebackhide__ = operator.methodcaller(" errisinstance" , ConfigException)
248
263
if not hasattr (x, " config" ):
249
- raise ConfigException(" not configured: %s " % (x,))
264
+ raise ConfigException(" not configured: %s " % (x,))
265
+
250
266
251
267
def test_something ():
252
268
checkconfig(42 )
@@ -269,19 +285,23 @@ running from a test you can do something like this:
269
285
270
286
# content of conftest.py
271
287
288
+
272
289
def pytest_configure (config ):
273
290
import sys
291
+
274
292
sys._called_from_test = True
275
293
294
+
276
295
def pytest_unconfigure (config ):
277
296
import sys
297
+
278
298
del sys._called_from_test
279
299
280
300
and then check for the ``sys._called_from_test `` flag:
281
301
282
302
.. code-block :: python
283
303
284
- if hasattr (sys, ' _called_from_test' ):
304
+ if hasattr (sys, " _called_from_test" ):
285
305
# called from within a test run
286
306
...
287
307
else :
@@ -303,6 +323,7 @@ It's easy to present extra information in a ``pytest`` run:
303
323
304
324
# content of conftest.py
305
325
326
+
306
327
def pytest_report_header (config ):
307
328
return " project deps: mylib-1.1"
308
329
@@ -327,8 +348,9 @@ display more information if applicable:
327
348
328
349
# content of conftest.py
329
350
351
+
330
352
def pytest_report_header (config ):
331
- if config.getoption(' verbose' ) > 0 :
353
+ if config.getoption(" verbose" ) > 0 :
332
354
return [" info1: did you know that ..." , " did you?" ]
333
355
334
356
which will add info only when run with "--v"::
@@ -369,12 +391,15 @@ out which tests are the slowest. Let's make an artificial test suite:
369
391
# content of test_some_are_slow.py
370
392
import time
371
393
394
+
372
395
def test_funcfast ():
373
396
time.sleep(0.1 )
374
397
398
+
375
399
def test_funcslow1 ():
376
400
time.sleep(0.2 )
377
401
402
+
378
403
def test_funcslow2 ():
379
404
time.sleep(0.3 )
380
405
@@ -411,17 +436,19 @@ an ``incremental`` marker which is to be used on classes:
411
436
412
437
import pytest
413
438
439
+
414
440
def pytest_runtest_makereport (item , call ):
415
441
if " incremental" in item.keywords:
416
442
if call.excinfo is not None :
417
443
parent = item.parent
418
444
parent._previousfailed = item
419
445
446
+
420
447
def pytest_runtest_setup (item ):
421
448
if " incremental" in item.keywords:
422
449
previousfailed = getattr (item.parent, " _previousfailed" , None )
423
450
if previousfailed is not None :
424
- pytest.xfail(" previous test failed (%s )" % previousfailed.name)
451
+ pytest.xfail(" previous test failed (%s )" % previousfailed.name)
425
452
426
453
These two hook implementations work together to abort incremental-marked
427
454
tests in a class. Here is a test module example:
@@ -432,15 +459,19 @@ tests in a class. Here is a test module example:
432
459
433
460
import pytest
434
461
462
+
435
463
@pytest.mark.incremental
436
464
class TestUserHandling (object ):
437
465
def test_login (self ):
438
466
pass
467
+
439
468
def test_modification (self ):
440
469
assert 0
470
+
441
471
def test_deletion (self ):
442
472
pass
443
473
474
+
444
475
def test_normal ():
445
476
pass
446
477
@@ -491,9 +522,11 @@ Here is an example for making a ``db`` fixture available in a directory:
491
522
# content of a/conftest.py
492
523
import pytest
493
524
525
+
494
526
class DB (object ):
495
527
pass
496
528
529
+
497
530
@pytest.fixture (scope = " session" )
498
531
def db ():
499
532
return DB()
@@ -602,6 +635,7 @@ case we just write some information out to a ``failures`` file:
602
635
import pytest
603
636
import os.path
604
637
638
+
605
639
@pytest.hookimpl (tryfirst = True , hookwrapper = True )
606
640
def pytest_runtest_makereport (item , call ):
607
641
# execute all other hooks to obtain the report object
@@ -628,6 +662,8 @@ if you then have failing tests:
628
662
# content of test_module.py
629
663
def test_fail1 (tmpdir ):
630
664
assert 0
665
+
666
+
631
667
def test_fail2 ():
632
668
assert 0
633
669
@@ -680,6 +716,7 @@ here is a little example implemented via a local plugin:
680
716
681
717
import pytest
682
718
719
+
683
720
@pytest.hookimpl (tryfirst = True , hookwrapper = True )
684
721
def pytest_runtest_makereport (item , call ):
685
722
# execute all other hooks to obtain the report object
@@ -698,10 +735,10 @@ here is a little example implemented via a local plugin:
698
735
# request.node is an "item" because we use the default
699
736
# "function" scope
700
737
if request.node.rep_setup.failed:
701
- print (" setting up a test failed!" , request.node.nodeid)
738
+ print (" setting up a test failed!" , request.node.nodeid)
702
739
elif request.node.rep_setup.passed:
703
740
if request.node.rep_call.failed:
704
- print (" executing test failed" , request.node.nodeid)
741
+ print (" executing test failed" , request.node.nodeid)
705
742
706
743
707
744
if you then have failing tests:
@@ -712,16 +749,20 @@ if you then have failing tests:
712
749
713
750
import pytest
714
751
752
+
715
753
@pytest.fixture
716
754
def other ():
717
755
assert 0
718
756
757
+
719
758
def test_setup_fails (something , other ):
720
759
pass
721
760
761
+
722
762
def test_call_fails (something ):
723
763
assert 0
724
764
765
+
725
766
def test_fail2 ():
726
767
assert 0
727
768
@@ -789,7 +830,7 @@ test got stuck if necessary:
789
830
790
831
for pid in psutil.pids():
791
832
environ = psutil.Process(pid).environ()
792
- if ' PYTEST_CURRENT_TEST' in environ:
833
+ if " PYTEST_CURRENT_TEST" in environ:
793
834
print (f ' pytest process { pid} running: { environ[" PYTEST_CURRENT_TEST" ]} ' )
794
835
795
836
During the test session pytest will set ``PYTEST_CURRENT_TEST `` to the current test
@@ -843,8 +884,9 @@ like ``pytest-timeout`` they must be imported explicitly and passed on to pytest
843
884
import sys
844
885
import pytest_timeout # Third party plugin
845
886
846
- if len (sys.argv) > 1 and sys.argv[1 ] == ' --pytest' :
887
+ if len (sys.argv) > 1 and sys.argv[1 ] == " --pytest" :
847
888
import pytest
889
+
848
890
sys.exit(pytest.main(sys.argv[2 :], plugins = [pytest_timeout]))
849
891
else :
850
892
# normal application execution: at this point argv can be parsed
0 commit comments