setup.py的Unittest

时间:2018-05-07 10:11:40

标签: python python-unittest

我有以下Python应用程序:

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

setup.py可用于安装application。此外,setup.py可用于运行application/test

中的单元测试

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

我的代码测试代码是:

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命令?

提前致谢,

帕特里克

1 个答案:

答案 0 :(得分:0)

激活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将确保即使test_installation失败也会删除您的venv;
  • 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())