我的模块中有以下代码块,
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 =========================================================================================
如何从测试中忽略这段代码?
谢谢,
答案 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
。请注意,args
到mymethod
是argsnamespace
个对象。如果选择,您可以拆分单个元素并将它们作为参数发送到方法中。
答案 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。