[GRASS-SVN] r61181 - sandbox/wenzeslaus/gunittest

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Jul 7 20:45:45 PDT 2014


Author: wenzeslaus
Date: 2014-07-07 20:45:45 -0700 (Mon, 07 Jul 2014)
New Revision: 61181

Modified:
   sandbox/wenzeslaus/gunittest/case.py
   sandbox/wenzeslaus/gunittest/loader.py
   sandbox/wenzeslaus/gunittest/main.py
Log:
gunittest: remove additional methods for running modules, format assert messages differently than unittest

Modified: sandbox/wenzeslaus/gunittest/case.py
===================================================================
--- sandbox/wenzeslaus/gunittest/case.py	2014-07-07 23:00:27 UTC (rev 61180)
+++ sandbox/wenzeslaus/gunittest/case.py	2014-07-08 03:45:45 UTC (rev 61181)
@@ -34,10 +34,38 @@
     Always use keyword arguments for all parameters other than first two. For
     the firt two, it is recommened to use keyword arguments but not required.
     """
+    longMessage = True  # to get both standard and custom message
+
     def __init__(self, methodName):
         super(TestCase, self).__init__(methodName)
         self._temp_region = None
 
+    def _formatMessage(self, msg, standardMsg):
+        """Honour the longMessage attribute when generating failure messages.
+
+        If longMessage is False this means:
+
+        * Use only an explicit message if it is provided
+        * Otherwise use the standard message for the assert
+
+        If longMessage is True:
+
+        * Use the standard message
+        * If an explicit message is provided, return string with both messages
+
+        Based on Python unittest _formatMessage, formatting chanaged.
+        """
+        if not self.longMessage:
+            return msg or standardMsg
+        if msg is None:
+            return standardMsg
+        try:
+            # don't switch to '{}' formatting in Python 2.X
+            # it changes the way unicode input is handled
+            return '%s \n%s' % (msg, standardMsg)
+        except UnicodeDecodeError:
+            return '%s \n%s' % (safe_repr(msg), safe_repr(standardMsg))
+
     def use_temp_region(self):
         """Use temporary region instead of the standard one for this process.
 
@@ -45,8 +73,17 @@
         `del_temp_region()` in `tearDown()`. By this you ensure that each test
         method will have its own region and will not influece others.
 
+        ::
+
+            def setUp(self):
+                self.use_temp_region()
+
+            def tearDown(self):
+                self.del_temp_region()
+
         Copies the current region to a temporary region with
-        "g.region save=", then sets WIND_OVERRIDE to refer to that region.
+        ``g.region save=``, then sets ``WIND_OVERRIDE`` to refer
+        to that region.
         """
         # this should be unique for each object because method name is used
         name = "tmp.%s" % (self.id())
@@ -203,6 +240,34 @@
                                    reference=reference, msg=msg, sep='=',
                                    precision=precision)
 
+    # TODO: use precision?
+    def assertRasterMinMax(self, map, refmin, refmax, msg=None):
+        """Test that raster map minimum and maximum are within limits.
+
+        Map mimimum and maximum is tested against expression::
+
+            refmin <= actualmin and refmax >= actualmax
+
+        Use keyword arguments syntax for all function parameters.
+
+        To check that more statistics have certain values use
+        `assertRasterFitsUnivar` or `assertRasterFitsInfo`
+        """
+        stdout = call_module('r.info', map=map, flags='r')
+        actual = text_to_keyvalue(stdout, sep='=')
+        if refmin > actual['min']:
+            stdmsg = ('The actual minimum ({a}) is smaller than the reference'
+                      ' one ({r}) for raster map {m}'
+                      ' (with maximum {o})'.format(
+                          a=actual['min'], r=refmin, m=map, o=actual['max']))
+            self.fail(self._formatMessage(msg, stdmsg))
+        if refmax < actual['max']:
+            stdmsg = ('The actual maximum ({a}) is greater than the reference'
+                      ' one ({r}) for raster map {m}'
+                      ' (with minimum {o})'.format(
+                          a=actual['max'], r=refmax, m=map, o=actual['min']))
+            self.fail(self._formatMessage(msg, stdmsg))
+
     def assertFileExists(self, filename, msg=None,
                          skip_size_check=False, skip_access_check=False):
         """Test the existence of a file.
@@ -267,66 +332,6 @@
                                                                         reference)
             self.fail(self._formatMessage(msg, stdmsg))
 
