Merge pull request #1797 from nicoddemus/merge-master-into-features

Merge master into features
This commit is contained in:
Bruno Oliveira 2016-08-06 18:48:40 -03:00 committed by GitHub
commit 4ab2e57ebd
22 changed files with 183 additions and 186 deletions

View File

@ -25,7 +25,7 @@ env:
- TESTENV=py35-trial - TESTENV=py35-trial
- TESTENV=py27-nobyte - TESTENV=py27-nobyte
- TESTENV=doctesting - TESTENV=doctesting
- TESTENV=py27-cxfreeze - TESTENV=freeze
script: tox --recreate -e $TESTENV script: tox --recreate -e $TESTENV

View File

@ -254,6 +254,15 @@ time or change existing behaviors in order to make them less surprising/more use
* ``optparse`` backward compatibility supports float/complex types (`#457`_). * ``optparse`` backward compatibility supports float/complex types (`#457`_).
* Refined logic for determining the ``rootdir``, considering only valid
paths which fixes a number of issues: `#1594`_, `#1435`_ and `#1471`_.
Thanks to `@blueyed`_ and `@davehunt`_ for the PR.
* Always include full assertion explanation. The previous behaviour was hiding
sub-expressions that happened to be False, assuming this was redundant information.
Thanks `@bagerard`_ for reporting (`#1503`_). Thanks to `@davehunt`_ and
`@tomviner`_ for PR.
* Renamed the pytest ``pdb`` module (plugin) into ``debugging``. * Renamed the pytest ``pdb`` module (plugin) into ``debugging``.
* Better message in case of not using parametrized variable (see `#1539`_). * Better message in case of not using parametrized variable (see `#1539`_).
@ -322,11 +331,13 @@ time or change existing behaviors in order to make them less surprising/more use
.. _#1421: https://github.com/pytest-dev/pytest/issues/1421 .. _#1421: https://github.com/pytest-dev/pytest/issues/1421
.. _#1426: https://github.com/pytest-dev/pytest/issues/1426 .. _#1426: https://github.com/pytest-dev/pytest/issues/1426
.. _#1428: https://github.com/pytest-dev/pytest/pull/1428 .. _#1428: https://github.com/pytest-dev/pytest/pull/1428
.. _#1435: https://github.com/pytest-dev/pytest/issues/1435
.. _#1441: https://github.com/pytest-dev/pytest/pull/1441 .. _#1441: https://github.com/pytest-dev/pytest/pull/1441
.. _#1444: https://github.com/pytest-dev/pytest/pull/1444 .. _#1444: https://github.com/pytest-dev/pytest/pull/1444
.. _#1454: https://github.com/pytest-dev/pytest/pull/1454 .. _#1454: https://github.com/pytest-dev/pytest/pull/1454
.. _#1461: https://github.com/pytest-dev/pytest/pull/1461 .. _#1461: https://github.com/pytest-dev/pytest/pull/1461
.. _#1468: https://github.com/pytest-dev/pytest/pull/1468 .. _#1468: https://github.com/pytest-dev/pytest/pull/1468
.. _#1471: https://github.com/pytest-dev/pytest/issues/1471
.. _#1474: https://github.com/pytest-dev/pytest/pull/1474 .. _#1474: https://github.com/pytest-dev/pytest/pull/1474
.. _#1479: https://github.com/pytest-dev/pytest/issues/1479 .. _#1479: https://github.com/pytest-dev/pytest/issues/1479
.. _#1502: https://github.com/pytest-dev/pytest/pull/1502 .. _#1502: https://github.com/pytest-dev/pytest/pull/1502
@ -341,6 +352,7 @@ time or change existing behaviors in order to make them less surprising/more use
.. _#1562: https://github.com/pytest-dev/pytest/issues/1562 .. _#1562: https://github.com/pytest-dev/pytest/issues/1562
.. _#1579: https://github.com/pytest-dev/pytest/issues/1579 .. _#1579: https://github.com/pytest-dev/pytest/issues/1579
.. _#1580: https://github.com/pytest-dev/pytest/pull/1580 .. _#1580: https://github.com/pytest-dev/pytest/pull/1580
.. _#1594: https://github.com/pytest-dev/pytest/issues/1594
.. _#1597: https://github.com/pytest-dev/pytest/pull/1597 .. _#1597: https://github.com/pytest-dev/pytest/pull/1597
.. _#1605: https://github.com/pytest-dev/pytest/issues/1605 .. _#1605: https://github.com/pytest-dev/pytest/issues/1605
.. _#1616: https://github.com/pytest-dev/pytest/pull/1616 .. _#1616: https://github.com/pytest-dev/pytest/pull/1616
@ -367,6 +379,7 @@ time or change existing behaviors in order to make them less surprising/more use
.. _#717: https://github.com/pytest-dev/pytest/issues/717 .. _#717: https://github.com/pytest-dev/pytest/issues/717
.. _#925: https://github.com/pytest-dev/pytest/issues/925 .. _#925: https://github.com/pytest-dev/pytest/issues/925
.. _@anntzer: https://github.com/anntzer .. _@anntzer: https://github.com/anntzer
.. _@bagerard: https://github.com/bagerard .. _@bagerard: https://github.com/bagerard
.. _@BeyondEvil: https://github.com/BeyondEvil .. _@BeyondEvil: https://github.com/BeyondEvil
@ -397,8 +410,8 @@ time or change existing behaviors in order to make them less surprising/more use
.. _@RedBeardCode: https://github.com/RedBeardCode .. _@RedBeardCode: https://github.com/RedBeardCode
.. _@sallner: https://github.com/sallner .. _@sallner: https://github.com/sallner
.. _@sober7: https://github.com/sober7 .. _@sober7: https://github.com/sober7
.. _@suzaku: https://github.com/suzaku
.. _@Stranger6667: https://github.com/Stranger6667 .. _@Stranger6667: https://github.com/Stranger6667
.. _@suzaku: https://github.com/suzaku
.. _@tareqalayan: https://github.com/tareqalayan .. _@tareqalayan: https://github.com/tareqalayan
.. _@taschini: https://github.com/taschini .. _@taschini: https://github.com/taschini
.. _@tramwaj29: https://github.com/tramwaj29 .. _@tramwaj29: https://github.com/tramwaj29

