【问题标题】:Unittest for setup.pysetup.py 的单元测试
【发布时间】:2018-05-07 10:11:39
【问题描述】:

我有以下 Python 应用程序:

.
├── application
│   ├── __init__.py
│   ├── code
│   │   ├── ...
│   └── test
│       ├── ...
└── setup.py

setup.py 可用于安装application。此外,setup.py 可用于运行单元测试,它们位于application/test

现在,我想在application/test 中创建一个单元测试来尝试安装应用程序,如果无法安装则失败。

我对这样一个单元测试的代码是:

import unittest
import os


class TestInstallation(unittest.TestCase):

    def test_installation(self):
        os.system('virtualenv --python=python3 ENV')
        os.system('source ENV/bin/activate')

        # install application
        os.system('python setup.py install')
        self.assertTrue('application' in os.system('pip list'))

        os.system('deactivate')
        os.system('rm -rf ENV')

但是,这不起作用,因为每个命令都是单独执行的。 (即执行命令启动虚拟环境后,立即退出该环境)。

这就引出了一个问题,什么是测试应用程序是否可以成功安装的好方法。这可以在 Python 中完成,还是仅使用 shell 命令完成?

提前致谢,

帕特里克

【问题讨论】:

    标签: python python-unittest


    【解决方案1】:

    venv 的激活只不过是在 shell 中调整 PATHPYTHONHOME,因此您可以使用来自该 venv 的正确可执行文件。如果您明确指定可执行文件的路径,则无需运行ENV/bin/activate。比如命令序列

    $ virtualenv ENV --python=python3
    $ source ENV/bin/activate
    $ python setup.py install
    $ pip list
    $ deactivate
    

    等价于序列

    $ virtualenv ENV --python=python3
    $ ENV/bin/python setup.py install
    $ ENV/bin/pip list
    

    您可以在测试中使用它。此外,我会:

    • 在测试类设置/拆卸中移动ENV的创建和删除,以便实际测试噪音更小。此外,tearDown 将确保您的 venv 被删除,即使 test_installation 失败;
    • os.system 的用法替换为subprocess,因为它会返回一个更好的结果对象以供检查;
    • 使用stdout=subprocess.PIPE 运行命令以捕获打印的行(此外,它们不会使测试输出混乱);
    • 使用pip list --format=freeze,以便检查包名称和版本。

    但是,这都是可选的,您不必遵循此示例。

    这就是我调整测试的方式:

    import shutil
    import subprocess
    import unittest
    
    
    class TestInstallation(unittest.TestCase):
    
        def setUp(self):
            subprocess.run(['virtualenv', 'ENV', '--python=python3'], 
                           stdout=subprocess.PIPE)
            self.python = 'ENV/bin/python3'
            self.pip = 'ENV/bin/pip3'
    
        def tearDown(self):
            shutil.rmtree('ENV')
    
        def test_installation(self):
            subprocess.run([self.python, 'setup.py', 'install'], 
                           stdout=subprocess.PIPE)
            # check the installation succeeded (process exited with a 0)
            self.assertEqual(result.returncode, 0)
    
            result = subprocess.run([self.pip, 'list', '--format=freeze'],
                                    stdout=subprocess.PIPE,
                                    universal_newlines=True)
            self.assertIn('application==0.1', result.stdout.split())
    

    【讨论】:

      猜你喜欢
      • 2011-09-04
      • 1970-01-01
      • 2018-05-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-27
      • 1970-01-01
      相关资源
      最近更新 更多