我正在编写一个测试脚本,其中包含不同测试的不同功能。我希望能够随机选择要运行的测试。我已经通过以下功能实现了这一目标......
test_options = ("AOI", "RMODE")
def random_test(test_options, control_obj):
ran_test_opt = choice(test_options)
if ran_test_opt.upper() == "AOI":
logging.debug("Random AOI Test selected")
random_aoi()
elif ran_test_opt.upper() == "RMODE":
logging.debug("Random Read Mode Test selected")
random_read_mode(control_obj)
但是,我希望在不必修改随机测试选择功能的情况下添加更多测试功能。我想要做的就是在脚本中添加测试功能。另外,我还想要一种方法来选择哪个测试将包含在随机选择中。这就是变量test_options的作用。我将如何改变我的随机生成函数来实现这一目标?
编辑:我解决了所有测试可能需要不同的参数,将它们全部包含在测试类中。所有参数都将传递给init,测试函数将使用“self”引用它们。当他们需要一个特定的变量时......class Test(object):
"""A class that contains and keeps track of the tests and the different modes"""
def __init__(self, parser, control_obj):
self.parser = parser
self.control_obj = control_obj
def random_test(self):
test_options = []
for name in self.parser.options('Test_Selection'):
if self.parser.getboolean('Test_Selection', name):
test_options.append(name.lower())
ran_test_opt = choice(test_options)
ran_test_func = getattr(self, ran_test_opt)
ran_test_func()
#### TESTS ####
def random_aoi(self):
logging.info("Random AOI Test")
self.control_obj.random_readout_size()
def random_read_mode(self):
logging.info("Random Readout Mode Test")
self.control_obj.random_read_mode()
答案 0 :(得分:3)
您可以在python中创建一个函数列表,您可以调用它们:
test_options = (random_aoi, random_read_mode)
def random_test(test_options, control_obj):
ran_test_opt = choice(test_options)
ran_test_opt(control_obj) # call the randomly selected function
你必须让每个函数以这种方式使用相同的参数,所以你可以用同样的方式调用它们。
答案 1 :(得分:3)
如果您需要为这些函数提供一些人类可读的名称,您可以将它们与函数一起存储在字典中。我希望你将control_obj
传递给每个函数。
编辑:这似乎与@Ikke的答案相同,但使用字典而不是函数列表。
>>> test_options = {'AOI': random_aoi, 'RMODE': random_read_mode}
>>> def random_test(test_options, control_obj):
... ran_test_opt = test_options[choice(test_options.keys())]
... ran_test_opt(control_obj)
或者您可以从test_options.values()
中选择一项测试。对list()
的'额外'调用是因为在python 3.x中,dict.values()
返回一个迭代器。
>>> ran_test_opt = choice(list(test_options.values()))
答案 2 :(得分:1)
我会在这里走出去,并建议你实际使用一个真正的单元测试框架。 Python提供了一个 - 方便的名称unittest
。要随机运行测试,它会像这样工作:
import unittest
class Tests(unittest.TestCase):
def test_something(self):
...
def test_something_else(self):
...
if __name__ == '__main__':
tests = list(unittest.defaultTestLoader.loadTestsFromTestCase(Tests))
import random
# repeat as many times as you would like...
test = random.choice(tests)
print(test)
test()
要运行所有测试,请使用:unittest.main()
- 我想您可以通过简单的命令行开关来切换。
这具有巨大的优势,您无需保持与测试本身分开的最新测试列表。如果要添加新测试,只需添加一个,unittest
将找到它(只要方法名称以test
开头)。它还会告诉您有关哪些测试运行以及哪些测试失败等信息。
答案 3 :(得分:0)
如果您将测试选择功能和测试本身包装在一个类中,您可以执行以下操作:
from random import choice
class Test(object):
""" Randomly selects a test from the methods with 'random' in the name """
def random_aoi(self):
print 'aoi'
def random_read_mode(self):
print 'read_mode'
def random_text(self):
print 'test'
# add as many tests as needed here
# important that this function doesn't have 'random' in the name(in my code anyway)
def run_test(self): # you can add control_obj to the args
methods = [m for m in dir(self) if callable(getattr(self, m)) and 'random' in m]
test = choice(methods)
getattr(self, test)() # you would add control_obj between these parens also
app = Test()
app.run_test()
这样可以轻松添加测试而无需更改任何其他代码。 以下是getattr
的信息答案 4 :(得分:0)
除了其他选项,请查看functools.partial
。它允许为函数创建闭包:
from functools import partial
def test_function_a(x,y):
return x+y
def other_function(b, c=5, d=4):
return (b*c)**d
def my_test_functions(some_input):
funclist = (partial(test_function_a, x=some_input, y=4),
partial(other_function, b=some_input, d=9))
return funclist
random.choice(funclist)()
这使您可以规范化每个测试函数的参数列表。