繁体   English   中英

随机选择功能

[英]Randomly select functions

我正在编写一个测试脚本,其中包含不同测试的不同功能。 我希望能够随机选择要运行的测试。 我已经通过以下功能实现了这一目标......

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()

您可以在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

您必须使每个函数以这种方式使用相同的参数,因此您可以以相同的方式调用它们。

如果需要为函数提供一些人类可读的名称,可以将它们与函数一起存储在字典中。 我希望你将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()))

我要在这里走出去,并建议你实际上使用一个真正的单元测试框架。 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开头)。 它还会告诉您有关哪些测试运行以及哪些测试失败等信息。

如果您将测试选择功能和测试本身包装在一个类中,则可以执行以下操作:

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的信息

除了其他选项,请查看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)()

这使您可以规范化每个测试函数的参数列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM