鼻子:找到测试发生器

时间:2015-02-26 10:53:52

标签: python python-3.x nose

我对鼻子测试框架有点问题。

情境:

我想用我连接到计算机的设备测试我的软件。每个设备都使用不同的配置进行测试。幸运的是,由于测试代码没有改变,我只需创建包含每个设备配置的文件。

目前,我已经在课堂上使用了普通的测试方法。这意味着在我的测试方法中,我正在加载我想要测试的设备的配置文件,然后迭代该文件中的所有配置并执行测试。不幸的是,这只能为每个设备提供一个测试结果,而不是每个配置测试设备。

所以我偶然发现了鼻子自己的测试发生器。旧的测试被修改,因此他们使用的是生成器,到目前为止一切正常,我得到了每个配置的结果,一切都很好。

我的小问题:

然而,我现在已经看到了撞墙。当使用--collect-only来显示可用的测试时,我会得到两种可能的结果之一:

  1. 加载配置文件,测试生成器根据该配置文件生成测试。这意味着nose会使用每个可能的参数配置显示测试。但是,由于配置文件可能不适合我稍后要测试的设备,因此我得到错误的结果。
  2. 我发现提供--collect-only功能的插件绕过了测试的固定装置。因此,我将配置的加载移动到一个夹具中,以避免生成的测试垃圾邮件列为可用测试列表。不幸的是,这导致没有生成测试,因此没有显示测试,因为生成器没有生成任何内容
  3. 到目前为止我尝试了什么:

    所以,我尝试了一些方法来解决这个问题:

    1. 使用标志确定--collect-only是否正在运行。当收集插件绕过灯具时,我在生成器中设置了一个标志,默认值为true,并在该生成器的灯具中将其设置为false。我希望检查标志并在--collect-only运行时忽略测试生成将解决我的问题。那时我才知道鼻子检查测试方法是否是一个生成器,并期望它提供测试方法。
    2. 由于我的第一个想法失败了,因为鼻子知道函数是一个生成器并且期望​​它至少有一个生成函数,我的第二个想法是用一组空参数调用该函数。由于我的配置存储在dict()中,我只是传递了一个空字典。幸运的是,这足以产生一个测试。然而,显然,鼻子会检查测试是否可执行,如果失败,则再次忽略测试。
    3. 第二次失败后我尝试了另一个方向。我稍微阅读了鼻子的源代码,试图弄清楚它是如何在内部工作的。那时我偶然发现了“isgenerator()”检查。所以我想,我会自己扫描我的目录进行测试,将我找到的所有静态测试添加到列表中,当我偶然发现生成器时,我不会生成测试,而是将生成器的名称添加到列表中试验。好吧,这个失败到目前为止我没有关于鼻子内部如何工作的真实经验。意思是,我找到所有的静态测试,但不是发电机。目前,这是我找到测试的代码:

      ķ     来自nose.loader导入TestLoader     来自nose.util import isgenerator     import os

      folder = os.getcwd()
      testLoader = TestLoader()
      tests = testLoader.loadTestsFromDir(folder)
      for testModule in tests:
      print ("Found test module %s" % testModule.id())
      for testFile in testModule:
          print ("Found test file %s" % testFile.id())
          for test in testFile:
              print("Found test %s" % test.id())
              if not isgenerator(test):
                  for x in test:
                      print("Found x %s" % x.id())
              else:
                  print ("GENERATOR FOUND")
      
    4. 我没有想过要尝试的想法。也许我遇到了某种X-Y问题,或者我只是盲目地看到明显的解决方案。

1 个答案:

答案 0 :(得分:0)

好的,所以,在稍微跳过调试器之后,我想出了以下解决方案并将其作为答案发布在此处,因为它似乎有效。然而,它看起来既不优雅,也不知道它究竟有多稳定。

foundTests = dict()
    for testPackage in loadedTests:
        #print ("Found test module %s" % testModule.id())
        for testModule in testPackage:
            #print ("Found test file %s" % testFile.id())
            for testCase in testModule:
                #print("Found test %s" % test.id())
                    for test in testCase:
                        if isinstance(test, Test):
                            key, value = readTestInformation(test)
                            foundTests[key] = value

                        elif hasattr(test, "test_generator"):
                            factory = test.factory
                            for suite in factory.suites:
                                try:
                                    if inspect.ismethod(suite):
                                        key, value = readGeneratedTestInformation(suite)
                                        foundTests[key]=value
                                except:
                                    pass

这个函数简单地遍历找到的所有包,在它们内部遍历所有找到的模块,在迭代所有类的模块内部,最后迭代一个类中的所有测试方法。

如果测试方法是一个生成器,它似乎具有“test_generator”属性,所以我检查它然后遍历工厂内的所有套件,每次检查它是否是一个函数。如果是,我得到了测试生成器功能。

所以,如果有人想出更好的解决方案,我会很高兴看到它。这种方式看起来很糟糕。