@@ -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,22 +285,28 @@ 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
306
+ ...
286
307
else :
287
308
# called "normally"
309
+ ...
288
310
289
311
accordingly in your application. It's also a good idea
290
312
to use your own application module rather than ``sys ``
@@ -301,6 +323,7 @@ It's easy to present extra information in a ``pytest`` run:
301
323
302
324
# content of conftest.py
303
325
326
+
304
327
def pytest_report_header (config ):
305
328
return " project deps: mylib-1.1"
306
329
@@ -325,8 +348,9 @@ display more information if applicable:
325
348
326
349
# content of conftest.py
327
350
351
+
328
352
def pytest_report_header (config ):
329
- if config.getoption(' verbose' ) > 0 :
353
+ if config.getoption(" verbose" ) > 0 :
330
354
return [" info1: did you know that ..." , " did you?" ]
331
355
332
356
which will add info only when run with "--v"::
@@ -367,12 +391,15 @@ out which tests are the slowest. Let's make an artificial test suite:
367
391
# content of test_some_are_slow.py
368
392
import time
369
393
394
+
370
395
def test_funcfast ():
371
396
time.sleep(0.1 )
372
397
398
+
373
399
def test_funcslow1 ():
374
400
time.sleep(0.2 )
375
401
402
+
376
403
def test_funcslow2 ():
377
404
time.sleep(0.3 )
378
405
@@ -409,17 +436,19 @@ an ``incremental`` marker which is to be used on classes:
409
436
410
437
import pytest
411
438
439
+
412
440
def pytest_runtest_makereport (item , call ):
413
441
if " incremental" in item.keywords:
414
442
if call.excinfo is not None :
415
443
parent = item.parent
416
444
parent._previousfailed = item
417
445
446
+
418
447
def pytest_runtest_setup (item ):
419
448
if " incremental" in item.keywords:
420
449
previousfailed = getattr (item.parent, " _previousfailed" , None )
421
450
if previousfailed is not None :
422
- pytest.xfail(" previous test failed (%s )" % previousfailed.name)
451
+ pytest.xfail(" previous test failed (%s )" % previousfailed.name)
423
452
424
453
These two hook implementations work together to abort incremental-marked
425
454
tests in a class. Here is a test module example:
@@ -430,15 +459,19 @@ tests in a class. Here is a test module example:
430
459
431
460
import pytest
432
461
462
+
433
463
@pytest.mark.incremental
434
464
class TestUserHandling (object ):
435
465
def test_login (self ):
436
466
pass
467
+
437
468
def test_modification (self ):
438
469
assert 0
470
+
439
471
def test_deletion (self ):
440
472
pass
441
473
474
+
442
475
def test_normal ():
443
476
pass
444
477
@@ -489,9 +522,11 @@ Here is an example for making a ``db`` fixture available in a directory:
489
522
# content of a/conftest.py
490
523
import pytest
491
524
525
+
492
526
class DB (object ):
493
527
pass
494
528
529
+
495
530
@pytest.fixture (scope = " session" )
496
531
def db ():
497
532
return DB()
@@ -600,6 +635,7 @@ case we just write some information out to a ``failures`` file:
600
635
import pytest
601
636
import os.path
602
637
638
+
603
639
@pytest.hookimpl (tryfirst = True , hookwrapper = True )
604
640
def pytest_runtest_makereport (item , call ):
605
641
# execute all other hooks to obtain the report object
@@ -626,6 +662,8 @@ if you then have failing tests:
626
662
# content of test_module.py
627
663
def test_fail1 (tmpdir ):
628
664
assert 0
665
+
666
+
629
667
def test_fail2 ():
630
668
assert 0
631
669
@@ -678,6 +716,7 @@ here is a little example implemented via a local plugin:
678
716
679
717
import pytest
680
718
719
+
681
720
@pytest.hookimpl (tryfirst = True , hookwrapper = True )
682
721
def pytest_runtest_makereport (item , call ):
683
722
# execute all other hooks to obtain the report object
@@ -696,10 +735,10 @@ here is a little example implemented via a local plugin:
696
735
# request.node is an "item" because we use the default
697
736
# "function" scope
698
737
if request.node.rep_setup.failed:
699
- print (" setting up a test failed!" , request.node.nodeid)
738
+ print (" setting up a test failed!" , request.node.nodeid)
700
739
elif request.node.rep_setup.passed:
701
740
if request.node.rep_call.failed:
702
- print (" executing test failed" , request.node.nodeid)
741
+ print (" executing test failed" , request.node.nodeid)
703
742
704
743
705
744
if you then have failing tests:
@@ -710,16 +749,20 @@ if you then have failing tests:
710
749
711
750
import pytest
712
751
752
+
713
753
@pytest.fixture
714
754
def other ():
715
755
assert 0
716
756
757
+
717
758
def test_setup_fails (something , other ):
718
759
pass
719
760
761
+
720
762
def test_call_fails (something ):
721
763
assert 0
722
764
765
+
723
766
def test_fail2 ():
724
767
assert 0
725
768
@@ -787,7 +830,7 @@ test got stuck if necessary:
787
830
788
831
for pid in psutil.pids():
789
832
environ = psutil.Process(pid).environ()
790
- if ' PYTEST_CURRENT_TEST' in environ:
833
+ if " PYTEST_CURRENT_TEST" in environ:
791
834
print (f ' pytest process { pid} running: { environ[" PYTEST_CURRENT_TEST" ]} ' )
792
835
793
836
During the test session pytest will set ``PYTEST_CURRENT_TEST `` to the current test
@@ -841,8 +884,9 @@ like ``pytest-timeout`` they must be imported explicitly and passed on to pytest
841
884
import sys
842
885
import pytest_timeout # Third party plugin
843
886
844
- if len (sys.argv) > 1 and sys.argv[1 ] == ' --pytest' :
887
+ if len (sys.argv) > 1 and sys.argv[1 ] == " --pytest" :
845
888
import pytest
889
+
846
890
sys.exit(pytest.main(sys.argv[2 :], plugins = [pytest_timeout]))
847
891
else :
848
892
# normal application execution: at this point argv can be parsed
0 commit comments