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

标签 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'...  ]

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

测试示例一:

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...

测试示例二:

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...

测试示例三:

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 这样的东西是在正确的轨道上,但我不确定。即使是从哪里开始的想法也将不胜感激。谢谢

最佳答案

使用 nose测试运行器将有助于 discover the tests , setup/teardown 函数和方法。

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

A timer plugin for nosetests that answers the question: how much time does every test take?


演示:

  • 假设您有一个名为 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 变量在“设置”函数和方法中设置为 1,然后在测试函数和方法中,value 被断言为1 - 这样您就可以看到设置函数的工作情况。

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

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}

关于python - 如何在不添加任何代码的情况下在 Python 中对单元测试进行基准测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24150016/

相关文章:

python - python中按钮按下和释放之间的时间?

javascript - 用 pako(javascript 中的 zlib)压缩,用 zlib(python)解压不起作用

testing - extentreports-testng-适配器 : How to generate HTML report with screenshot if test failed (cucumber, testng)

oracle - 我们如何验证 oracle 中的映射文档以确保已提供所有信息?

python - 了解 numpy.r_() 串联的语法

python - 如何在 Mac 上设置 Julia init 路径?

ruby-on-rails - ControllerTest 错误,无法找到 'id' = 的事务

c++ - 在 C++ 中将模拟对象转换为它们的抽象基类

c# - 带有单元测试的 C# IDE(如 Eclipse for Java 和 assertEquals( ... ) 等)

java - 用于 Java 的参数值覆盖 (PVC) 工具