代码之家  ›  专栏  ›  技术社区  ›  James Adams

Python:如何在单元(nose)测试期间忽略修饰符?

  •  5
  • James Adams  · 技术社区  · 7 年前

    我想忽略代码中的某些修饰符,以跳过相关功能,但仅在作为单元测试的一部分运行时。这能做到吗?

    例如,我有一个函数f,用一个Nuba修饰符定义,如下所示:

    @numba.jit
    def f(a, b):
      return a + b
    

    当我运行一个调用上述函数的单元测试时,我不希望出现numba魔术,因为它会减慢速度并在某些平台上导致错误。有没有可能在某个地方设置一个设置,让nose在不应用任何numba实时(和/或所有numba)修饰符的情况下运行测试?

    5 回复  |  直到 6 年前
        1
  •  4
  •   Dunes    7 年前

    仅对于NUBA,您可以设置环境变量(例如。 export NUMBA_DISABLE_JIT=1 )使jit装饰器无需操作。

    http://numba.pydata.org/numba-doc/dev/user/troubleshoot.html#disabling-jit-compilation

        2
  •  2
  •   Mike Müller    7 年前

    您可能可以欺骗nose使用自己的装饰器来保持函数不变。 写入文件 numba.py 包含此函数的:

    def jit(func):
        return func
    

    放在你的蟒蛇身上。 可以从该文件所在的目录运行测试,也可以在中执行此操作 您的测试文件作为第一行:

    import sys
    
    sys.path.insert(0, 'path/to/dir/with/myfile') 
    

    或者,可以设置环境变量 PYTHONPATH 到文件所在的目录。

    窗户:

    set PYTHONPATH=%PYTHONPATH%;path/to/dir/with/myfile
    

    Unix/Mac:

    export PYTHONPATH=$PYTHONPATH$:path/to/dir/with/myfile
    
        3
  •  2
  •   georgexsh    7 年前

    您可以使用新的装饰器修补装饰器,您可以控制:

    import functools
    
    def patch(parent, obj_name, switch_reg, switch_name):
        def gen_switcher():
            def wrapper(func):
                ori_wrapped = ori_decorator(func)
                @functools.wraps(func)
                def _(*args, **kwargs):
                    if switch_reg.get(switch_name, False):
                        func_to_call = func
                    else:
                        func_to_call = ori_wrapped
                    print(func_to_call)
                    return func_to_call(*args, **kwargs)
                return _
            return wrapper
        ori_decorator = getattr(parent, obj_name)
        setattr(parent, obj_name, gen_switcher())
    

    使用:

    # have to patch the decorator before applying it
    import numba
    switchs = {}
    patch(numba, 'jit', switchs, 'DISABLE_NUMBA_JIT')
    
    @numba.jit
    def f(a, b):
      return a + b
    
    f(1, 2)
    

    产量:

    CPUDispatcher(<function f at 0x10a5f90d0>)
    

    然后使用:

    # this part could be rewrited as a context manager    
    switchs['DISABLE_NUMBA_JIT'] = True
    f(1, 2)
    

    获取:

    <function f at 0x10a5f90d0>
    
        4
  •  2
  •   dopexxx    3 年前

    如果您正在使用 coverage ,您可以修改CI .yml 通过添加文件 NUMBA_DISABLE_JIT=1 就在你的 新闻报道 命令:

    NUMBA_DISABLE_JIT=1 coverage run -p "test_*.py"
    
        5
  •  1
  •   Harald Nordgren    6 年前

    我会将该函数分离为一个非修饰部分,由您进行单元测试,然后让您的实际函数具有修饰器,只需调用helper函数:

    @numba.jit
    def f(a, b):
      return f_undecorated(a, b)
    
    def f_undecorated(a, b):
      return a + b
    

    仅为编写单元测试 f_undecorated .