@@ -31,7 +31,8 @@ def run(pytester, path="report.html", *args):
31
31
pytester .runpytest ("-s" , "--html" , path , * args )
32
32
33
33
chrome_options = webdriver .ChromeOptions ()
34
- chrome_options .add_argument ("--headless" )
34
+ if os .environ .get ("CI" , False ):
35
+ chrome_options .add_argument ("--headless" )
35
36
chrome_options .add_argument ("--window-size=1920x1080" )
36
37
driver = webdriver .Remote (
37
38
command_executor = "http://127.0.0.1:4444" , options = chrome_options
@@ -90,9 +91,12 @@ def get_text(page, selector):
90
91
return get_element (page , selector ).string
91
92
92
93
93
- def get_log (page ):
94
+ def get_log (page , test_id = None ):
94
95
# TODO(jim) move to get_text (use .contents)
95
- log = get_element (page , ".summary div[class='log']" )
96
+ if test_id :
97
+ log = get_element (page , f".summary tbody[id$='{ test_id } '] div[class='log']" )
98
+ else :
99
+ log = get_element (page , ".summary div[class='log']" )
96
100
all_text = ""
97
101
for text in log .strings :
98
102
all_text += text
@@ -527,3 +531,96 @@ def test_pass(): pass
527
531
)
528
532
page = run (pytester )
529
533
assert_results (page , passed = 1 )
534
+
535
+
536
+ class TestLogCapturing :
537
+ LOG_LINE_REGEX = r"\s+this is {}"
538
+
539
+ @pytest .fixture
540
+ def log_cli (self , pytester ):
541
+ pytester .makeini (
542
+ """
543
+ [pytest]
544
+ log_cli = 1
545
+ log_cli_level = INFO
546
+ log_cli_date_format = %Y-%m-%d %H:%M:%S
547
+ log_cli_format = %(asctime)s %(levelname)s: %(message)s
548
+ """
549
+ )
550
+
551
+ @pytest .fixture
552
+ def test_file (self ):
553
+ return """
554
+ import pytest
555
+ import logging
556
+ @pytest.fixture
557
+ def setup():
558
+ logging.info("this is setup")
559
+ {setup}
560
+ yield
561
+ logging.info("this is teardown")
562
+ {teardown}
563
+
564
+ def test_logging(setup):
565
+ logging.info("this is test")
566
+ assert {assertion}
567
+ """
568
+
569
+ @pytest .mark .usefixtures ("log_cli" )
570
+ def test_all_pass (self , test_file , pytester ):
571
+ pytester .makepyfile (test_file .format (setup = "" , teardown = "" , assertion = True ))
572
+ page = run (pytester )
573
+ assert_results (page , passed = 1 )
574
+
575
+ log = get_log (page )
576
+ for when in ["setup" , "test" , "teardown" ]:
577
+ assert_that (log ).matches (self .LOG_LINE_REGEX .format (when ))
578
+
579
+ @pytest .mark .usefixtures ("log_cli" )
580
+ def test_setup_error (self , test_file , pytester ):
581
+ pytester .makepyfile (
582
+ test_file .format (setup = "error" , teardown = "" , assertion = True )
583
+ )
584
+ page = run (pytester )
585
+ assert_results (page , error = 1 )
586
+
587
+ log = get_log (page )
588
+ assert_that (log ).matches (self .LOG_LINE_REGEX .format ("setup" ))
589
+ assert_that (log ).does_not_match (self .LOG_LINE_REGEX .format ("test" ))
590
+ assert_that (log ).does_not_match (self .LOG_LINE_REGEX .format ("teardown" ))
591
+
592
+ @pytest .mark .usefixtures ("log_cli" )
593
+ def test_test_fails (self , test_file , pytester ):
594
+ pytester .makepyfile (test_file .format (setup = "" , teardown = "" , assertion = False ))
595
+ page = run (pytester )
596
+ assert_results (page , failed = 1 )
597
+
598
+ log = get_log (page )
599
+ for when in ["setup" , "test" , "teardown" ]:
600
+ assert_that (log ).matches (self .LOG_LINE_REGEX .format (when ))
601
+
602
+ @pytest .mark .usefixtures ("log_cli" )
603
+ @pytest .mark .parametrize (
604
+ "assertion, result" , [(True , {"passed" : 1 }), (False , {"failed" : 1 })]
605
+ )
606
+ def test_teardown_error (self , test_file , pytester , assertion , result ):
607
+ pytester .makepyfile (
608
+ test_file .format (setup = "" , teardown = "error" , assertion = assertion )
609
+ )
610
+ page = run (pytester )
611
+ assert_results (page , error = 1 , ** result )
612
+
613
+ for test_name in ["test_logging" , "test_logging::teardown" ]:
614
+ log = get_log (page , test_name )
615
+ for when in ["setup" , "test" , "teardown" ]:
616
+ assert_that (log ).matches (self .LOG_LINE_REGEX .format (when ))
617
+
618
+ def test_no_log (self , test_file , pytester ):
619
+ pytester .makepyfile (test_file .format (setup = "" , teardown = "" , assertion = True ))
620
+ page = run (pytester )
621
+ assert_results (page , passed = 1 )
622
+
623
+ log = get_log (page , "test_logging" )
624
+ assert_that (log ).contains ("No log output captured." )
625
+ for when in ["setup" , "test" , "teardown" ]:
626
+ assert_that (log ).does_not_match (self .LOG_LINE_REGEX .format (when ))
0 commit comments