View File

@ -1,5 +1,5 @@
.. image:: http://pytest.org/latest/_static/pytest1.png .. image:: http://docs.pytest.org/en/latest/_static/pytest1.png
:target: http://pytest.org :target: http://docs.pytest.org
:align: center :align: center
:alt: pytest :alt: pytest
@ -51,33 +51,34 @@ To execute it::
test_sample.py:5: AssertionError test_sample.py:5: AssertionError
======= 1 failed in 0.12 seconds ======== ======= 1 failed in 0.12 seconds ========
Due to ``pytest``'s detailed assertion introspection, only plain ``assert`` statements are used. See `getting-started <http://pytest.org/latest/getting-started.html#our-first-test-run>`_ for more examples.
Due to ``py.test``'s detailed assertion introspection, only plain ``assert`` statements are used. See `getting-started <http://docs.pytest.org/en/latest/getting-started.html#our-first-test-run>`_ for more examples.
Features Features
-------- --------
- Detailed info on failing `assert statements <http://pytest.org/latest/assert.html>`_ (no need to remember ``self.assert*`` names); - Detailed info on failing `assert statements <http://docs.pytest.org/en/latest/assert.html>`_ (no need to remember ``self.assert*`` names);
- `Auto-discovery - `Auto-discovery
<http://pytest.org/latest/goodpractices.html#python-test-discovery>`_ <http://docs.pytest.org/en/latest/goodpractices.html#python-test-discovery>`_
of test modules and functions; of test modules and functions;
- `Modular fixtures <http://pytest.org/latest/fixture.html>`_ for - `Modular fixtures <http://docs.pytest.org/en/latest/fixture.html>`_ for
managing small or parametrized long-lived test resources; managing small or parametrized long-lived test resources;
- Can run `unittest <http://pytest.org/latest/unittest.html>`_ (or trial), - Can run `unittest <http://docs.pytest.org/en/latest/unittest.html>`_ (or trial),
`nose <http://pytest.org/latest/nose.html>`_ test suites out of the box; `nose <http://docs.pytest.org/en/latest/nose.html>`_ test suites out of the box;
- Python2.6+, Python3.3+, PyPy-2.3, Jython-2.5 (untested); - Python2.6+, Python3.3+, PyPy-2.3, Jython-2.5 (untested);
- Rich plugin architecture, with over 150+ `external plugins <http://pytest.org/latest/plugins.html#installing-external-plugins-searching>`_ and thriving community; - Rich plugin architecture, with over 150+ `external plugins <http://docs.pytest.org/en/latest/plugins.html#installing-external-plugins-searching>`_ and thriving community;
Documentation Documentation
------------- -------------
For full documentation, including installation, tutorials and PDF documents, please see http://pytest.org. For full documentation, including installation, tutorials and PDF documents, please see http://docs.pytest.org.
Bugs/Requests Bugs/Requests
@ -89,7 +90,7 @@ Please use the `GitHub issue tracker <https://github.com/pytest-dev/pytest/issue
Changelog Changelog
--------- ---------
Consult the `Changelog <http://pytest.org/latest/changelog.html>`_ page for fixes and enhancements of each version. Consult the `Changelog <http://docs.pytest.org/en/latest/changelog.html>`_ page for fixes and enhancements of each version.
License License

