[Pytest-commit] commit/pytest: 4 new changesets

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Wed Oct 22 07:14:14 CEST 2014


4 new commits in pytest:

https://bitbucket.org/hpk42/pytest/commits/4fb4cb5ae00f/
Changeset:   4fb4cb5ae00f
Branch:      python-classes-glob
User:        nicoddemus
Date:        2014-10-16 22:27:10+00:00
Summary:     added support for glob-style patterns to python_classes and python_functions config options

fixes #600
Affected #:  4 files

diff -r 4696fc59a5a15f9c79902d34489865bf7f840b6c -r 4fb4cb5ae00f6ca77992b2a566eefb073f299d27 _pytest/python.py
--- a/_pytest/python.py
+++ b/_pytest/python.py
@@ -1,4 +1,5 @@
 """ Python test discovery, setup and run of test functions. """
+import fnmatch
 import py
 import inspect
 import sys
@@ -127,9 +128,10 @@
         default=['test_*.py', '*_test.py'],
         help="glob-style file patterns for Python test module discovery")
     parser.addini("python_classes", type="args", default=["Test",],
-        help="prefixes for Python test class discovery")
+        help="prefixes or glob names for Python test class discovery")
     parser.addini("python_functions", type="args", default=["test",],
-        help="prefixes for Python test function and method discovery")
+        help="prefixes or glob names for Python test function and "
+             "method discovery")
 
 def pytest_cmdline_main(config):
     if config.option.showfixtures:
@@ -307,14 +309,22 @@
 class PyCollector(PyobjMixin, pytest.Collector):
 
     def funcnamefilter(self, name):
-        for prefix in self.config.getini("python_functions"):
-            if name.startswith(prefix):
-                return True
+        return self._matches_prefix_or_glob_option('python_functions', name)
 
     def classnamefilter(self, name):
-        for prefix in self.config.getini("python_classes"):
-            if name.startswith(prefix):
+        return self._matches_prefix_or_glob_option('python_classes', name)
+
+    def _matches_prefix_or_glob_option(self, option_name, name):
+        """
+        checks if the given name matches the prefix or glob-pattern defined
+        in ini configuration.
+        """
+        for option in self.config.getini(option_name):
+            if name.startswith(option):
                 return True
+            elif fnmatch.fnmatch(name, option):
+                return True
+        return False
 
     def collect(self):
         if not getattr(self.obj, "__test__", True):

diff -r 4696fc59a5a15f9c79902d34489865bf7f840b6c -r 4fb4cb5ae00f6ca77992b2a566eefb073f299d27 doc/en/customize.txt
--- a/doc/en/customize.txt
+++ b/doc/en/customize.txt
@@ -115,17 +115,33 @@
 
 .. confval:: python_classes
 
-   One or more name prefixes determining which test classes
-   are considered as test modules.
+   One or more name prefixes or glob-style patterns determining which classes
+   are considered for test collection. Here is an example of how to collect
+   tests from classes that end in ``Suite``::
+
+    # content of pytest.ini
+    [pytest]
+    python_classes = *Suite
+
+   Note that ``unittest.TestCase`` derived classes are always collected
+   regardless of this option, as ``unittest``'s own collection framework is used
+   to collect those tests.
 
 .. confval:: python_functions
 
-   One or more name prefixes determining which test functions
-   and methods are considered as test modules.  Note that this
-   has no effect on methods that live on a ``unittest.TestCase``
-   derived class.
+   One or more name prefixes or glob-patterns determining which test functions
+   and methods are considered tests. Here is an example of how
+   to collect test functions and methods that end in ``_test``::
 
-   See :ref:`change naming conventions` for examples.
+    # content of pytest.ini
+    [pytest]
+    python_functions = *_test
+
+   Note that this has no effect on methods that live on a ``unittest
+   .TestCase`` derived class, as ``unittest``'s own collection framework is used
+   to collect those tests.
+
+   See :ref:`change naming conventions` for more detailed examples.
 
 .. confval:: doctest_optionflags
 

