From cd62ee3f29456d96d336f4c67cbd37a0a95f7b4a Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Fri, 12 Sep 2014 18:24:53 +0100 Subject: Have all unit tests import from our own subclass of trial's unittest TestCase; set up logging in ONE PLACE ONLY --- tests/unittest.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 tests/unittest.py (limited to 'tests/unittest.py') diff --git a/tests/unittest.py b/tests/unittest.py new file mode 100644 index 0000000000..00c3c532eb --- /dev/null +++ b/tests/unittest.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +# Copyright 2014 OpenMarket Ltd +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from twisted.trial import unittest + +import logging + + +# logging doesn't have a "don't log anything at all EVARRRR setting, +# but since the highest value is 50, 1000000 should do ;) +NEVER = 1000000 + +logging.getLogger().addHandler(logging.StreamHandler()) +logging.getLogger().setLevel(NEVER) + + +class TestCase(unittest.TestCase): + pass -- cgit 1.4.1 From ca8349a897c233d72ea74128dabdd1311f00c13c Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Fri, 12 Sep 2014 18:29:07 +0100 Subject: Allow a TestCase to set a 'loglevel' attribute, which overrides the logging level while that testcase runs --- tests/unittest.py | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) (limited to 'tests/unittest.py') diff --git a/tests/unittest.py b/tests/unittest.py index 00c3c532eb..19be03b96a 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -27,4 +27,25 @@ logging.getLogger().setLevel(NEVER) class TestCase(unittest.TestCase): - pass + def __init__(self, *args, **kwargs): + super(TestCase, self).__init__(*args, **kwargs) + + level = getattr(self, "loglevel", NEVER) + + orig_setUp = self.setUp + + def setUp(): + old_level = logging.getLogger().level + + if old_level != level: + orig_tearDown = self.tearDown + + def tearDown(): + ret = orig_tearDown() + logging.getLogger().setLevel(old_level) + return ret + self.tearDown = tearDown + + logging.getLogger().setLevel(level) + return orig_setUp() + self.setUp = setUp -- cgit 1.4.1 From 33c4dd4c2ddcd81854855e84a838db9603bbe338 Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Fri, 12 Sep 2014 18:38:11 +0100 Subject: Define a (class) decorator for easily setting a DEBUG logging level on a TestCase --- tests/unittest.py | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'tests/unittest.py') diff --git a/tests/unittest.py b/tests/unittest.py index 19be03b96a..c66a3b8407 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -49,3 +49,8 @@ class TestCase(unittest.TestCase): logging.getLogger().setLevel(level) return orig_setUp() self.setUp = setUp + + +def DEBUG(target): + target.loglevel = logging.DEBUG + return target -- cgit 1.4.1 From d9f3f322c5f17a4c3d3ac000462a7bbd0a407711 Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Fri, 12 Sep 2014 18:43:49 +0100 Subject: Additionally look first for a 'loglevel' attribute on the running test method, before the TestCase --- tests/unittest.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'tests/unittest.py') diff --git a/tests/unittest.py b/tests/unittest.py index c66a3b8407..8ae724c786 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -27,10 +27,14 @@ logging.getLogger().setLevel(NEVER) class TestCase(unittest.TestCase): - def __init__(self, *args, **kwargs): - super(TestCase, self).__init__(*args, **kwargs) + def __init__(self, methodName, *args, **kwargs): + super(TestCase, self).__init__(methodName, *args, **kwargs) - level = getattr(self, "loglevel", NEVER) + method = getattr(self, methodName) + + level = getattr(method, "loglevel", + getattr(self, "loglevel", + NEVER)) orig_setUp = self.setUp -- cgit 1.4.1 From aeb69c0f8cc6e723316aefbc6b71c82b4ed94aad Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Fri, 12 Sep 2014 18:45:48 +0100 Subject: Add some docstrings --- tests/unittest.py | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tests/unittest.py') diff --git a/tests/unittest.py b/tests/unittest.py index 8ae724c786..e437d3541a 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -27,6 +27,10 @@ logging.getLogger().setLevel(NEVER) class TestCase(unittest.TestCase): + """A subclass of twisted.trial's TestCase which looks for 'loglevel' + attributes on both itself and its individual test methods, to override the + root logger's logging level while that test (case|method) runs.""" + def __init__(self, methodName, *args, **kwargs): super(TestCase, self).__init__(methodName, *args, **kwargs) @@ -56,5 +60,7 @@ class TestCase(unittest.TestCase): def DEBUG(target): + """A decorator to set the .loglevel attribute to logging.DEBUG. + Can apply to either a TestCase or an individual test method.""" target.loglevel = logging.DEBUG return target -- cgit 1.4.1 From 7a77aabb4bbb997db9dadd46e49d855946c1ae2e Mon Sep 17 00:00:00 2001 From: "Paul \"LeoNerd\" Evans" Date: Fri, 12 Sep 2014 19:07:29 +0100 Subject: Define a CLOS-like 'around' modifier as a decorator, to neaten up the 'orig_*' noise of wrapping the setUp()/tearDown() methods --- tests/unittest.py | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'tests/unittest.py') diff --git a/tests/unittest.py b/tests/unittest.py index e437d3541a..fb97fb1148 100644 --- a/tests/unittest.py +++ b/tests/unittest.py @@ -26,6 +26,23 @@ logging.getLogger().addHandler(logging.StreamHandler()) logging.getLogger().setLevel(NEVER) +def around(target): + """A CLOS-style 'around' modifier, which wraps the original method of the + given instance with another piece of code. + + @around(self) + def method_name(orig, *args, **kwargs): + return orig(*args, **kwargs) + """ + def _around(code): + name = code.__name__ + orig = getattr(target, name) + def new(*args, **kwargs): + return code(orig, *args, **kwargs) + setattr(target, name, new) + return _around + + class TestCase(unittest.TestCase): """A subclass of twisted.trial's TestCase which looks for 'loglevel' attributes on both itself and its individual test methods, to override the @@ -40,23 +57,19 @@ class TestCase(unittest.TestCase): getattr(self, "loglevel", NEVER)) - orig_setUp = self.setUp - - def setUp(): + @around(self) + def setUp(orig): old_level = logging.getLogger().level if old_level != level: - orig_tearDown = self.tearDown - - def tearDown(): - ret = orig_tearDown() + @around(self) + def tearDown(orig): + ret = orig() logging.getLogger().setLevel(old_level) return ret - self.tearDown = tearDown logging.getLogger().setLevel(level) - return orig_setUp() - self.setUp = setUp + return orig() def DEBUG(target): -- cgit 1.4.1