View File

@ -1181,6 +1181,8 @@ def get_common_ancestor(args):
if str(arg)[0] == "-": if str(arg)[0] == "-":
continue continue
p = py.path.local(arg) p = py.path.local(arg)
if not p.exists():
continue
if common_ancestor is None: if common_ancestor is None:
common_ancestor = p common_ancestor = p
else: else:
@ -1194,21 +1196,28 @@ def get_common_ancestor(args):
common_ancestor = shared common_ancestor = shared
if common_ancestor is None: if common_ancestor is None:
common_ancestor = py.path.local() common_ancestor = py.path.local()
elif not common_ancestor.isdir(): elif common_ancestor.isfile():
common_ancestor = common_ancestor.dirpath() common_ancestor = common_ancestor.dirpath()
return common_ancestor return common_ancestor
def get_dirs_from_args(args):
return [d for d in (py.path.local(x) for x in args
if not str(x).startswith("-"))
if d.exists()]
def determine_setup(inifile, args): def determine_setup(inifile, args):
dirs = get_dirs_from_args(args)
if inifile: if inifile:
iniconfig = py.iniconfig.IniConfig(inifile) iniconfig = py.iniconfig.IniConfig(inifile)
try: try:
inicfg = iniconfig["pytest"] inicfg = iniconfig["pytest"]
except KeyError: except KeyError:
inicfg = None inicfg = None
rootdir = get_common_ancestor(args) rootdir = get_common_ancestor(dirs)
else: else:
ancestor = get_common_ancestor(args) ancestor = get_common_ancestor(dirs)
rootdir, inifile, inicfg = getcfg( rootdir, inifile, inicfg = getcfg(
[ancestor], ["pytest.ini", "tox.ini", "setup.cfg"]) [ancestor], ["pytest.ini", "tox.ini", "setup.cfg"])
if rootdir is None: if rootdir is None:
@ -1216,6 +1225,12 @@ def determine_setup(inifile, args):
if rootdir.join("setup.py").exists(): if rootdir.join("setup.py").exists():
break break
else: else:
rootdir, inifile, inicfg = getcfg(
dirs, ["pytest.ini", "tox.ini", "setup.cfg"])
if rootdir is None:
rootdir = get_common_ancestor([py.path.local(), ancestor])
is_fs_root = os.path.splitdrive(str(rootdir))[1] == os.sep
if is_fs_root:
rootdir = ancestor rootdir = ancestor
return rootdir, inifile, inicfg or {} return rootdir, inifile, inicfg or {}

View File

@ -10,7 +10,7 @@ environment:
# builds timing out in AppVeyor # builds timing out in AppVeyor
- TOXENV: "linting,py26,py27,py33,py34,py35,pypy" - TOXENV: "linting,py26,py27,py33,py34,py35,pypy"
- TOXENV: "py27-pexpect,py27-xdist,py27-trial,py35-pexpect,py35-xdist,py35-trial" - TOXENV: "py27-pexpect,py27-xdist,py27-trial,py35-pexpect,py35-xdist,py35-trial"
- TOXENV: "py27-nobyte,doctesting,py27-cxfreeze" - TOXENV: "py27-nobyte,doctesting,freeze"
install: install:
- echo Installed Pythons - echo Installed Pythons

View File

