如何使用exec在代码中运行单元测试python文件

时间:2019-06-04 09:13:21

标签: python-3.x exec python-unittest

我想在我的代码中执行另一个python文件,所以我使用此代码,效果很好:

runner.py

        with open(pyfile, encoding="utf-8") as f:
            code = f.read()
        gl = globals()
        gl["__name__"] = "__main__"
        gl["__file__"] = pyfile
        exec(compile(code, pyfile, 'exec'), gl)

所以我可以用a.py执行if __name__ in __main__中的代码:

a.py


def testprint():
    print(123321)


if __name__ == "__main__":
    testprint()

runner.py中,我更改了__file____name__以确保何时执行a.py中的runner.py,就像我在使用{{ 1}}来运行它。

这似乎很好,直到我使用python a.py获得一个python文件,像这样:

b.py

unittest

当我尝试在import unittest class Test(unittest.TestCase): def setUp(self): pass def test_case1(self): pass def tearDown(self): pass if __name__ == '__main__': unittest.main() 中运行b.py时,它将失败:

runner.py

此问题是因为在单元测试中,它将使用 File "runner.py", line 72, in run_pyfile exec(compile(code, pyfile, 'exec'), gl) File "a.py", line 23, in <module> unittest.main() File "C:\Python36\Lib\unittest\main.py", line 96, in __init__ self.parseArgs(argv) File "C:\Python36\Lib\unittest\main.py", line 143, in parseArgs self.createTests() File "C:\Python36\Lib\unittest\main.py", line 147, in createTests self.test = self.testLoader.loadTestsFromModule(self.module) File "C:\Python36\Lib\unittest\loader.py", line 123, in loadTestsFromModule tests.append(self.loadTestsFromTestCase(obj)) File "C:\Python36\Lib\unittest\loader.py", line 92, in loadTestsFromTestCase loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames)) File "C:\Python36\Lib\unittest\suite.py", line 24, in __init__ for test in tests: TypeError: __init__() takes 1 positional argument but 2 were given 来初始化__main__,但是它将TestProgram用作runner.py,而不是真实的文件路径( b.py)

__main__

-

我尝试了这些方法,但是它们不起作用:

  1. 尝试使用importlib
class TestProgram(object):
    def __init__(self, module='__main__', defaultTest=None, argv=None,
                    testRunner=None, testLoader=loader.defaultTestLoader,
                    exit=True, verbosity=1, failfast=None, catchbreak=None,
                    buffer=None, warnings=None, *, tb_locals=False):
        if isinstance(module, str):
            self.module = __import__(module) # <---the result is self.module= runner.py, not b.py

当我使用a.py时,它仍然可以正常工作,但在b.py中却失败了。因为它将把一些奇怪的argv传递给unittest(不是b.py的路径,而是我的python.exe的路径和一些奇怪的数字)

  1. 尝试使用runpy
import importlib.util
spec = importlib.util.spec_from_file_location("__main__", "a.py")
foo = importlib.util.module_from_spec(spec)
spec.loader.exec_module(foo)

我可以得到一个字典和一些输出(一些版权的东西),但不是我想要的。

那么如何在代码中执行import runpy runpy.run_path("a.py") python文件?

我正在使用Python3.6 +

0 个答案:

没有答案