如何在不添加任何代码的情况下在Python中对单元测试进

时间:2014-06-10 20:10:01

标签: python unit-testing testing benchmarking

我有一个Python项目,其中包含一些已经实现的测试,我想开始对它们进行基准测试,以便我可以比较代码,服务器等的性能。以类似于Nose的方式定位文件没有问题,因为无论如何我在所有测试文件的名称中都有“测试”。但是,我在尝试动态执行这些测试时遇到了一些麻烦。

截至目前,我能够运行一个脚本,该脚本将目录路径作为参数,并返回一个文件路径列表,如下所示:

def getTestFiles(directory):
    fileList = []
    print "Searching for 'test' in " + directory
    if not os.path.isdir(os.path.dirname(directory)):
        # throw error
        raise InputError(directory, "Not a valid directory")
    else:
        for root, dirs, files in os.walk(directory):
            #print files
            for f in files:
                if "test" in f and f.endswith(".py"):
                    fileList.append(os.path.join(root, f))
    return fileList

# returns a list like this:
# [  'C:/Users/myName/Desktop/example1_test.py',
#    'C:/Users/myName/Desktop/example2_test.py',
#    'C:/Users/myName/Desktop/folder1/example3_test.py',
#    'C:/Users/myName/Desktop/folder2/example4_test.py'...  ]

问题是这些文件可能有不同的语法,我正试图弄清楚如何处理。例如:

TestExampleOne:

import dummy1
import dummy2
import dummy3

class TestExampleOne(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        # set up

    def test_one(self):
        # test stuff
    def test_two(self):
        # test stuff
    def test_three(self):
        # test stuff

    # etc...

TestExampleTwo:

import dummy1
import dummy2
import dummy3

def setup(self):
    try:
        # config stuff
    except Exception as e:
        logger.exception(e)

def test_one():
    # test stuff
def test_two():
    # test stuff
def test_three():
    # test stuff

# etc...

TestExampleThree:

import dummy1
import dummy2
import dummy3

def setup(self):
    try:
        # config stuff
    except Exception as e:
        logger.exception(e)

class TestExampleTwo(unittest.TestCase):
    def test_one(self):
        # test stuff
    def test_two(self):
        # test stuff
    # etc...

class TestExampleThree(unittest.TestCase):
    def test_one(self):
        # test stuff
    def test_two(self):
        # test stuff
    # etc...

# etc...

我真的希望能够编写一个模块,在目录中搜索名称中包含“test”的每个文件,然后执行每个文件中的每个单元测试,为每个测试提供执行时间。我认为像NodeVisitor这样的东西是正确的,但我不确定。即使是从哪里开始的想法将不胜感激。感谢

1 个答案:

答案 0 :(得分:12)

使用nose测试运行器将有助于discover the tests,设置/拆卸功能和方法。

nose-timer插件有助于进行基准测试:

  

用于测试的计时器插件可以回答这个问题:多长时间   每次测试都需要吗?


演示:

  • 假设您有一个名为test_nose的包,其中包含以下脚本:

    • test1.py

      import time
      import unittest
      
      class TestExampleOne(unittest.TestCase):
          @classmethod
          def setUpClass(cls):
              cls.value = 1
      
          def test_one(self):
              time.sleep(1)
              self.assertEqual(1, self.value)
      
    • test2.py

      import time
      
      value = None
      
      def setup():
          global value
          value = 1
      
      def test_one():
          time.sleep(2)
          assert value == 1
      
    • test3.py

      import time
      import unittest
      
      value = None
      
      def setup():
          global value
          value = 1
      
      class TestExampleTwo(unittest.TestCase):
          def test_one(self):
              time.sleep(3)
              self.assertEqual(1, value)
      
      class TestExampleThree(unittest.TestCase):
          def test_one(self):
              time.sleep(4)
              self.assertEqual(1, value)
      
  • 安装nose测试跑步者:

    pip install nose
    
  • 安装nose-timer插件:

    pip install nose-timer
    
  • 运行测试:

    $ nosetests test_nose --with-timer
    ....
    test_nose.test3.TestExampleThree.test_one: 4.0003s
    test_nose.test3.TestExampleTwo.test_one: 3.0010s
    test_nose.test2.test_one: 2.0011s
    test_nose.test1.TestExampleOne.test_one: 1.0005s
    ----------------------------------------------------------------------
    Ran 4 tests in 10.006s
    
    OK
    

结果实际上很方便地突出显示: nosetests results

着色可以通过--timer-ok--timer-warning参数控制。

请注意,添加了time.sleep(n)个调用,以使手动减速以清楚地看到影响。另请注意,value变量在“setup”函数和方法中设置为1,然后在测试函数和方法中value被声明为1 - 这样你可以看到设置功能的工作。

UPD(在脚本中使用nose运行nose-timer):

from pprint import pprint
import nose
from nosetimer import plugin

plugin = plugin.TimerPlugin()
plugin.enabled = True
plugin.timer_ok = 1000
plugin.timer_warning = 2000
plugin.timer_no_color = False


nose.run(plugins=[plugin])
result = plugin._timed_tests
pprint(result)

将其保存到test.py脚本中并将目标目录传递给它:

python test.py /home/example/dir/tests --with-timer

result变量将包含:

{'test_nose.test1.TestExampleOne.test_one': 1.0009748935699463,
 'test_nose.test2.test_one': 2.0003929138183594,
 'test_nose.test3.TestExampleThree.test_one': 4.000233173370361,
 'test_nose.test3.TestExampleTwo.test_one': 3.001115083694458}