@ -3,7 +3,7 @@
Full pytest documentation Full pytest documentation
=========================== ===========================
`Download latest version as PDF <pytest.pdf>`_ `Download latest version as PDF <https://media.readthedocs.org/pdf/pytest/latest/pytest.pdf>`_
.. `Download latest version as EPUB <http://media.readthedocs.org/epub/pytest/latest/pytest.epub>`_ .. `Download latest version as EPUB <http://media.readthedocs.org/epub/pytest/latest/pytest.epub>`_

View File

@ -29,25 +29,29 @@ project/testrun-specific information.
Here is the algorithm which finds the rootdir from ``args``: Here is the algorithm which finds the rootdir from ``args``:
- determine the common ancestor directory for the specified ``args``. - determine the common ancestor directory for the specified ``args`` that are
recognised as paths that exist in the file system. If no such paths are
found, the common ancestor directory is set to the current working directory.
- look for ``pytest.ini``, ``tox.ini`` and ``setup.cfg`` files in the - look for ``pytest.ini``, ``tox.ini`` and ``setup.cfg`` files in the ancestor
ancestor directory and upwards. If one is matched, it becomes the directory and upwards. If one is matched, it becomes the ini-file and its
ini-file and its directory becomes the rootdir. An existing directory becomes the rootdir.
``pytest.ini`` file will always be considered a match whereas
``tox.ini`` and ``setup.cfg`` will only match if they contain
a ``[pytest]`` section.
- if no ini-file was found, look for ``setup.py`` upwards from - if no ini-file was found, look for ``setup.py`` upwards from the common
the common ancestor directory to determine the ``rootdir``. ancestor directory to determine the ``rootdir``.
- if no ini-file and no ``setup.py`` was found, use the already - if no ``setup.py`` was found, look for ``pytest.ini``, ``tox.ini`` and
determined common ancestor as root directory. This allows to ``setup.cfg`` in each of the specified ``args`` and upwards. If one is
work with pytest in structures that are not part of a package matched, it becomes the ini-file and its directory becomes the rootdir.
and don't have any particular ini-file configuration.
Note that options from multiple ini-files candidates are never merged, - if no ini-file was found, use the already determined common ancestor as root
the first one wins (``pytest.ini`` always wins even if it does not directory. This allows to work with pytest in structures that are not part of
a package and don't have any particular ini-file configuration.
Note that an existing ``pytest.ini`` file will always be considered a match,
whereas ``tox.ini`` and ``setup.cfg`` will only match if they contain a
``[pytest]`` section. Options from multiple ini-files candidates are never
merged - the first one wins (``pytest.ini`` always wins, even if it does not
contain a ``[pytest]`` section). contain a ``[pytest]`` section).
The ``config`` object will subsequently carry these attributes: The ``config`` object will subsequently carry these attributes:

View File

@ -720,40 +720,29 @@ and run it::
You'll see that the fixture finalizers could use the precise reporting You'll see that the fixture finalizers could use the precise reporting
information. information.
Integrating pytest runner and cx_freeze Freezing pytest
----------------------------------------------------------- ---------------
If you freeze your application using a tool like If you freeze your application using a tool like
`cx_freeze <https://cx-freeze.readthedocs.io>`_ in order to distribute it `PyInstaller <https://pyinstaller.readthedocs.io>`_
to your end-users, it is a good idea to also package your test runner and run in order to distribute it to your end-users, it is a good idea to also package
your tests using the frozen application. your test runner and run your tests using the frozen application. This way packaging
errors such as dependencies not being included into the executable can be detected early
while also allowing you to send test files to users so they can run them in their
machines, which can be useful to obtain more information about a hard to reproduce bug.
This way packaging errors such as dependencies not being Fortunately recent ``PyInstaller`` releases already have a custom hook
included into the executable can be detected early while also allowing you to for pytest, but if you are using another tool to freeze executables
send test files to users so they can run them in their machines, which can be such as ``cx_freeze`` or ``py2exe``, you can use ``pytest.freeze_includes()``
invaluable to obtain more information about a hard to reproduce bug. to obtain the full list of internal pytest modules. How to configure the tools
to find the internal modules varies from tool to tool, however.
Unfortunately ``cx_freeze`` can't discover them Instead of freezing the pytest runner as a separate executable, you can make
automatically because of ``pytest``'s use of dynamic module loading, so you your frozen program work as the pytest runner by some clever
must declare them explicitly by using ``pytest.freeze_includes()``:: argument handling during program startup. This allows you to
have a single executable, which is usually more convenient.
# contents of setup.py .. code-block:: python
from cx_Freeze import setup, Executable
import pytest
setup(
name="app_main",
executables=[Executable("app_main.py")],
options={"build_exe":
{
'includes': pytest.freeze_includes()}
},
# ... other options
)
If you don't want to ship a different executable just in order to run your tests,
you can make your program check for a certain flag and pass control
over to ``pytest`` instead. For example::
# contents of app_main.py # contents of app_main.py
import sys import sys
@ -766,7 +755,8 @@ over to ``pytest`` instead. For example::
# by your argument-parsing library of choice as usual # by your argument-parsing library of choice as usual
... ...
This makes it convenient to execute your tests from within your frozen
application, using standard ``pytest`` command-line options:: This allows you to execute tests using the frozen
application with standard ``pytest`` command-line options::
./app_main --pytest --verbose --tb=long --junitxml=results.xml test-suite/ ./app_main --pytest --verbose --tb=long --junitxml=results.xml test-suite/

