Python 如何在使用execfile调用的脚本中抑制语句的执行?

Python 如何在使用execfile调用的脚本中抑制语句的执行?,python,unit-testing,Python,Unit Testing,标题中提出的问题可能是一个例子,但我找不到更好的简明描述。我想通过在每个python脚本上运行execfile(filename)来测试一些python脚本,然后查看它们是否触发断言/抛出异常。到目前为止还不错,但它们中的大多数都用一条语句启动了一个用于构象的gui,比如说world.show('someString')。对于自动化测试,我不想看到gui。如何在不更改脚本本身的情况下抑制gui 编辑: 关于评论:本质上,我可以做: import unittest class TestExamp

标题中提出的问题可能是一个例子,但我找不到更好的简明描述。我想通过在每个python脚本上运行
execfile(filename)
来测试一些python脚本,然后查看它们是否触发断言/抛出异常。到目前为止还不错,但它们中的大多数都用一条语句启动了一个用于构象的gui,比如说
world.show('someString')
。对于自动化测试,我不想看到gui。如何在不更改脚本本身的情况下抑制gui

编辑: 关于评论:本质上,我可以做:

import unittest

class TestExamples(unittest.TestCase):

    def test_firstExample(self):
        execfile('example1.py')

    def test_secondExample(self):
        execfile('example2.py')

    # and many more

if __name__ == '__main__':
    unittest.main()

但是a)有两个以上,我不希望为每个示例编写测试函数。我想他们被测试只是在文件夹中。这可能通过unittests
discover
解决。和b),它们中的大多数以可视化计算结束,就像使用
matplotlib.pyplot.show()
一样。我想在不改变示例本身的情况下抑制这种可视化

我认为,正确的方法是模拟您正在使用的GUI(如您问题下面的评论所述)

但“简单方法”可能是安装虚拟帧缓冲区X服务器(例如,对于Debian,它将是软件包),并使用以下命令运行unittest脚本:

xvfb-run python unittest.py

我认为,正确的方法是模拟您正在使用的GUI(如您问题下面的评论所述)

但“简单方法”可能是安装虚拟帧缓冲区X服务器(例如,对于Debian,它将是软件包),并使用以下命令运行unittest脚本:

xvfb-run python unittest.py

这里有一个相当简单的选项:假设您有一个像这样的文件
world.py

def show(text):
    return some_gui_stuff.confirm(text)
def show(text):
    return True
import world
import fakeworld
world.show = fakeworld.show
execfile('example1.py')
…然后创建一个新文件
fakeworld.py
,如下所示

def show(text):
    return some_gui_stuff.confirm(text)
def show(text):
    return True
import world
import fakeworld
world.show = fakeworld.show
execfile('example1.py')
…然后在测试脚本中,执行如下操作

import sys
sys.modules['world'] = __import__('fakeworld')
execfile('example1.py')
import world
world.show = lambda x: True
execfile('example1.py')
example1.py
尝试导入world时,它将使用您在测试脚本顶部导入的伪版本

这意味着您必须为
world.py
中的每个函数创建一个假版本。如果有很多函数,但只有一两个需要更改,那么这样做可能会更容易

def show(text):
    return some_gui_stuff.confirm(text)
def show(text):
    return True
import world
import fakeworld
world.show = fakeworld.show
execfile('example1.py')
…或者如果
world.show
实际上是唯一的功能,您甚至可能不需要创建
fakeworld.py
-只需执行以下操作即可

import sys
sys.modules['world'] = __import__('fakeworld')
execfile('example1.py')
import world
world.show = lambda x: True
execfile('example1.py')

这里有一个相当简单的选项:假设您有一个像这样的文件
world.py

def show(text):
    return some_gui_stuff.confirm(text)
def show(text):
    return True
import world
import fakeworld
world.show = fakeworld.show
execfile('example1.py')
…然后创建一个新文件
fakeworld.py
,如下所示

def show(text):
    return some_gui_stuff.confirm(text)
def show(text):
    return True
import world
import fakeworld
world.show = fakeworld.show
execfile('example1.py')
…然后在测试脚本中,执行如下操作

import sys
sys.modules['world'] = __import__('fakeworld')
execfile('example1.py')
import world
world.show = lambda x: True
execfile('example1.py')
example1.py
尝试导入world时,它将使用您在测试脚本顶部导入的伪版本

这意味着您必须为
world.py
中的每个函数创建一个假版本。如果有很多函数,但只有一两个需要更改,那么这样做可能会更容易

def show(text):
    return some_gui_stuff.confirm(text)
def show(text):
    return True
import world
import fakeworld
world.show = fakeworld.show
execfile('example1.py')
…或者如果
world.show
实际上是唯一的功能,您甚至可能不需要创建
fakeworld.py
-只需执行以下操作即可

import sys
sys.modules['world'] = __import__('fakeworld')
execfile('example1.py')
import world
world.show = lambda x: True
execfile('example1.py')

您必须用mock替换GUI调用,但这是否可能取决于具体的GUI。尽管如此,我还是要重构脚本以使用
main()
函数。Python的unittest模块或“nose”不能为您做什么?也就是说,Martijn提出了一个很好的观点,即您需要模拟某些接口。您必须用模拟来替换GUI调用,但如果可能,则取决于确切的GUI。尽管如此,我还是要重构脚本以使用
main()
函数。Python的unittest模块或“nose”不能为您做什么?也就是说,Martijn提出了一个很好的观点,您需要模拟某些接口。我如何“模拟”GUI
xvfb
在找不到GLX的情况下中止。这只是您系统的配置问题,可能缺少libgl-*-GLX或类似的东西(取决于您使用的驱动程序),但如何解决这一问题是超级用户或askubuntu站点的一个问题。我将如何“模拟”GUI
xvfb
在找不到GLX的情况下中止。这只是系统的配置问题,可能缺少libgl-*-GLX或类似的东西(取决于您使用的驱动程序),但如何解决这一问题是超级用户或askubuntu站点的问题。