diff -r 4696fc59a5a15f9c79902d34489865bf7f840b6c -r 4fb4cb5ae00f6ca77992b2a566eefb073f299d27 doc/en/example/pythoncollection.txt
--- a/doc/en/example/pythoncollection.txt
+++ b/doc/en/example/pythoncollection.txt
@@ -26,17 +26,17 @@
     [pytest]
     python_files=check_*.py
     python_classes=Check
-    python_functions=check
+    python_functions=*_check
 
-This would make ``pytest`` look for ``check_`` prefixes in
-Python filenames, ``Check`` prefixes in classes and ``check`` prefixes
-in functions and classes.  For example, if we have::
+This would make ``pytest`` look for tests in files that match the ``check_*
+.py`` glob-pattern, ``Check`` prefixes in classes, and functions and methods
+that match ``*_check``.  For example, if we have::
 
     # content of check_myapp.py
     class CheckMyApp:
-        def check_simple(self):
+        def simple_check(self):
             pass
-        def check_complex(self):
+        def complex_check(self):
             pass
 
 then the test collection looks like this::
@@ -48,14 +48,14 @@
     <Module 'check_myapp.py'><Class 'CheckMyApp'><Instance '()'>
-          <Function 'check_simple'>
-          <Function 'check_complex'>
+          <Function 'simple_check'>
+          <Function 'complex_check'>
     
     =============================  in 0.01 seconds =============================
 
 .. note::
 
-   the ``python_functions`` and ``python_classes`` has no effect
+   the ``python_functions`` and ``python_classes`` options has no effect
    for ``unittest.TestCase`` test discovery because pytest delegates
    detection of test case methods to unittest code.
 

diff -r 4696fc59a5a15f9c79902d34489865bf7f840b6c -r 4fb4cb5ae00f6ca77992b2a566eefb073f299d27 testing/test_collection.py
--- a/testing/test_collection.py
+++ b/testing/test_collection.py
@@ -528,6 +528,30 @@
         assert s.endswith("test_example_items1.testone")
         print(s)
 