View File

@ -11,7 +11,7 @@ Installation and Getting Started
`colorama (Windows) <http://pypi.python.org/pypi/colorama>`_, `colorama (Windows) <http://pypi.python.org/pypi/colorama>`_,
`argparse (py26) <http://pypi.python.org/pypi/argparse>`_. `argparse (py26) <http://pypi.python.org/pypi/argparse>`_.
**documentation as PDF**: `download latest <http://pytest.org/latest/pytest.pdf>`_ **documentation as PDF**: `download latest <https://media.readthedocs.org/pdf/pytest/latest/pytest.pdf>`_
.. _`getstarted`: .. _`getstarted`:
.. _installation: .. _installation:

View File

@ -10,7 +10,7 @@ pytest: helps you write better programs
- free and open source software, distributed under the terms of the :ref:`MIT license <license>` - free and open source software, distributed under the terms of the :ref:`MIT license <license>`
- **well tested** with more than a thousand tests against itself - **well tested** with more than a thousand tests against itself
- **strict backward compatibility policy** for safe pytest upgrades - **strict backward compatibility policy** for safe pytest upgrades
- :ref:`comprehensive online <toc>` and `PDF documentation <pytest.pdf>`_ - :ref:`comprehensive online <toc>` and `PDF documentation <https://media.readthedocs.org/pdf/pytest/latest/pytest.pdf>`_
- many :ref:`third party plugins <extplugins>` and :ref:`builtin helpers <pytest helpers>`, - many :ref:`third party plugins <extplugins>` and :ref:`builtin helpers <pytest helpers>`,
- used in :ref:`many small and large projects and organisations <projects>` - used in :ref:`many small and large projects and organisations <projects>`
- comes with many :ref:`tested examples <examples>` - comes with many :ref:`tested examples <examples>`

View File

@ -1,64 +0,0 @@
"""
Installs cx_freeze from source, but first patching
setup.py as described here:
http://stackoverflow.com/questions/25107697/compiling-cx-freeze-under-ubuntu
"""
import glob
import tarfile
import os
import sys
import platform
import py
if __name__ == '__main__':
if 'ubuntu' not in platform.version().lower():
print('Not Ubuntu, installing using pip. (platform.version() is %r)' %
platform.version())
res = os.system('pip install cx_freeze')
if res != 0:
sys.exit(res)
sys.exit(0)
rootdir = py.path.local.make_numbered_dir(prefix='cx_freeze')
res = os.system('pip install --download %s --no-use-wheel '
'cx_freeze' % rootdir)
if res != 0:
sys.exit(res)
packages = glob.glob('%s/*.tar.gz' % rootdir)
assert len(packages) == 1
tar_filename = packages[0]
tar_file = tarfile.open(tar_filename)
try:
tar_file.extractall(path=str(rootdir))
finally:
tar_file.close()
basename = os.path.basename(tar_filename).replace('.tar.gz', '')
setup_py_filename = '%s/%s/setup.py' % (rootdir, basename)
with open(setup_py_filename) as f:
lines = f.readlines()
line_to_patch = 'if not vars.get("Py_ENABLE_SHARED", 0):'
for index, line in enumerate(lines):
if line_to_patch in line:
indent = line[:line.index(line_to_patch)]
lines[index] = indent + 'if True:\n'
print('Patched line %d' % (index + 1))
break
else:
sys.exit('Could not find line in setup.py to patch!')
with open(setup_py_filename, 'w') as f:
f.writelines(lines)
os.chdir('%s/%s' % (rootdir, basename))
res = os.system('python setup.py install')
if res != 0:
sys.exit(res)
sys.exit(0)

