11# /////////////////////////////////////////////////////////////////////////////
22# PyTest Configuration
33
4- import _pytest .outcomes
5-
64import pluggy
75import pytest
8- import _pytest
96import os
107import logging
118import pathlib
129import math
1310import datetime
1411
12+ import _pytest .outcomes
13+ import _pytest .unittest
14+ import _pytest .logging
15+
1516# /////////////////////////////////////////////////////////////////////////////
1617
1718C_ROOT_DIR__RELATIVE = ".."
@@ -91,10 +92,6 @@ def GetCurrentTestWorkerSignature() -> str:
9192 return __class__ .sm_CurrentTestWorkerSignature
9293
9394
94- # /////////////////////////////////////////////////////////////////////////////# /////////////////////////////////////////////////////////////////////////////
95- # Fixtures
96-
97-
9895# /////////////////////////////////////////////////////////////////////////////
9996# TEST_PROCESS_STATS
10097
@@ -109,10 +106,12 @@ class TEST_PROCESS_STATS:
109106 cSkippedTests : int = 0
110107 cNotXFailedTests : int = 0
111108 cUnexpectedTests : int = 0
109+ cAchtungTests : int = 0
112110
113111 FailedTests = list [str ]()
114112 XFailedTests = list [str ]()
115113 NotXFailedTests = list [str ]()
114+ AchtungTests = list [str ]()
116115
117116 # --------------------------------------------------------------------
118117 def incrementTotalTestCount () -> None :
@@ -163,6 +162,14 @@ def incrementNotXFailedTests(testID: str) -> None:
163162 def incrementUnexpectedTests () -> None :
164163 __class__ .cUnexpectedTests += 1
165164
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+
166173
167174# /////////////////////////////////////////////////////////////////////////////
168175
@@ -198,10 +205,13 @@ def helper__makereport__setup(
198205 assert item is not None
199206 assert call is not None
200207 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 )
202210 assert type (call ) == pytest .CallInfo # noqa: E721
203211 assert type (outcome ) == pluggy .Result # noqa: E721
204212
213+ C_LINE1 = "******************************************************"
214+
205215 # logging.info("pytest_runtest_makereport - setup")
206216
207217 TEST_PROCESS_STATS .incrementTotalTestCount ()
@@ -214,26 +224,42 @@ def helper__makereport__setup(
214224 TEST_PROCESS_STATS .incrementNotExecutedTestCount ()
215225 return
216226
217- assert rep .outcome == "passed"
218-
219- testNumber = TEST_PROCESS_STATS .incrementExecutedTestCount ()
220-
221227 testID = ""
222228
223229 if item .cls is not None :
224230 testID = item .cls .__module__ + "." + item .cls .__name__ + "::"
225231
226232 testID = testID + item .name
227233
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 )
230248
231- logging .info ("******************************************************" )
232- logging .info ("* START TEST {0}" .format (testID ))
249+ logging .info (C_LINE1 )
250+ logging .info ("* ACHTUNG TEST {0}" .format (testID ))
233251 logging .info ("*" )
234252 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+
236261 logging .info ("*" )
262+ return
237263
238264
239265# ------------------------------------------------------------------------
@@ -243,12 +269,11 @@ def helper__makereport__call(
243269 assert item is not None
244270 assert call is not None
245271 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 )
247274 assert type (call ) == pytest .CallInfo # noqa: E721
248275 assert type (outcome ) == pluggy .Result # noqa: E721
249276
250- # logging.info("pytest_runtest_makereport - call")
251-
252277 rep = outcome .get_result ()
253278 assert rep is not None
254279 assert type (rep ) == pytest .TestReport # noqa: E721
@@ -341,7 +366,8 @@ def helper__makereport__call(
341366 else :
342367 TEST_PROCESS_STATS .incrementUnexpectedTests ()
343368 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
345371
346372 # --------
347373 logging .info ("*" )
@@ -350,6 +376,7 @@ def helper__makereport__call(
350376 logging .info ("* EXIT STATUS : {0}" .format (exitStatus ))
351377 logging .info ("*" )
352378 logging .info ("* STOP TEST {0}" .format (testID ))
379+ logging .info ("*" )
353380
354381
355382# /////////////////////////////////////////////////////////////////////////////
@@ -359,17 +386,14 @@ def helper__makereport__call(
359386def pytest_runtest_makereport (item : pytest .Function , call : pytest .CallInfo ):
360387 assert item is not None
361388 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 )
363391 assert type (call ) == pytest .CallInfo # noqa: E721
364392
365- # logging.info("[pytest_runtest_makereport][#001][{0}][{1}]".format(item.name, call.when))
366-
367393 outcome : pluggy .Result = yield
368394 assert outcome is not None
369395 assert type (outcome ) == pluggy .Result # noqa: E721
370396
371- # logging.info("[pytest_runtest_makereport][#002][{0}][{1}]".format(item.name, call.when))
372-
373397 rep : pytest .TestReport = outcome .get_result ()
374398 assert rep is not None
375399 assert type (rep ) == pytest .TestReport # noqa: E721
@@ -440,41 +464,61 @@ def run_after_tests(request: pytest.FixtureRequest):
440464
441465 yield
442466
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 = "---------------------------"
451468
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 + "]" )
454474
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
456482
457- if len (TEST_PROCESS_STATS .XFailedTests ) > 0 :
458- helper__print_test_list (TEST_PROCESS_STATS .XFailedTests )
483+ LOCAL__print_line1_with_header (header )
459484 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+ )
460495
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+ )
463501
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 ,
466506 )
467507
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
471514
472- logging . info ( "--------------------------- [ SUMMARY STATISTICS] " )
515+ LOCAL__print_line1_with_header ( " SUMMARY STATISTICS" )
473516 logging .info ("" )
474517 logging .info ("[TESTS]" )
475518 logging .info (" TOTAL : {0}" .format (TEST_PROCESS_STATS .cTotalTests ))
476519 logging .info (" EXECUTED : {0}" .format (TEST_PROCESS_STATS .cExecutedTests ))
477520 logging .info (" NOT EXECUTED: {0}" .format (TEST_PROCESS_STATS .cNotExecutedTests ))
521+ logging .info (" ACHTUNG : {0}" .format (TEST_PROCESS_STATS .cAchtungTests ))
478522 logging .info ("" )
479523 logging .info (" PASSED : {0}" .format (TEST_PROCESS_STATS .cPassedTests ))
480524 logging .info (" FAILED : {0}" .format (TEST_PROCESS_STATS .cFailedTests ))
@@ -503,7 +547,13 @@ def pytest_configure(config: pytest.Config) -> None:
503547
504548 log_path .mkdir (exist_ok = True )
505549
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+
507557 logging_plugin .set_log_path (str (log_path / log_name ))
508558
509559
0 commit comments