7

At work, we are considering configuring a local pypi repository for internal software deployment. Deploying with "pip install" would be convenient, but I am concerned that unit tests should be executed after adding a new package to ensure proper installation. I had always assumed pip was doing this, but I see nothing related to testing in the pip documentation.

Fuligo septica
  • 117
  • 1
  • 7
  • 4
    `pip` has nothing to do with testing. It is simply a package manager. What do you expect it to test? – DeepSpace Jan 05 '19 at 19:23
  • 2
    @DeepSpace Fuligo septica is a new user and while he misunderstood what pip can do, his question's intent was specific and clear – ycx Jan 05 '19 at 20:07
  • @DeepSpace Other languages bundle the testing in with package installation. For example, Perl's package managers execute the unit tests when they retrieve and install modules from the CPAN. – Fuligo septica Jan 05 '19 at 22:02
  • @ycx Fuligo septica is not a new user. 2 years at the site and a few questions. – phd Jan 05 '19 at 22:54
  • 2
    I tried to word this question in a way that would not invite personal opinion, but I may not have clearly communicated the problem. The goal is to reliably deploy local Python packages. Past experience has been with a utility that retrieves, installs, and tests the packages. pip feels familiar in this respect, but it seems to exclude the testing. Perhaps I am missing something or there is some other complimentary tool used for Python? Perhaps this is a due to a difference in programming philosophy so that unit testing of a newly installed package is assumed unnecessary? – Fuligo septica Jan 05 '19 at 23:16
  • 1
    What you can do is include the tests in the dist file, so the user can run the tests after installing your package. This is what e.g. `numpy` or `pandas` do. Running the tests during the installation phase is often not possible per se, makes little sense in general and would only increase the installation time. If you are concerned about the code's behaviour after the installation, you should prepare some testing environments and configure regular testing with them as part of the CI pipeline. – hoefling Jan 06 '19 at 00:23
  • 1
    @hoefling Thanks. Bundling the tests with the distribution file so that they are distributed with pip, but executed during a follow-up step would be a good solution. – Fuligo septica Jan 06 '19 at 04:32

2 Answers2

2

You can pass a parameter to setup.py via pip:

--install-option Extra arguments to be supplied to the setup.py install command (use like –install-option=”–install-scripts=/usr/local/bin”). Use multiple –install-option options to pass multiple options to setup.py install. If you are using an option with a directory path, be sure to use absolute path.

pip install --install-option test

will issue

setup.py test

then You need setup.cfg in the same directory as setup.py:

# setup.cfg
[aliases]
test=pytest

sample setup.py:

# setup.py
"""Setuptools entry point."""
import codecs
import os

try:
    from setuptools import setup
except ImportError:
    from distutils.core import setup


CLASSIFIERS = [
    'Development Status :: 5 - Production/Stable',
    'Intended Audience :: Developers',
    'License :: OSI Approved :: MIT License',
    'Natural Language :: English',
    'Operating System :: OS Independent',
    'Programming Language :: Python',
    'Topic :: Software Development :: Libraries :: Python Modules'
]

dirname = os.path.dirname(__file__)

long_description = (
    codecs.open(os.path.join(dirname, 'README.rst'), encoding='utf-8').read() + '\n' +
    codecs.open(os.path.join(dirname, 'CHANGES.rst'), encoding='utf-8').read()
)

setup(
    name='your_package',
    version='0.0.1',
    description='some short description',
    long_description=long_description,
    long_description_content_type='text/x-rst',
    author='Your Name',
    author_email='your@email.com',
    url='https://github.com/your_account/your_package',
    packages=['your_package'],
    install_requires=['pytest',
                      'typing',
                      'your_package'],
    classifiers=CLASSIFIERS,
    setup_requires=['pytest-runner'],
    tests_require=['pytest'])
bitranox
  • 1,664
  • 13
  • 21
  • This method doesn't work when installing from a distribution: `pip install /tmp/mymodule.tar.gz --install-option test`. Is it possible to do in this context? – DannyDannyDanny Aug 12 '21 at 11:56
  • The use of [pytest-runner now deprecated](https://pypi.org/project/pytest-runner/) – Psionman Nov 29 '21 at 16:42
-2

There is a way:

import pkg_resources as pkr
packages = [(v.project_name, v.version) for v in pkr.working_set]
print (packages)
# [('zope.interface', '4.5.0'), ..., ('absl-py', '0.2.2')]

This will give you a list of tuples which you can then filter and search through to find whether they match with what you require.
Simple examples:

if packages[-1] == ('absl-py', '0.2.2'):
    print ('aye')
#aye

package_dict = dict(packages) 
#this converts the packages into a dictionary format
#However, you can simply open a file via
#with open('packages.txt', 'r') as f:
#process your packages into a dict object here, then use the below code    

for i,v in packages:
    if package_dict[i] == v:
        print ('yay') #will print yay multiple times
ycx
  • 3,155
  • 3
  • 14
  • 26
  • 1
    I believe you have provided a way to locate the test modules for a given package. This might be a route to explore. Thanks for the suggestion. I was hoping someone would reveal the best practice for deploying and testing modules using pip or explain why my concern to execute the unit tests following installation is unfounded. – Fuligo septica Jan 07 '19 at 01:16
  • @Fuligoseptica Thanks for the commendation, is your original question about checking whether the packages and their version numbers have been installed in the environment? Wanted to know because I got downvoted pretty hard for an answer I thought would help people construct their own unit tests in this aspect. Would appreciate if you could let me know. – ycx Jan 07 '19 at 02:48
  • @ycx My original question was about about executing unit tests during package installation. The question was motivated by a desire to ensure that a package works correctly in the environment in which it has been installed. Other package managers execute unit tests as part of the installation. For some reason, pip works differently. That's an observation, not a judgement. I simply want to identify a robust way to deploy packages. I upvoted your answer for the insight you gave. – Fuligo septica Jan 07 '19 at 05:33
  • @Fuligoseptica I understand now. Thanks! Is it possible for you to show me an example or website link of a package manager and the type of unit tests it runs during package installation? I am pretty new to this, generally non-python stuff, and would like to learn something in this aspect. – ycx Jan 07 '19 at 06:26
  • 2
    @ycx cpanminus (https://metacpan.org/pod/distribution/App-cpanminus/bin/cpanm) is to Perl what pip is to Python. Both fetch and install packages from a central repository. However, with cpanminus testing is performed by default (there is a notest option to disable it). For someone who transitioned to Python from Perl, it feels a little dangerous not to have the package's test be executed during installation, hence my question. I'm guessing there is some difference in Python's package management that makes test execution unnecessary. – Fuligo septica Jan 07 '19 at 23:09