View File

@ -1,15 +0,0 @@
"""
Sample setup.py script that generates an executable with pytest runner embedded.
"""
if __name__ == '__main__':
from cx_Freeze import setup, Executable
import pytest
setup(
name="runtests",
version="0.1",
description="example of how embedding pytest into an executable using cx_freeze",
executables=[Executable("runtests_script.py")],
options={"build_exe": {'includes': pytest.freeze_includes()}},
)

View File

@ -1,15 +0,0 @@
"""
Called by tox.ini: uses the generated executable to run the tests in ./tests/
directory.
.. note:: somehow calling "build/runtests_script" directly from tox doesn't
seem to work (at least on Windows).
"""
if __name__ == '__main__':
import os
import sys
executable = os.path.join(os.getcwd(), 'build', 'runtests_script')
if sys.platform.startswith('win'):
executable += '.exe'
sys.exit(os.system('%s tests' % executable))

3
testing/freeze/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
build/
dist/
*.spec

View File

@ -0,0 +1,13 @@
"""
Generates an executable with pytest runner embedded using PyInstaller.
"""
if __name__ == '__main__':
import pytest
import subprocess
hidden = []
for x in pytest.freeze_includes():
hidden.extend(['--hidden-import', x])
args = ['pyinstaller', '--noconfirm'] + hidden + ['runtests_script.py']
subprocess.check_call(' '.join(args), shell=True)

View File

@ -1,6 +1,6 @@
""" """
This is the script that is actually frozen into an executable: simply executes This is the script that is actually frozen into an executable: simply executes
pytest main(). py.test main().
""" """
if __name__ == '__main__': if __name__ == '__main__':

12
testing/freeze/tox_run.py Normal file
View File

@ -0,0 +1,12 @@
"""
Called by tox.ini: uses the generated executable to run the tests in ./tests/
directory.
"""
if __name__ == '__main__':
import os
import sys
executable = os.path.join(os.getcwd(), 'dist', 'runtests_script', 'runtests_script')
if sys.platform.startswith('win'):
executable += '.exe'
sys.exit(os.system('%s tests' % executable))

View File

@ -493,6 +493,7 @@ class TestSession:
class Test_getinitialnodes: class Test_getinitialnodes:
def test_global_file(self, testdir, tmpdir): def test_global_file(self, testdir, tmpdir):
x = tmpdir.ensure("x.py") x = tmpdir.ensure("x.py")
with tmpdir.as_cwd():
config = testdir.parseconfigure(x) config = testdir.parseconfigure(x)
col = testdir.getnode(config, x) col = testdir.getnode(config, x)
assert isinstance(col, pytest.Module) assert isinstance(col, pytest.Module)
@ -507,6 +508,7 @@ class Test_getinitialnodes:
subdir = tmpdir.join("subdir") subdir = tmpdir.join("subdir")
x = subdir.ensure("x.py") x = subdir.ensure("x.py")
subdir.ensure("__init__.py") subdir.ensure("__init__.py")
with subdir.as_cwd():
config = testdir.parseconfigure(x) config = testdir.parseconfigure(x)
col = testdir.getnode(config, x) col = testdir.getnode(config, x)
assert isinstance(col, pytest.Module) assert isinstance(col, pytest.Module)

View File

