summaryrefslogtreecommitdiffstats
path: root/ipatests/pytest_plugins
diff options
context:
space:
mode:
authorPetr Viktorin <pviktori@redhat.com>2014-10-10 14:56:29 +0200
committerTomas Babej <tbabej@redhat.com>2014-11-21 12:14:44 +0100
commit3a9a98b2852d26fdc8257d20ef907ad8c47bcfe3 (patch)
tree794f36c63b64315a1f70e515ce5c945721f70827 /ipatests/pytest_plugins
parent0cb12f3cdef899df47e749ddaef937f7d1bd7a91 (diff)
downloadfreeipa-3a9a98b2852d26fdc8257d20ef907ad8c47bcfe3.tar.gz
freeipa-3a9a98b2852d26fdc8257d20ef907ad8c47bcfe3.tar.xz
freeipa-3a9a98b2852d26fdc8257d20ef907ad8c47bcfe3.zip
Integration tests: Port the ordering plugin to pytest
Ordered integration tests may now be run with pytest. https://fedorahosted.org/freeipa/ticket/4610 Reviewed-By: Tomas Babej <tbabej@redhat.com>
Diffstat (limited to 'ipatests/pytest_plugins')
-rw-r--r--ipatests/pytest_plugins/ordering.py88
1 files changed, 88 insertions, 0 deletions
diff --git a/ipatests/pytest_plugins/ordering.py b/ipatests/pytest_plugins/ordering.py
new file mode 100644
index 000000000..3af496a88
--- /dev/null
+++ b/ipatests/pytest_plugins/ordering.py
@@ -0,0 +1,88 @@
+# Authors:
+# Petr Viktorin <pviktori@redhat.com>
+#
+# Copyright (C) 2014 Red Hat
+# see file 'COPYING' for use and warranty information
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation, either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+"""Pytest plugin for IPA
+
+Adds support for the @pytest.mark.source_order decorator which,
+when applied to a class, runs the test methods in source order.
+
+See test_ordering for an example.
+"""
+
+import unittest
+
+import pytest
+
+
+def ordered(cls):
+ """Decorator that marks a test class as ordered
+
+ Methods within the marked class will be executed in definition order
+ (or more strictly, in ordered by the line number where they're defined).
+
+ Subclasses of unittest.TestCase can not be ordered.
+
+ Generator methods will not be ordered by this plugin.
+ """
+ cls._order_plugin__ordered = True
+ assert not isinstance(cls, unittest.TestCase), (
+ "A unittest.TestCase may not be ordered.")
+ cls = pytest.mark.source_order(cls)
+ return cls
+
+
+def decorate_items(items):
+ node_indexes = {}
+ for index, item in enumerate(items):
+ try:
+ func = item.function
+ except AttributeError:
+ yield (index, ), item
+ continue
+
+ key = (index, )
+ for node in reversed(item.listchain()):
+ # Find the corresponding class
+ if isinstance(node, pytest.Class):
+ cls = node.cls
+ else:
+ continue
+ if getattr(cls, '_order_plugin__ordered', False):
+ node_index = node_indexes.setdefault(node, index)
+ # Find first occurence of the method in class hierarchy
+ for i, parent_class in enumerate(reversed(cls.mro())):
+ if getattr(parent_class, '_order_plugin__ordered', False):
+ method = getattr(parent_class, func.__name__, None)
+ if method:
+ # Sort methods as tuples (position of the class
+ # in the inheritance chain, position of the method
+ # within that class)
+ key = (node_index, 0,
+ i, method.func_code.co_firstlineno, node)
+ break
+ else:
+ # Weird case fallback
+ # Method name not in any of the classes in MRO, run it last
+ key = node_index, 1, func.func_code.co_firstlineno, node
+ break
+ yield key, item
+
+
+def pytest_collection_modifyitems(session, config, items):
+ items[:] = [item for i, item in sorted(decorate_items(items))]