1
1
# /////////////////////////////////////////////////////////////////////////////
2
2
# PyTest Configuration
3
3
4
- import _pytest .outcomes
5
-
6
4
import pluggy
7
5
import pytest
8
- import _pytest
9
6
import os
10
7
import logging
11
8
import pathlib
12
9
import math
13
10
import datetime
14
11
12
+ import _pytest .outcomes
13
+ import _pytest .unittest
14
+ import _pytest .logging
15
+
15
16
# /////////////////////////////////////////////////////////////////////////////
16
17
17
18
C_ROOT_DIR__RELATIVE = ".."
@@ -91,10 +92,6 @@ def GetCurrentTestWorkerSignature() -> str:
91
92
return __class__ .sm_CurrentTestWorkerSignature
92
93
93
94
94
- # /////////////////////////////////////////////////////////////////////////////# /////////////////////////////////////////////////////////////////////////////
95
- # Fixtures
96
-
97
-
98
95
# /////////////////////////////////////////////////////////////////////////////
99
96
# TEST_PROCESS_STATS
100
97
@@ -109,10 +106,12 @@ class TEST_PROCESS_STATS:
109
106
cSkippedTests : int = 0
110
107
cNotXFailedTests : int = 0
111
108
cUnexpectedTests : int = 0
109
+ cAchtungTests : int = 0
112
110
113
111
FailedTests = list [str ]()
114
112
XFailedTests = list [str ]()
115
113
NotXFailedTests = list [str ]()
114
+ AchtungTests = list [str ]()
116
115
117
116
# --------------------------------------------------------------------
118
117
def incrementTotalTestCount () -> None :
@@ -163,6 +162,14 @@ def incrementNotXFailedTests(testID: str) -> None:
163
162
def incrementUnexpectedTests () -> None :
164
163
__class__ .cUnexpectedTests += 1
165
164
165
+ # --------------------------------------------------------------------
166
+ def incrementAchtungTestCount (testID : str ) -> None :
167
+ assert type (testID ) == str # noqa: E721
168
+ assert type (__class__ .AchtungTests ) == list # noqa: E721
169
+
170
+ __class__ .AchtungTests .append (testID ) # raise?
171
+ __class__ .cAchtungTests += 1
172
+
166
173
167
174
# /////////////////////////////////////////////////////////////////////////////
168
175
@@ -198,10 +205,13 @@ def helper__makereport__setup(
198
205
assert item is not None
199
206
assert call is not None
200
207
assert outcome is not None
201
- assert type (item ) == pytest .Function # noqa: E721
208
+ # it may be pytest.Function or _pytest.unittest.TestCaseFunction
209
+ assert isinstance (item , pytest .Function )
202
210
assert type (call ) == pytest .CallInfo # noqa: E721
203
211
assert type (outcome ) == pluggy .Result # noqa: E721
204
212
213
+ C_LINE1 = "******************************************************"
214
+
205
215
# logging.info("pytest_runtest_makereport - setup")
206
216
207
217
TEST_PROCESS_STATS .incrementTotalTestCount ()
@@ -214,26 +224,42 @@ def helper__makereport__setup(
214
224
TEST_PROCESS_STATS .incrementNotExecutedTestCount ()
215
225
return
216
226
217
- assert rep .outcome == "passed"
218
-
219
- testNumber = TEST_PROCESS_STATS .incrementExecutedTestCount ()
220
-
221
227
testID = ""
222
228
223
229
if item .cls is not None :
224
230
testID = item .cls .__module__ + "." + item .cls .__name__ + "::"
225
231
226
232
testID = testID + item .name
227
233
228
- if testNumber > 1 :
229
- logging .info ("" )
234
+ if rep .outcome == "passed" :
235
+ testNumber = TEST_PROCESS_STATS .incrementExecutedTestCount ()
236
+
237
+ logging .info (C_LINE1 )
238
+ logging .info ("* START TEST {0}" .format (testID ))
239
+ logging .info ("*" )
240
+ logging .info ("* Path : {0}" .format (item .path ))
241
+ logging .info ("* Number: {0}" .format (testNumber ))
242
+ logging .info ("*" )
243
+ return
244
+
245
+ assert rep .outcome != "passed"
246
+
247
+ TEST_PROCESS_STATS .incrementAchtungTestCount (testID )
230
248
231
- logging .info ("******************************************************" )
232
- logging .info ("* START TEST {0}" .format (testID ))
249
+ logging .info (C_LINE1 )
250
+ logging .info ("* ACHTUNG TEST {0}" .format (testID ))
233
251
logging .info ("*" )
234
252
logging .info ("* Path : {0}" .format (item .path ))
235
- logging .info ("* Number: {0}" .format (testNumber ))
253
+ logging .info ("* Outcome is [{0}]" .format (rep .outcome ))
254
+
255
+ if rep .outcome == "failed" :
256
+ assert call .excinfo is not None
257
+ assert call .excinfo .value is not None
258
+ logging .info ("*" )
259
+ logging .error (call .excinfo .value )
260
+
236
261
logging .info ("*" )
262
+ return
237
263
238
264
239
265
# ------------------------------------------------------------------------
@@ -243,12 +269,11 @@ def helper__makereport__call(
243
269
assert item is not None
244
270
assert call is not None
245
271
assert outcome is not None
246
- assert type (item ) == pytest .Function # noqa: E721
272
+ # it may be pytest.Function or _pytest.unittest.TestCaseFunction
273
+ assert isinstance (item , pytest .Function )
247
274
assert type (call ) == pytest .CallInfo # noqa: E721
248
275
assert type (outcome ) == pluggy .Result # noqa: E721
249
276
250
- # logging.info("pytest_runtest_makereport - call")
251
-
252
277
rep = outcome .get_result ()
253
278
assert rep is not None
254
279
assert type (rep ) == pytest .TestReport # noqa: E721
@@ -341,7 +366,8 @@ def helper__makereport__call(
341
366
else :
342
367
TEST_PROCESS_STATS .incrementUnexpectedTests ()
343
368
exitStatus = "UNEXPECTED [{0}]" .format (rep .outcome )
344
- assert False
369
+ # [2025-03-28] It may create a useless problem in new environment.
370
+ # assert False
345
371
346
372
# --------
347
373
logging .info ("*" )
@@ -350,6 +376,7 @@ def helper__makereport__call(
350
376
logging .info ("* EXIT STATUS : {0}" .format (exitStatus ))
351
377
logging .info ("*" )
352
378
logging .info ("* STOP TEST {0}" .format (testID ))
379
+ logging .info ("*" )
353
380
354
381
355
382
# /////////////////////////////////////////////////////////////////////////////
@@ -359,17 +386,14 @@ def helper__makereport__call(
359
386
def pytest_runtest_makereport (item : pytest .Function , call : pytest .CallInfo ):
360
387
assert item is not None
361
388
assert call is not None
362
- assert type (item ) == pytest .Function # noqa: E721
389
+ # it may be pytest.Function or _pytest.unittest.TestCaseFunction
390
+ assert isinstance (item , pytest .Function )
363
391
assert type (call ) == pytest .CallInfo # noqa: E721
364
392
365
- # logging.info("[pytest_runtest_makereport][#001][{0}][{1}]".format(item.name, call.when))
366
-
367
393
outcome : pluggy .Result = yield
368
394
assert outcome is not None
369
395
assert type (outcome ) == pluggy .Result # noqa: E721
370
396
371
- # logging.info("[pytest_runtest_makereport][#002][{0}][{1}]".format(item.name, call.when))
372
-
373
397
rep : pytest .TestReport = outcome .get_result ()
374
398
assert rep is not None
375
399
assert type (rep ) == pytest .TestReport # noqa: E721
@@ -440,41 +464,61 @@ def run_after_tests(request: pytest.FixtureRequest):
440
464
441
465
yield
442
466
443
- logging .info ("--------------------------- [FAILED TESTS]" )
444
- logging .info ("" )
445
-
446
- assert len (TEST_PROCESS_STATS .FailedTests ) == TEST_PROCESS_STATS .cFailedTests
447
-
448
- if len (TEST_PROCESS_STATS .FailedTests ) > 0 :
449
- helper__print_test_list (TEST_PROCESS_STATS .FailedTests )
450
- logging .info ("" )
467
+ C_LINE1 = "---------------------------"
451
468
452
- logging .info ("--------------------------- [XFAILED TESTS]" )
453
- logging .info ("" )
469
+ def LOCAL__print_line1_with_header (header : str ):
470
+ assert type (C_LINE1 ) == str # noqa: E721
471
+ assert type (header ) == str # noqa: E721
472
+ assert header != ""
473
+ logging .info (C_LINE1 + " [" + header + "]" )
454
474
455
- assert len (TEST_PROCESS_STATS .XFailedTests ) == TEST_PROCESS_STATS .cXFailedTests
475
+ def LOCAL__print_test_list (header : str , test_count : int , test_list : list [str ]):
476
+ assert type (header ) == str # noqa: E721
477
+ assert type (test_count ) == int # noqa: E721
478
+ assert type (test_list ) == list # noqa: E721
479
+ assert header != ""
480
+ assert test_count >= 0
481
+ assert len (test_list ) == test_count
456
482
457
- if len (TEST_PROCESS_STATS .XFailedTests ) > 0 :
458
- helper__print_test_list (TEST_PROCESS_STATS .XFailedTests )
483
+ LOCAL__print_line1_with_header (header )
459
484
logging .info ("" )
485
+ if len (test_list ) > 0 :
486
+ helper__print_test_list (test_list )
487
+ logging .info ("" )
488
+
489
+ # fmt: off
490
+ LOCAL__print_test_list (
491
+ "ACHTUNG TESTS" ,
492
+ TEST_PROCESS_STATS .cAchtungTests ,
493
+ TEST_PROCESS_STATS .AchtungTests ,
494
+ )
460
495
461
- logging .info ("--------------------------- [NOT XFAILED TESTS]" )
462
- logging .info ("" )
496
+ LOCAL__print_test_list (
497
+ "FAILED TESTS" ,
498
+ TEST_PROCESS_STATS .cFailedTests ,
499
+ TEST_PROCESS_STATS .FailedTests
500
+ )
463
501
464
- assert (
465
- len (TEST_PROCESS_STATS .NotXFailedTests ) == TEST_PROCESS_STATS .cNotXFailedTests
502
+ LOCAL__print_test_list (
503
+ "XFAILED TESTS" ,
504
+ TEST_PROCESS_STATS .cXFailedTests ,
505
+ TEST_PROCESS_STATS .XFailedTests ,
466
506
)
467
507
468
- if len (TEST_PROCESS_STATS .NotXFailedTests ) > 0 :
469
- helper__print_test_list (TEST_PROCESS_STATS .NotXFailedTests )
470
- logging .info ("" )
508
+ LOCAL__print_test_list (
509
+ "NOT XFAILED TESTS" ,
510
+ TEST_PROCESS_STATS .cNotXFailedTests ,
511
+ TEST_PROCESS_STATS .NotXFailedTests ,
512
+ )
513
+ # fmt: on
471
514
472
- logging . info ( "--------------------------- [ SUMMARY STATISTICS] " )
515
+ LOCAL__print_line1_with_header ( " SUMMARY STATISTICS" )
473
516
logging .info ("" )
474
517
logging .info ("[TESTS]" )
475
518
logging .info (" TOTAL : {0}" .format (TEST_PROCESS_STATS .cTotalTests ))
476
519
logging .info (" EXECUTED : {0}" .format (TEST_PROCESS_STATS .cExecutedTests ))
477
520
logging .info (" NOT EXECUTED: {0}" .format (TEST_PROCESS_STATS .cNotExecutedTests ))
521
+ logging .info (" ACHTUNG : {0}" .format (TEST_PROCESS_STATS .cAchtungTests ))
478
522
logging .info ("" )
479
523
logging .info (" PASSED : {0}" .format (TEST_PROCESS_STATS .cPassedTests ))
480
524
logging .info (" FAILED : {0}" .format (TEST_PROCESS_STATS .cFailedTests ))
@@ -503,7 +547,13 @@ def pytest_configure(config: pytest.Config) -> None:
503
547
504
548
log_path .mkdir (exist_ok = True )
505
549
506
- logging_plugin = config .pluginmanager .get_plugin ("logging-plugin" )
550
+ logging_plugin : _pytest .logging .LoggingPlugin = config .pluginmanager .get_plugin (
551
+ "logging-plugin"
552
+ )
553
+
554
+ assert logging_plugin is not None
555
+ assert isinstance (logging_plugin , _pytest .logging .LoggingPlugin )
556
+
507
557
logging_plugin .set_log_path (str (log_path / log_name ))
508
558
509
559
0 commit comments