Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using py.test with compiled library code

I have a python library with the following repository structure:

repobase
 |- mylibrary
 |  |- __init__.py
 |- tests
    |- test_mylibrary.py

Up to now, running the tests could simply be done by calling py.test in the repobase directory. The import mylibrary in test_mylibrary.py then used the local code in repobase/mylibrary.

Now, I've extended the library to use compiled code. Therefore the source code at repobase/mylibrary is not functional on its own. I have to do a setup.py build. This creates repobase/build/lib.linux-x86_64-2.7/mylibrary.

Is there a reasonable way to make py.test use this directory for importing mylibrary? Given these constraints:

  1. I do not want to include any sys.path / import magic in test_mylibrary.py because this may break tests in other envrionments.

  2. I don't want to give up the possibility to run py.test from repobase. Therefore modifying the PYTHONPATH does not help because . will still be first in sys.path. And thus repobase/mylibrary would be favored over repobase/build/lib.linux-x86_64-2.7/mylibrary.

If not, what's the standard way for testing python libraries, that need building?

like image 457
Tim Hoffmann Avatar asked May 18 '16 18:05

Tim Hoffmann


People also ask

How do I run pytest on one file?

Try this: py. test test_basic.py -k test_first here test_first is a test case present in my test_basic.py file. Use the :: syntax to run a single test in a test file, e.g.: pytest tests/test_models.py::TestMyModel .


1 Answers

I think your problem is simply that py.test is not copying the built shared object to the root of your repository.

I just tried running the UT straight from the Python wiki on testing C extensions using py.test as follows:

python setup.py build
py.test test/examp_unittest.py

This failed with AssertionError: No module named examp.

However, when I follow the wiki to the letter (and run python setup.py test instead), I note that it copies the .so to the root directory (note the last line before it starts running the test):

running test
running egg_info
writing examp.egg-info/PKG-INFO
writing top-level names to examp.egg-info/top_level.txt
writing dependency_links to examp.egg-info/dependency_links.txt
reading manifest file 'examp.egg-info/SOURCES.txt'
writing manifest file 'examp.egg-info/SOURCES.txt'
running build_ext
copying build/lib.linux-x86_64-2.6/examp.so ->
runTest (test.examp_unittest.DeviceTest) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

Having run that on my system, I can now run py.test quite happily on the same code base - as shown below.

============================= test session starts ==============================
platform linux2 -- Python 2.7.3, pytest-2.9.2, py-1.4.31, pluggy-0.3.1
rootdir: /tmp/sotest, inifile: 
collected 1 items 

test/examp_unittest.py .

=========================== 1 passed in 0.01 seconds ===========================

The solution is therefore to copy your shared object to the root of your repository.

To make sure I have run the whole thing from scratch, just building the extension, copying the shared object and then running py.test. This all works as expected.

like image 130
Peter Brittain Avatar answered Oct 13 '22 14:10

Peter Brittain