@ -483,6 +483,7 @@ def test_consider_args_after_options_for_rootdir_and_inifile(testdir, args):
args[i] = d1 args[i] = d1
elif arg == 'dir2': elif arg == 'dir2':
args[i] = d2 args[i] = d2
with root.as_cwd():
result = testdir.runpytest(*args) result = testdir.runpytest(*args)
result.stdout.fnmatch_lines(['*rootdir: *myroot, inifile: ']) result.stdout.fnmatch_lines(['*rootdir: *myroot, inifile: '])
@ -566,10 +567,14 @@ class TestWarning:
class TestRootdir: class TestRootdir:
def test_simple_noini(self, tmpdir): def test_simple_noini(self, tmpdir):
assert get_common_ancestor([tmpdir]) == tmpdir assert get_common_ancestor([tmpdir]) == tmpdir
assert get_common_ancestor([tmpdir.mkdir("a"), tmpdir]) == tmpdir a = tmpdir.mkdir("a")
assert get_common_ancestor([tmpdir, tmpdir.join("a")]) == tmpdir assert get_common_ancestor([a, tmpdir]) == tmpdir
assert get_common_ancestor([tmpdir, a]) == tmpdir
with tmpdir.as_cwd(): with tmpdir.as_cwd():
assert get_common_ancestor([]) == tmpdir assert get_common_ancestor([]) == tmpdir
no_path = tmpdir.join('does-not-exist')
assert get_common_ancestor([no_path]) == tmpdir
assert get_common_ancestor([no_path.join('a')]) == tmpdir
@pytest.mark.parametrize("name", "setup.cfg tox.ini pytest.ini".split()) @pytest.mark.parametrize("name", "setup.cfg tox.ini pytest.ini".split())
def test_with_ini(self, tmpdir, name): def test_with_ini(self, tmpdir, name):
@ -604,7 +609,8 @@ class TestRootdir:
assert inifile is None assert inifile is None
assert inicfg == {} assert inicfg == {}
def test_nothing(self, tmpdir): def test_nothing(self, tmpdir, monkeypatch):
monkeypatch.chdir(str(tmpdir))
rootdir, inifile, inicfg = determine_setup(None, [tmpdir]) rootdir, inifile, inicfg = determine_setup(None, [tmpdir])
assert rootdir == tmpdir assert rootdir == tmpdir
assert inifile is None assert inifile is None
@ -685,3 +691,36 @@ class TestOverrideIniArgs:
"ini2:url=/tmp/user2?a=b&d=e", "ini2:url=/tmp/user2?a=b&d=e",
"ini3:True", "ini3:True",
"ini4:False"]) "ini4:False"])
def test_with_arg_outside_cwd_without_inifile(self, tmpdir, monkeypatch):
monkeypatch.chdir(str(tmpdir))
a = tmpdir.mkdir("a")
b = tmpdir.mkdir("b")
rootdir, inifile, inicfg = determine_setup(None, [a, b])
assert rootdir == tmpdir
assert inifile is None
def test_with_arg_outside_cwd_with_inifile(self, tmpdir):
a = tmpdir.mkdir("a")
b = tmpdir.mkdir("b")
inifile = a.ensure("pytest.ini")
rootdir, parsed_inifile, inicfg = determine_setup(None, [a, b])
assert rootdir == a
assert inifile == parsed_inifile
@pytest.mark.parametrize('dirs', ([], ['does-not-exist'],
['a/does-not-exist']))
def test_with_non_dir_arg(self, dirs, tmpdir):
with tmpdir.ensure(dir=True).as_cwd():
rootdir, inifile, inicfg = determine_setup(None, dirs)
assert rootdir == tmpdir
assert inifile is None
def test_with_existing_file_in_subdir(self, tmpdir):
a = tmpdir.mkdir("a")
a.ensure("exist")
with tmpdir.as_cwd():
rootdir, inifile, inicfg = determine_setup(None, ['a/exist'])
assert rootdir == tmpdir
assert inifile is None

11
tox.ini
View File

@ -5,7 +5,7 @@ distshare={homedir}/.tox/distshare
envlist= envlist=
linting,py26,py27,py33,py34,py35,pypy, linting,py26,py27,py33,py34,py35,pypy,
{py27,py35}-{pexpect,xdist,trial}, {py27,py35}-{pexpect,xdist,trial},
py27-nobyte,doctesting,py27-cxfreeze py27-nobyte,doctesting,freeze
[testenv] [testenv]
commands= pytest --lsof -rfsxX {posargs:testing} commands= pytest --lsof -rfsxX {posargs:testing}
@ -128,12 +128,11 @@ changedir=testing
commands= commands=
{envpython} {envbindir}/py.test-jython -rfsxX {posargs} {envpython} {envbindir}/py.test-jython -rfsxX {posargs}
[testenv:py27-cxfreeze] [testenv:freeze]
changedir=testing/cx_freeze changedir=testing/freeze
platform=linux|darwin deps=pyinstaller
commands= commands=
{envpython} install_cx_freeze.py {envpython} create_executable.py
{envpython} runtests_setup.py build --build-exe build
{envpython} tox_run.py {envpython} tox_run.py