+    def test_class_and_functions_discovery_using_glob(self, testdir):
+        """
+        tests that python_classes and python_functions config options work
+        as prefixes and glob-like patterns (issue #600).
+        """
+        testdir.makeini("""
+            [pytest]
+            python_classes = *Suite Test
+            python_functions = *_test test
+        """)
+        p = testdir.makepyfile('''
+            class MyTestSuite:
+                def x_test(self):
+                    pass
+
+            class TestCase:
+                def test_y(self):
+                    pass
+        ''')
+        items, reprec = testdir.inline_genitems(p)
+        ids = [x.getmodpath() for x in items]
+        assert ids == ['MyTestSuite.x_test', 'TestCase.test_y']
+
+
 def test_matchnodes_two_collections_same_file(testdir):
     testdir.makeconftest("""
         import pytest


https://bitbucket.org/hpk42/pytest/commits/f975c55d571f/
Changeset:   f975c55d571f
Branch:      python-classes-glob
User:        nicoddemus
Date:        2014-10-20 20:36:31+00:00
Summary:     checking that option contains glob characters before calling fnmatch

requested during code review
Affected #:  1 file

diff -r 4fb4cb5ae00f6ca77992b2a566eefb073f299d27 -r f975c55d571f3d08a1e3a02d6b2c13a9f4257d48 _pytest/python.py
--- a/_pytest/python.py
+++ b/_pytest/python.py
@@ -322,7 +322,11 @@
         for option in self.config.getini(option_name):
             if name.startswith(option):
                 return True
-            elif fnmatch.fnmatch(name, option):
+            # check that name looks like a glob-string before calling fnmatch
+            # because this is called for every name in each collected module,
+            # and fnmatch is somewhat expensive to call
+            elif ('*' in option or '?' in option or '[' in option) and \
+                    fnmatch.fnmatch(name, option):
                 return True
         return False
 


https://bitbucket.org/hpk42/pytest/commits/447020d27a8e/
Changeset:   447020d27a8e
Branch:      python-classes-glob
User:        nicoddemus
Date:        2014-10-21 21:22:53+00:00
Summary:     added changelog entry about glob-patterns in python_classes and python_functions

- also fixed small typo
Affected #:  1 file

diff -r f975c55d571f3d08a1e3a02d6b2c13a9f4257d48 -r 447020d27a8ef51b4a03b76fab923a0b8c4b2000 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,9 @@
   parameter is a callable, you also need to pass in a reason to disambiguate
   it from the "decorator" case.  Thanks Tom Viner.
 
+- "python_classes" and "python_functions" options now support glob-patterns
+ for test discovery, as discussed in issue600. Thanks Ldiary Translations.
+
 2.6.4.dev
 ----------
 
@@ -86,7 +89,7 @@
   Thanks sontek.
 
 - Implement issue549: user-provided assertion messages now no longer
-  replace the py.test instrospection message but are shown in addition
+  replace the py.test introspection message but are shown in addition
   to them.
 
 2.6.1


https://bitbucket.org/hpk42/pytest/commits/e9bfc62abed3/
Changeset:   e9bfc62abed3
User:        hpk42
Date:        2014-10-22 05:14:10+00:00
Summary:     Merged in nicoddemus/pytest/python-classes-glob (pull request #225)

added support for glob-style patterns to python_classes and python_functions config options
Affected #:  5 files

diff -r 78def8dd5c941ec312994f87fd31f8a422943879 -r e9bfc62abed3c6151cd6978167377f4bb1566802 CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -16,6 +16,9 @@
   parameter is a callable, you also need to pass in a reason to disambiguate
   it from the "decorator" case.  Thanks Tom Viner.
 
+- "python_classes" and "python_functions" options now support glob-patterns
+ for test discovery, as discussed in issue600. Thanks Ldiary Translations.
+
 2.6.4.dev
 ----------
 
@@ -86,7 +89,7 @@
   Thanks sontek.
 
 - Implement issue549: user-provided assertion messages now no longer
-  replace the py.test instrospection message but are shown in addition
+  replace the py.test introspection message but are shown in addition
   to them.
 
 2.6.1

diff -r 78def8dd5c941ec312994f87fd31f8a422943879 -r e9bfc62abed3c6151cd6978167377f4bb1566802 _pytest/python.py
--- a/_pytest/python.py
+++ b/_pytest/python.py
@@ -1,4 +1,5 @@
 """ Python test discovery, setup and run of test functions. """
+import fnmatch
 import py
 import inspect
 import sys
@@ -127,9 +128,10 @@
         default=['test_*.py', '*_test.py'],
         help="glob-style file patterns for Python test module discovery")
     parser.addini("python_classes", type="args", default=["Test",],
-        help="prefixes for Python test class discovery")
+        help="prefixes or glob names for Python test class discovery")
     parser.addini("python_functions", type="args", default=["test",],
-        help="prefixes for Python test function and method discovery")
+        help="prefixes or glob names for Python test function and "
+             "method discovery")
 
 def pytest_cmdline_main(config):
     if config.option.showfixtures:
@@ -307,14 +309,26 @@
 class PyCollector(PyobjMixin, pytest.Collector):
 
     def funcnamefilter(self, name):
-        for prefix in self.config.getini("python_functions"):
-            if name.startswith(prefix):
-                return True
+        return self._matches_prefix_or_glob_option('python_functions', name)
 
     def classnamefilter(self, name):
-        for prefix in self.config.getini("python_classes"):
-            if name.startswith(prefix):
+        return self._matches_prefix_or_glob_option('python_classes', name)
+
+    def _matches_prefix_or_glob_option(self, option_name, name):
+        """
+        checks if the given name matches the prefix or glob-pattern defined
+        in ini configuration.
+        """
+        for option in self.config.getini(option_name):
+            if name.startswith(option):
                 return True
+            # check that name looks like a glob-string before calling fnmatch
+            # because this is called for every name in each collected module,
+            # and fnmatch is somewhat expensive to call
+            elif ('*' in option or '?' in option or '[' in option) and \
+                    fnmatch.fnmatch(name, option):
+                return True
+        return False
 
     def collect(self):
         if not getattr(self.obj, "__test__", True):

diff -r 78def8dd5c941ec312994f87fd31f8a422943879 -r e9bfc62abed3c6151cd6978167377f4bb1566802 doc/en/customize.txt
--- a/doc/en/customize.txt
+++ b/doc/en/customize.txt
@@ -115,17 +115,33 @@
 
 .. confval:: python_classes
 
-   One or more name prefixes determining which test classes
-   are considered as test modules.
+   One or more name prefixes or glob-style patterns determining which classes
+   are considered for test collection. Here is an example of how to collect
+   tests from classes that end in ``Suite``::
+
+    # content of pytest.ini
+    [pytest]
+    python_classes = *Suite
+
+   Note that ``unittest.TestCase`` derived classes are always collected
+   regardless of this option, as ``unittest``'s own collection framework is used
+   to collect those tests.
 
 .. confval:: python_functions
 
-   One or more name prefixes determining which test functions
-   and methods are considered as test modules.  Note that this
-   has no effect on methods that live on a ``unittest.TestCase``
-   derived class.
+   One or more name prefixes or glob-patterns determining which test functions
+   and methods are considered tests. Here is an example of how
+   to collect test functions and methods that end in ``_test``::
 
-   See :ref:`change naming conventions` for examples.
+    # content of pytest.ini
+    [pytest]
+    python_functions = *_test
+
+   Note that this has no effect on methods that live on a ``unittest
+   .TestCase`` derived class, as ``unittest``'s own collection framework is used
+   to collect those tests.
+
+   See :ref:`change naming conventions` for more detailed examples.
 
 .. confval:: doctest_optionflags
 

diff -r 78def8dd5c941ec312994f87fd31f8a422943879 -r e9bfc62abed3c6151cd6978167377f4bb1566802 doc/en/example/pythoncollection.txt
--- a/doc/en/example/pythoncollection.txt
+++ b/doc/en/example/pythoncollection.txt
@@ -26,17 +26,17 @@
     [pytest]
     python_files=check_*.py
     python_classes=Check
-    python_functions=check
+    python_functions=*_check
 
-This would make ``pytest`` look for ``check_`` prefixes in
-Python filenames, ``Check`` prefixes in classes and ``check`` prefixes
-in functions and classes.  For example, if we have::
+This would make ``pytest`` look for tests in files that match the ``check_*
+.py`` glob-pattern, ``Check`` prefixes in classes, and functions and methods
+that match ``*_check``.  For example, if we have::
 
     # content of check_myapp.py
     class CheckMyApp:
-        def check_simple(self):
+        def simple_check(self):
             pass
-        def check_complex(self):
+        def complex_check(self):
             pass
 
 then the test collection looks like this::
@@ -48,14 +48,14 @@
     <Module 'check_myapp.py'><Class 'CheckMyApp'><Instance '()'>
-          <Function 'check_simple'>
-          <Function 'check_complex'>
+          <Function 'simple_check'>
+          <Function 'complex_check'>
     
     =============================  in 0.01 seconds =============================
 
 .. note::
 
-   the ``python_functions`` and ``python_classes`` has no effect
+   the ``python_functions`` and ``python_classes`` options has no effect
    for ``unittest.TestCase`` test discovery because pytest delegates
    detection of test case methods to unittest code.
 

diff -r 78def8dd5c941ec312994f87fd31f8a422943879 -r e9bfc62abed3c6151cd6978167377f4bb1566802 testing/test_collection.py
--- a/testing/test_collection.py
+++ b/testing/test_collection.py
@@ -528,6 +528,30 @@
         assert s.endswith("test_example_items1.testone")
         print(s)
 
+    def test_class_and_functions_discovery_using_glob(self, testdir):
+        """
+        tests that python_classes and python_functions config options work
+        as prefixes and glob-like patterns (issue #600).
+        """
+        testdir.makeini("""
+            [pytest]
+            python_classes = *Suite Test
+            python_functions = *_test test
+        """)
+        p = testdir.makepyfile('''
+            class MyTestSuite:
+                def x_test(self):
+                    pass
+
+            class TestCase:
+                def test_y(self):
+                    pass
+        ''')
+        items, reprec = testdir.inline_genitems(p)
+        ids = [x.getmodpath() for x in items]
+        assert ids == ['MyTestSuite.x_test', 'TestCase.test_y']
+
+
 def test_matchnodes_two_collections_same_file(testdir):
     testdir.makeconftest("""
         import pytest

Repository URL: https://bitbucket.org/hpk42/pytest/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.


More information about the pytest-commit mailing list