如何忽略单元测试中的Python代码块?

时间:2017-02-06 01:48:54

标签: python unit-testing

我的模块中有以下代码块,

PARSER = argparse.ArgumentParser(description='This script gets ELB statistics '
                                             'and look for any failed instances')
PARSER.add_argument('--profile', help='AWS profile - optional (only if multiple '
                                      'accounts are setup in credentials file)', default='')
PARSER.add_argument('--region', help='AWS region. Defaults to ap-southeast-2',
                    default='ap-southeast-2')
PARSER.add_argument('--elb', help='DNS Name of the ELB to test', required=True)
PARSER.add_argument('--start', help='Start time of the load test (YYYY-MM-DD HH:MM:SS)',
                    required=True)
PARSER.add_argument('--end', help='End time of the load test (YYYY-MM-DD HH:MM:SS)',
                    required=True)
PARSER.add_argument('--debug', help='Print debugging information', action='store_true')

ARGS = PARSER.parse_args()

PROFILE = ARGS.profile
REGION = ARGS.region
ELB = ARGS.elb
START_TIME = format_date_string(ARGS.start)
END_TIME = format_date_string(ARGS.end)
DEBUG = ARGS.debug

if (START_TIME and END_TIME) is not None and START_TIME < END_TIME:
    ASG_MON = ASGMonitor(elb_dns_name=ELB, profile_name=PROFILE, region_name=REGION, debug=DEBUG)
    # used not keyword so the script exits with status 0 when function returns True (success)
    exit(not ASG_MON.analyse_elb_for_failed_nodes(START_TIME, END_TIME))
else:
    cprint('Error - Bad start and end date/time input')
    exit(1)

我只想在单元测试中包含ASGMonitor类(在同一个文件中)。但是argparse会导致我的测试出现问题,

  

py.test --cov elb_monitoring test --cov-fail-under 80 --cov-report   术语缺失

我收到了错误,

========================================================================================== test session starts ===========================================================================================
platform darwin -- Python 2.7.12, pytest-3.0.6, py-1.4.32, pluggy-0.4.0
rootdir: /Users/achinthag/Documents/Git_Workspace/ea-gatling/elb_monitoring, inifile: 
plugins: cov-2.4.0
collected 0 items / 1 errors 


---------- coverage: platform darwin, python 2.7.12-final-0 ----------
Name                                Stmts   Miss  Cover   Missing
-----------------------------------------------------------------
src/elb_monitoring/__init__.py          0      0   100%
src/elb_monitoring/elb_monitor.py      87     65    25%   15-17, 22-26, 35-49, 53-55, 61-70, 74-90, 94-111, 129-142
-----------------------------------------------------------------
TOTAL                                  87     65    25%

================================================================================================= ERRORS =================================================================================================
_______________________________________________________________________________ ERROR collecting test/test_elb_monitor.py ________________________________________________________________________________
test/test_elb_monitor.py:3: in <module>
    from elb_monitoring.elb_monitor import *
src/elb_monitoring/elb_monitor.py:127: in <module>
    ARGS = PARSER.parse_args()
/usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py:1701: in parse_args
    args, argv = self.parse_known_args(args, namespace)
/usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py:1733: in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
/usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py:1957: in _parse_known_args
    self.error(_('argument %s is required') % name)
/usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py:2374: in error
    self.exit(2, _('%s: error: %s\n') % (self.prog, message))
/usr/local/Cellar/python/2.7.12_2/Frameworks/Python.framework/Versions/2.7/lib/python2.7/argparse.py:2362: in exit
    _sys.exit(status)
E   SystemExit: 2
-------------------------------------------------------------------------------------------- Captured stderr ---------------------------------------------------------------------------------------------
usage: py.test [-h] [--profile PROFILE] [--region REGION] --elb ELB --start
               START --end END [--debug]
py.test: error: argument --elb is required
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
======================================================================================== 1 error in 0.61 seconds =========================================================================================

如何从测试中忽略这段代码?

谢谢,

3 个答案:

答案 0 :(得分:2)

您可以将解析器参数解压缩为辅助方法,并相应地处理它。

def parse_args(args):
    PARSER = argparse.ArgumentParser(description='This script gets ELB statistics '
                                                 'and look for any failed instances')
    PARSER.add_argument('--profile', help='AWS profile - optional (only if multiple '
                                          'accounts are setup in credentials file)', default='')
    PARSER.add_argument('--region', help='AWS region. Defaults to ap-southeast-2',
                        default='ap-southeast-2')
    PARSER.add_argument('--elb', help='DNS Name of the ELB to test', required=True)
    PARSER.add_argument('--start', help='Start time of the load test (YYYY-MM-DD HH:MM:SS)',
                        required=True)
    PARSER.add_argument('--end', help='End time of the load test (YYYY-MM-DD HH:MM:SS)',
                        required=True)
    PARSER.add_argument('--debug', help='Print debugging information', action='store_true')

    parsed_args = PARSER.parse_args()
    return parsed_args

def mymethod(ARGS):
    PROFILE = ARGS.profile
    REGION = ARGS.region
    ELB = ARGS.elb
    START_TIME = format_date_string(ARGS.start)
    END_TIME = format_date_string(ARGS.end)
    DEBUG = ARGS.debug

    if (START_TIME and END_TIME) is not None and START_TIME < END_TIME:
        ASG_MON = ASGMonitor(elb_dns_name=ELB, profile_name=PROFILE, region_name=REGION, debug=DEBUG)
        # used not keyword so the script exits with status 0 when function returns True (success)
        exit(not ASG_MON.analyse_elb_for_failed_nodes(START_TIME, END_TIME))
    else:
        cprint('Error - Bad start and end date/time input')
        exit(1)

args = parse_args(sys.argv[1:])
mymethod(args)

现在,您可以测试mymethod。请注意,argsmymethodargsnamespace个对象。如果选择,您可以拆分单个元素并将它们作为参数发送到方法中。

答案 1 :(得分:1)

你已经得到了很好的答案,但到目前为止还缺少一个更通用的部分。

关键是:为了从单元测试中获益;您的生产代码需要组织成独立单元。这里的第一个指导是Single Responsibility Principle

换句话说:你不能在一个模块或一个方法/功能中做一切;相反,你努力与之相反。你创建了一个类/方法/函数(这实际上取决于你想要多少OO)隔离了参数处理。您创建一个验证已解析输入的类/方法/函数;等等。

然后分别对每个单位进行单元测试;相互隔离。

答案 2 :(得分:0)

导入模块时,会执行该模块。这就是python的工作方式。当类的代码“运行”时,实际上定义了一个类。

那么你可以定义一个类并导入它,但是跳过执行其他代码吗?是。这是一个非常常见的技巧,我之前联系过。它是这样做的:

# everything that needs to be accessed when importing
# for instance, your
class ASGMonitor(object):
    # your stuff here

# Th never put your main program code directly
# in the module, create a function for this:
def main():
    # put code that must not be run when importing here

# Step 2 : only run main if your module is run directly
# but not if it is imported:
if __name__ == '__main__':
    main()

导入模块时,__name__是其名称。当模块直接运行时,它具有特殊名称__main__,这是我们利用的一个事实。导入模块时,main函数中的代码将不会运行...例如,当您对ASGMonitor类进行单元测试时。

有关详细说明,请参阅this question