-    # TODO: this function might be useful but it is questionable if it is really needed
-    # TODO: name run_module/test_module/assert_module/call_module?
-    # TODO: implemet this function
-    # TODO: this should be the function used for valgrind or profiling or debug
-    # TODO: how these functions will behave when doing some benchmark with stdin/stdout?
-    # TODO: should call fail instead of raising? probably not, it is not assert but...
-    # TODO: we can also comapre time to some expected but that's tricky
-    # maybe we should measure time but the real benchmarks with stdin/stdout
-    # should be done by some other function
-    # can accept stdin
-    # logs merged stdout and stderr
-    # raises when modules returns non-zero (should raise after logging)
-    def run_module(self, module, stdin=None, **kwargs):
-        """Run module and save stdout and stderr.
-
-        Use this function to call the module you are currently testing.
-        Do not use this function to call modules when preparing data,
-        or testing the results.
-
-        This function should be used when you expect the module to succeed
-        and you are testing outputs of the module other than stdout.
-        For example, if you are interested in raster map it produced.
-        The advantage of this function is that it gives you a posibility to
-        examine the output of the module.
-
-        This is not appropriate for the cases when you want module standard output.
-        For this cases use call_module function which will give you stdout
-        separated without stderr and will raise an exception with stderr in
-        case of error.
-
-        .. note::
-            There should be only one call of this method per test method.
-
-        :returns: None
-        """
-        # this probably will not not use call_module because it should
-        # enable valgrid, profiling, debug for the module, ...
-        # for now call_module is good enough
-        output = call_module(module, stdin, merge_stderr=True, **kwargs)
-        # TODO: log output (stdout+stderr) to some file
-        # TODO: log also stdin and parameters
-
-    # can accept stdin
-    # returns stdout
-    # logs stderr
-    # raises when modules returns non-zero (should raise after logging)
-    def read_module(self, module, stdin=None, **kwargs):
-        """
-
-        Similar to `run_module` but returns stdout. It logs only stderr.
-
-        .. note::
-            There should be only one call of this method per test method.
-        """
-        # TODO: this cannot be implemented using call_module for sure
-        # since it needs to get stdout and stderr separately
-        # for now call_module is good enough
-        output = call_module(module, stdin, merge_stderr=False, **kwargs)
-        return output
-
     @classmethod
     def runModule(cls, module, **kwargs):
         """Run PyGRASS module.
@@ -370,6 +375,10 @@
                                     module.get_python(),
                                     errors=module.outputs['stderr'].value)
 
+    # TODO: we can also comapre time to some expected but that's tricky
+    # maybe we should measure time but the real benchmarks with stdin/stdout
+    # should be done by some other function
+    # TODO: this should be the function used for valgrind or profiling or debug
     # TODO: it asserts the rc but it does much more, so testModule?
     # TODO: do we need special function for testing module failures or just add parameter returncode=0?
     # TODO: consider allwing to call this method more than once

Modified: sandbox/wenzeslaus/gunittest/loader.py
===================================================================
--- sandbox/wenzeslaus/gunittest/loader.py	2014-07-07 23:00:27 UTC (rev 61180)
+++ sandbox/wenzeslaus/gunittest/loader.py	2014-07-08 03:45:45 UTC (rev 61181)
@@ -36,8 +36,13 @@
             files = fnmatch.filter(os.listdir(full), file_pattern)
             # we just ignore __init__.py
             module_names = [f[:-3] for f in files if not f == '__init__.py']
+            # TODO: warning (in what way?) about no tests in testsuite
             for name in module_names:
                 # TODO: rewrite to use import_module and search the file if not
+                # TODO: do it without importing
+                # TODO: check if there is some main
+                # otherwise we can have successful test just because
+                # everything was loaded into Python
                 abspath = os.path.abspath(full)
                 sys.path.insert(0, abspath)
                 try:

Modified: sandbox/wenzeslaus/gunittest/main.py
===================================================================
--- sandbox/wenzeslaus/gunittest/main.py	2014-07-07 23:00:27 UTC (rev 61180)
+++ sandbox/wenzeslaus/gunittest/main.py	2014-07-08 03:45:45 UTC (rev 61181)
@@ -50,6 +50,7 @@
     """Run a test of a module.
     """
     # TODO: put the link to to the report only if available
+    # TODO: how to disable Python code coverage for module and C tests?
     doing_coverage = False
     try:
         import coverage



More information about the grass-commit mailing list