将日志分隔符添加到unittes中的所有fixture中

时间:2015-09-16 13:47:29

标签: python unit-testing logging global fixtures

我使用unittest模块。我需要从unittests日志中分离setUp,setUpClass,teardown和teardownClass日志。输出应该类似于:

NOTICE:  [lwgeom_functions_basic.c:LWGEOM_makepoint:2144] LWGEOM_makepoint called
NOTICE:  [g_serialized.c:gserialized_from_any_size:378] Input type: Point
NOTICE:  [g_serialized.c:gserialized_from_lwpoint_size:286] point size = 24
NOTICE:  [g_serialized.c:gserialized_from_lwgeom_size:420] g_serialize size = 32
NOTICE:  [g_serialized.c:gserialized_from_lwgeom_any:677] Input type (1) Point, hasz: 0 hasm: 0
NOTICE:  [g_serialized.c:gserialized_from_lwgeom_any:678] LWGEOM(0x2b87172b3080) uint8_t(0x2b87172b3228)
NOTICE:  [g_serialized.c:gserialized_from_lwpoint:445] lwpoint_to_gserialized(0x2b87172b3080, 0x2b87172b3228) called
NOTICE:  [g_serialized.c:gserialized_set_srid:78] Called with srid = 0
NOTICE:  [g_serialized.c:gserialized_get_type:50] entered
NOTICE:  [g_serialized.c:lwgeom_from_gserialized:1137] Got type 1 (Point), srid=0
NOTICE:  [g_serialized.c:lwgeom_from_gserialized_buffer:1091] Got type 1 (Point), hasz=0 hasm=0 geodetic=0 hasbox=0
NOTICE:  [g_serialized.c:gserialized_get_type:50] entered
NOTICE:  [lwgeom.c:lwgeom_set_srid:1455] entered with srid=0
NOTICE:  [lwgeom.c:lwgeom_set_srid:1455] entered with srid=26913
NOTICE:  [g_serialized.c:gserialized_from_any_size:378] Input type: Point
NOTICE:  [g_serialized.c:gserialized_from_lwpoint_size:286] point size = 24
NOTICE:  [g_serialized.c:gserialized_from_lwgeom_size:420] g_serialize size = 48
NOTICE:  [g_serialized.c:gserialized_from_gbox:772] returning size 16
NOTICE:  [g_serialized.c:gserialized_from_lwgeom_any:677] Input type (1) Point, hasz: 0 hasm: 0
NOTICE:  [g_serialized.c:gserialized_from_lwgeom_any:678] LWGEOM(0x2b87172b30a0) uint8_t(0x2b87172b3048)
NOTICE:  [g_serialized.c:gserialized_from_lwpoint:445] lwpoint_to_gserialized(0x2b87172b30a0, 0x2b87172b3048) called
NOTICE:  [g_serialized.c:gserialized_set_srid:78] Called with srid = 26913
NOTICE:  [g_serialized.c:gserialized_get_type:50] entered
NOTICE:  [g_serialized.c:gserialized_get_type:53] skipping forward past bbox (16 bytes)
NOTICE:  [g_serialized.c:lwgeom_from_gserialized:1137] Got type 1 (Point), srid=26913
NOTICE:  [g_serialized.c:lwgeom_from_gserialized_buffer:1091] Got type 1 (Point), hasz=0 hasm=0 geodetic=0 hasbox=1
NOTICE:  [lwgeom.c:lwgeom_set_srid:1455] entered with srid=26913
NOTICE:  [lwgeom.c:lwgeom_is_empty:1233] lwgeom_is_empty: got type Point
NOTICE:  [lwout_wkb.c:lwgeom_to_wkb:710] WKB output size: 25
NOTICE:  [lwout_wkb.c:lwgeom_to_wkb:723] Hex WKB output size: 51
NOTICE:  [lwgeom.c:lwgeom_is_empty:1233] lwgeom_is_empty: got type Point
NOTICE:  [lwout_wkb.c:lwpoint_to_wkb_buf:393] Entering function, buf = 0x2b87172b3530
NOTICE:  [lwout_wkb.c:lwpoint_to_wkb_buf:395] Endian set, buf = 0x2b87172b3532
NOTICE:  [lwout_wkb.c:integer_to_wkb_buf:189] Writing value '536870913'
NOTICE:  [lwout_wkb.c:lwpoint_to_wkb_buf:398] Type set, buf = 0x2b87172b353a
NOTICE:  [lwout_wkb.c:integer_to_wkb_buf:189] Writing value '26913'
NOTICE:  [lwout_wkb.c:lwpoint_to_wkb_buf:403] SRID set, buf = 0x2b87172b3542
NOTICE:  [lwout_wkb.c:ptarray_to_wkb_buf:360] Writing point #0
NOTICE:  [lwout_wkb.c:ptarray_to_wkb_buf:364] Writing dimension #0 (buf = 0x2b87172b3542)
NOTICE:  [lwout_wkb.c:ptarray_to_wkb_buf:364] Writing dimension #1 (buf = 0x2b87172b3552)
NOTICE:  [lwout_wkb.c:ptarray_to_wkb_buf:369] Done (buf = 0x2b87172b3562)
NOTICE:  [lwout_wkb.c:lwpoint_to_wkb_buf:407] Pointarray set, buf = 0x2b87172b3562
NOTICE:  [lwout_wkb.c:lwgeom_to_wkb:759] buf (0x2b87172b3563) - wkb_out (0x2b87172b3530) = 51
Total query runtime: 561 ms.
1 row retrieved.

我尝试覆盖unittest.suite(_handleClassSetUp,_handleModuleFixtures,_teDDownPreviousClass)中的一些函数,以便在调用它们之前和之后记录分隔符。因此,即使测试用例不包含setUpClass和tearDownClass,也会记录分隔符。而且,没有用于设置和拆卸的分隔符。

怎么做?

1 个答案:

答案 0 :(得分:3)

您可以使用元类来实现此功能。它所做的只是查找您提供的函数名列表,然后将装饰器应用于这些函数。装饰器处理打印输入和退出语句。

import functools
import unittest

FUNCTIONS_TO_LOG = ('setUp', 'tearDown')


def log_start_and_end(f):
    @functools.wraps(f)
    def wrapper(*args, **kwargs):
        print '********** start {}'.format(f.__name__)
        f(*args, **kwargs)
        print '********** end {}'.format(f.__name__)
    return wrapper


class LoggingMeta(type):
    def __new__(cls, name, bases, namespace):
        for attr, obj in namespace.items():
            if attr in FUNCTIONS_TO_LOG:
                namespace[attr] = log_start_and_end(obj)
        return super(LoggingMeta, cls).__new__(cls, name, bases, namespace)


class BaseTest(unittest.TestCase):
    __metaclass__ = LoggingMeta

    def setUp(self):
        print 'inside setup'

    def tearDown(self):
        print 'inside teardown'

    def test_test(self):
        print 'inside test'

if __name__ == '__main__':
    unittest.main()

这导致输出:

********** start setUp
inside setup
********** end setUp
inside test
********** start tearDown
inside teardown
********** end tearDown
.
Ran 1 test in 0.000s

OK