gunittest package

Submodules

gunittest.case module

GRASS Python testing framework test case

Copyright (C) 2014 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS GIS for details.

authors

Vaclav Petras

class gunittest.case.TestCase(methodName)[source]

Bases: unittest.case.TestCase

Always use keyword arguments for all parameters other than first two. For the first two, it is recommended to use keyword arguments but not required. Be especially careful and always use keyword argument syntax for msg parameter.

Create an instance of the class that will use the named test method when executed. Raises a ValueError if the instance does not have a method with the specified name.

assertFileExists(filename, msg=None, skip_size_check=False, skip_access_check=False)[source]

Test the existence of a file.

assertFileMd5(filename, md5, text=False, msg=None)[source]

Test that file MD5 sum is equal to the provided sum.

Usually, this function is used to test binary files or large text files which cannot be tested in some other way. Text files can be usually tested by some finer method.

To test text files with this function, you should always use parameter text set to True. Note that function checkers.text_file_md5() offers additional parameters which might be advantageous when testing text files.

The typical workflow is that you create a file in a way you trust (that you obtain the right file). Then you compute MD5 sum of the file. And provide the sum in a test as a string:

self.assertFileMd5('result.png', md5='807bba4ffa...')

Use file_md5() function from this package:

file_md5('original_result.png')

Or in command line, use md5sum command if available:

md5sum some_file.png

Finally, you can use Python hashlib to obtain MD5:

import hashlib
hasher = hashlib.md5()
# expecting the file to fit into memory
hasher.update(open('original_result.png', 'rb').read())
hasher.hexdigest()
assertFilesEqualMd5(filename, reference, msg=None)[source]

Test that files are the same using MD5 sum.

This functions requires you to provide a file to test and a reference file. For both, MD5 sum will be computed and compared with each other.

assertLooksLike(actual, reference, msg=None)[source]

Test that actual text is the same as reference with ellipses.

If actual contains platform dependent newline characters, these will replaced by \n which is expected to be in the test data.

See check_text_ellipsis() for details of behavior.

assertModule(module, msg=None, **kwargs)[source]

Run PyGRASS module in controlled way and assert non-zero return code.

You should use this method to invoke module you are testing. By using this method, you give testing framework more control over the execution, error handling and storing of output.

It will not print module stdout and stderr, instead it will always store them for further examination. Streams are stored separately.

This method is not suitable for testing error states of the module. If you want to test behavior which involves non-zero return codes and examine stderr in test, use assertModuleFail() method.

Runs the module and causes test failure if module ends with non-zero return code.

assertModuleFail(module, msg=None, **kwargs)[source]

Test that module fails with a non-zero return code.

Works like assertModule() but expects module to fail.

assertModuleKeyValue(module, reference, sep, precision, msg=None, **parameters)[source]

Test that output of a module is the same as provided subset.

self.assertModuleKeyValue('r.info', map='elevation', flags='gr',
                          reference=dict(min=55.58, max=156.33),
                          precision=0.01, sep='=')
module = SimpleModule('r.info', map='elevation', flags='gr')
self.assertModuleKeyValue(module,
                          reference=dict(min=55.58, max=156.33),
                          precision=0.01, sep='=')

The output of the module should be key-value pairs (shell script style) which is typically obtained using -g flag.

assertMultiLineEqual(first, second, msg=None)[source]

Test that the multiline string first is equal to the string second.

When not equal a diff of the two strings highlighting the differences will be included in the error message. This method is used by default when comparing strings with assertEqual().

This method replaces platform dependent newline characters by \n (LF) in both parameters. This is different from the same method implemented in Python unittest package which preserves the original newline characters.

This function removes the burden of getting the newline characters right on each platform. You can just use \n everywhere and this function will ensure that it does not matter if for example, a module generates (as expected) \r\n (CRLF) newline characters on MS Windows.

Warning

If you need to test the actual newline characters, use the standard string comparison and functions such as find().

assertRaster3dDoesNotExist(name, msg=None)[source]

Checks if the 3D raster map does not exist in current mapset

assertRaster3dExists(name, msg=None)[source]

Checks if the 3D raster map exists in current mapset

assertRaster3dFitsInfo(raster, reference, precision=None, msg=None)[source]

Test that raster map has the values obtained by r3.info module.

The function does not require all values from r3.info. Only the provided values are tested.

Use keyword arguments syntax for all function parameters.

This function supports values obtained by -g (info) and -r (range).

assertRaster3dFitsUnivar(raster, reference, precision=None, msg=None)[source]

Test that 3D raster map has the values obtained by r3.univar module.

The function does not require all values from r3.univar. Only the provided values are tested.

Use keyword arguments syntax for all function parameters.

Function does not use -e (extended statistics) flag, use assertModuleKeyValue() for the full interface of arbitrary module.

assertRaster3dMinMax(map, refmin, refmax, msg=None)[source]

Test that 3D raster map minimum and maximum are within limits.

Minimum and maximum values are obtained from r3.info. Map minimum 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 assertRaster3DFitsUnivar() or assertRaster3DFitsInfo()

assertRasterDoesNotExist(name, msg=None)[source]

Checks if the raster map does not exist in current mapset

assertRasterExists(name, msg=None)[source]

Checks if the raster map exists in current mapset

assertRasterFitsInfo(raster, reference, precision=None, msg=None)[source]

Test that raster map has the values obtained by r.info module.

The function does not require all values from r.info. Only the provided values are tested. Typical example is checking minimum, maximum and type of the map:

minmax = 'min=0\nmax=1451\ndatatype=FCELL'
self.assertRasterFitsInfo(raster='elevation', reference=minmax)

Use keyword arguments syntax for all function parameters.

This function supports values obtained -r (range) and -e (extended metadata) flags.

assertRasterFitsUnivar(raster, reference, precision=None, msg=None)[source]

Test that raster map has the values obtained by r.univar module.

The function does not require all values from r.univar. Only the provided values are tested. Typical example is checking minimum, maximum and number of NULL cells in the map:

values = 'null_cells=0\nmin=55.5787925720215\nmax=156.329864501953'
self.assertRasterFitsUnivar(raster='elevation', reference=values)

Use keyword arguments syntax for all function parameters.

Does not -e (extended statistics) flag, use assertModuleKeyValue() for the full interface of arbitrary module.

assertRasterMinMax(map, refmin, refmax, msg=None)[source]

Test that raster map minimum and maximum are within limits.

Minimum and maximum values are obtained from r.info. Map minimum 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()

assertRasters3dDifference(actual, reference, statistics, precision, msg=None)[source]

Test statistical values of difference of reference and actual rasters

For cases when you are interested in no or minimal difference, use assertRastersNoDifference() instead.

This method should not be used to test r3.mapcalc or r3.univar.

assertRasters3dNoDifference(actual, reference, precision, statistics=None, msg=None)[source]

Test that actual raster is not different from reference raster

Method behaves in the same way as assertRasterFitsUnivar() but works on difference reference - actual. If statistics is not given dict(min=-precision, max=precision) is used.

assertRastersDifference(actual, reference, statistics, precision, msg=None)[source]

Test statistical values of difference of reference and actual rasters

For cases when you are interested in no or minimal difference, use assertRastersNoDifference() instead.

This method should not be used to test r.mapcalc or r.univar.

Beware - comparison is performed on overall statistics and thus differences in individual cell values not changing overall statistics might go unnoticed. Use assertRastersEqual() for cell to cell equivalence testing.

assertRastersEqual(actual, reference, precision=0, msg=None)[source]

Test that actual raster is equal to reference raster

Test compares if each cell value in actual raster is within precision value to reference raster. NULL values in both rasters are considered to be a match.

For CELL maps precision should be set to 0, for FCELL and DCELL maps it should be set to match precision of reference map (a positive number larger than 0).

Comparison is performed with r.mapcalc and r.info and thus is affected by current computational region.

assertRastersNoDifference(actual, reference, precision, statistics=None, msg=None)[source]

Test that actual raster is not different from reference raster

Method behaves in the same way as assertRasterFitsUnivar() but works on difference reference - actual. If statistics is not given dict(min=-precision, max=precision) is used.

Beware - comparison is performed on overall statistics and thus differences in individual cell values not changing overall statistics might go unnoticed. Use assertRastersEqual() for cell to cell equivalence testing.

assertVectorAsciiEqualsVectorAscii(actual, reference, remove_files=False, msg=None)[source]

Test that two GRASS ASCII vector files are equal.

assertVectorDoesNotExist(name, msg=None)[source]

Checks if the vector map does not exist in current mapset

assertVectorEqualsAscii(actual, reference, digits, precision, msg=None)[source]

Test that vector is equal to the vector stored in GRASS ASCII file.

assertVectorEqualsVector(actual, reference, digits, precision, msg=None)[source]

Test that two vectors are equal.

assertVectorExists(name, msg=None)[source]

Checks if the vector map exists in current mapset

assertVectorFitsExtendedInfo(vector, reference, msg=None)[source]

Test that raster map has the values obtained by v.info module.

This function uses -e flag of v.info module to get topology info, so the reference dictionary should contain appropriate set or subset of values (only the provided values are tested).

The most useful items for testing (considering circumstances of test invocation) are name, title, level and num_dblinks. (When testing storing of v.info -e metadata, the selection might be different.)

No precision is applied (no difference is required). So, this function is not suitable for testing items which are floating point number.

Use keyword arguments syntax for all function parameters.

assertVectorFitsRegionInfo(vector, reference, precision, msg=None)[source]

Test that raster map has the values obtained by v.info module.

This function uses -g flag of v.info module to get topology info, so the reference dictionary should contain appropriate set or subset of values (only the provided values are tested).

Use keyword arguments syntax for all function parameters.

assertVectorFitsTopoInfo(vector, reference, msg=None)[source]

Test that raster map has the values obtained by v.info module.

This function uses -t flag of v.info module to get topology info, so the reference dictionary should contain appropriate set or subset of values (only the provided values are tested).

A example of checking number of points:

topology = dict(points=10938, primitives=10938)
self.assertVectorFitsTopoInfo(vector='bridges', reference=topology)

Note that here we are checking also the number of primitives to prove that there are no other features besides points.

No precision is applied (no difference is required). So, this function is not suitable for testing items which are floating point number (no such items are currently in topological information).

Use keyword arguments syntax for all function parameters.

assertVectorFitsUnivar(map, column, reference, msg=None, layer=None, type=None, where=None, precision=None)[source]

Test that vector map has the values obtained by v.univar module.

The function does not require all values from v.univar. Only the provided values are tested. Typical example is checking minimum and maximum of a column:

minmax = 'min=0\nmax=1451'
self.assertVectorFitsUnivar(map='bridges', column='WIDTH',
                            reference=minmax)

Use keyword arguments syntax for all function parameters.

Does not support -d (geometry distances) flag, -e (extended statistics) flag and few other, use assertModuleKeyValue for the full interface of arbitrary module.

assertVectorInfoEqualsVectorInfo(actual, reference, precision, msg=None)[source]

Test that two vectors are equal according to v.info -tg.

This function does not test geometry itself just the region of the vector map and number of features.

assertVectorIsVectorBuffered(actual, reference, precision, msg=None)[source]

This method should not be used to test v.buffer, v.overlay or v.select.

assertVectorsNoAreaDifference(actual, reference, precision, layer=1, msg=None)[source]

Test statistical values of difference of reference and actual rasters

Works only for areas.

Use keyword arguments syntax for all function parameters.

This method should not be used to test v.overlay or v.select.

classmethod del_temp_region()[source]

Remove the temporary region.

Unsets WIND_OVERRIDE and removes any region named by it.

html_reports = False
longMessage = True
maxDiff = None
readable_names = False
classmethod runModule(module, expecting_stdout=False, **kwargs)[source]

Run PyGRASS module.

Runs the module and raises an exception if the module ends with non-zero return code. Usually, this is the same as testing the return code and raising exception but by using this method, you give testing framework more control over the execution, error handling and storing of output.

In terms of testing framework, this function causes a common error, not a test failure.

Raises

CalledModuleError – if the module failed

classmethod use_temp_region()[source]

Use temporary region instead of the standard one for this process.

If you use this method, you have to call it in setUpClass() and call del_temp_region() in tearDownClass(). By this you ensure that each test method will have its own region and will not influence other classes.

@classmethod
def setUpClass(self):
    self.use_temp_region()

@classmethod
def tearDownClass(self):
    self.del_temp_region()

You can also call the methods in setUp() and tearDown() if you are using them.

Copies the current region to a temporary region with g.region save=, then sets WIND_OVERRIDE to refer to that region.

gunittest.checkers module

GRASS Python testing framework checkers

Copyright (C) 2014 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS GIS for details.

authors

Vaclav Petras, Soeren Gebbert

gunittest.checkers.check_text_ellipsis(reference, actual) → bool[source]
>>> check_text_ellipsis(
...     "Vector map <...> contains ... points.",
...     "Vector map <bridges> contains 5268 points.",
... )
True
>>> check_text_ellipsis(
...     "user: ...\\nname: elevation", "user: some_user\\nname: elevation"
... )
True
>>> check_text_ellipsis("user: ...\\nname: elevation", "user: \\nname: elevation")
False

The ellipsis is always considered even if it is followed by another dots. Consequently, a dot at the end of the sentence with preceding ellipsis will work as well as a line filled with undefined number of dots.

>>> check_text_ellipsis("The result is ....", "The result is 25.")
True
>>> check_text_ellipsis("max ..... ...", "max ....... 6")
True

However, there is no way how to express that the dot should be in the beginning and the ellipsis is at the end of the group of dots.

>>> check_text_ellipsis("The result is ....", "The result is .25")
False

The matching goes over lines (TODO: should this be changed?): >>> check_text_ellipsis(“a=11nb=…”, “a=11nb=22n”) True

This function is based on regular expression containing .+ but no other regular expression matching will be done.

>>> check_text_ellipsis("Result: [569] (...)", "Result: 9 (too high)")
False
gunittest.checkers.check_text_ellipsis_doctest(reference, actual)[source]
>>> check_text_ellipsis_doctest(
...     "user: ...\nname: elevation", "user: some_user\nname: elevation"
... )
True
>>> check_text_ellipsis_doctest(
...     "user: ...\nname: elevation", "user: \nname: elevation"
... )
True

This function is using doctest’s function to check the result, so we will discuss here how the underlying function behaves.

>>> checker = doctest.OutputChecker()
>>> checker.check_output(
...     "user: some_user\nname: elevation",
...     "user: some_user\nname: elevation",
...     optionflags=None,
... )
True
>>> checker.check_output(
...     "user: user1\nname: elevation",
...     "user: some_user\nname: elevation",
...     optionflags=doctest.ELLIPSIS,
... )
False
>>> checker.check_output(
...     "user: ...\nname: elevation",
...     "user: some_user\nname: elevation",
...     optionflags=doctest.ELLIPSIS,
... )
True

The ellipsis matches also an empty string, so the following matches:

>>> checker.check_output(
...     "user: ...\nname: elevation",
...     "user: \nname: elevation",
...     optionflags=doctest.ELLIPSIS,
... )
True

It is robust concerning misspelled matching string but does not allow ellipsis followed by a dot, e.g. at the end of the sentence:

>>> checker.check_output(
...     "user: ....\nname: elevation",
...     "user: some_user\nname: elevation",
...     optionflags=doctest.ELLIPSIS,
... )
False
gunittest.checkers.diff_keyvalue(dict_a, dict_b, precision, def_equal=<function values_equal>, key_equal=None, a_is_subset=False)[source]

Determine the difference of two dictionaries.

The function returns missing keys and different values for common keys:

>>> a = {"c": 2, "b": 3, "a": 4}
>>> b = {"c": 1, "b": 3, "d": 5}
>>> diff_keyvalue(a, b, precision=0)
(['d'], ['a'], [('c', 2, 1)])

You can provide only a subset of values in dict_a, in this case first item in tuple is an emptu list:

>>> diff_keyvalue(a, b, a_is_subset=True, precision=0)
([], ['a'], [('c', 2, 1)])

This function behaves the same as keyvalue_equals().

Returns

A tuple of lists, fist is list of missing keys in dict_a, second missing keys in dict_b and third is a list of mismatched values as tuples (key, value_from_a, value_from_b)

Return type

(list, list, list)

Comparing to the Python difflib package this function does not create any difference output. It just returns the dictionaries. Comparing to the Python unittest assertDictEqual(), this function does not issues error or exception, it just determines what it the difference.

gunittest.checkers.file_md5(filename)[source]

Get MD5 (check) sum of a file.

gunittest.checkers.files_equal_md5(filename_a, filename_b)[source]

Check equality of two files according to their MD5 sums

gunittest.checkers.keyvalue_equals(dict_a, dict_b, precision, def_equal=<function values_equal>, key_equal=None, a_is_subset=False)[source]

Compare two dictionaries.

Note

Always use keyword arguments for all parameters with defaults. It is a good idea to use keyword arguments also for the first two parameters.

An example of key-value texts comparison:

>>> keyvalue_equals(
...     text_to_keyvalue(
...         '''a: Hello
... b: 1.0
... c: 1,2,3,4,5
... d: hello,8,0.1'''
...     ),
...     text_to_keyvalue(
...         '''a: Hello
... b: 1.1
... c: 1,22,3,4,5
... d: hello,8,0.1'''
...     ),
...     precision=0.1,
... )
False
Parameters
  • dict_a – first dictionary

  • dict_b – second dictionary

  • precision – precision with which the floating point values are compared (passed to equality functions)

  • def_equal (callable) – function used for comparison by default

  • key_equal (dict) – dictionary of functions used for comparison of specific keys, def_equal is used for the rest, keys in dictionary are keys in dict_a and dict_b dictionaries, values are the functions used to comapare the given key

  • a_is_subsetTrue if dict_a is a subset of dict_b, False otherwise

Returns

True if identical, False if different

Use diff_keyvalue() to get information about differeces. You can use this function to find out if there is a difference and then use diff_keyvalue() to determine all the differences between dictionaries.

gunittest.checkers.main()[source]

Run the doctest

gunittest.checkers.proj_info_equals(text_a, text_b)[source]

Test if two PROJ_INFO texts are equal.

gunittest.checkers.proj_units_equals(text_a, text_b)[source]

Test if two PROJ_UNITS texts are equal.

gunittest.checkers.text_file_md5(filename, exclude_lines=None, exclude_re=None, prepend_lines=None, append_lines=None)[source]

Get a MD5 (check) sum of a text file.

Works in the same way as file_md5() function but ignores newlines characters and excludes lines from the file as well as prepend or append them if requested.

Parameters
  • exclude_lines – list of strings to be excluded (newline characters should not be part of the strings)

  • exclude_re – regular expression string; lines matching this regular expression will not be considered

  • prepend_lines – list of lines to be prepended to the file before computing the sum

  • append_lines – list of lines to be appended to the file before computing the sum

gunittest.checkers.text_to_keyvalue(text, sep=':', val_sep=', ', functions=None, skip_invalid=False, skip_empty=False, from_string=<function value_from_string>)[source]

Convert test to key-value pairs (dictionary-like KeyValue object).

Converts a key-value text file, where entries are separated by newlines and the key and value are separated by sep, into a key-value dictionary and discovers/uses the correct data types (float, int or string) for values.

Besides key-value pairs it also parses values itself. Value is created with the best fitting type using value_from_string() function by default. When val_sep is present in value part, the resulting value is a list of values.

Parameters
  • text – string to convert

  • sep – character that separates the keys and values

  • val_sep – character that separates the values of a single key

  • functions – list of functions to apply on the resulting dictionary

  • skip_invalid – skip all lines which does not contain separator

  • skip_empty – skip empty lines

  • from_string – a function used to convert strings to values, use lambda x: x for no conversion

Returns

a dictionary representation of text

Return type

grass.script.core.KeyValue or dict

And example of converting text with text, floats, integers and list to a dictionary:

>>> sorted(
...     text_to_keyvalue(
...         '''a: Hello
... b: 1.0
... c: 1,2,3,4,5
... d : hello,8,0.1'''
...     ).items()
... )  # sorted items from the dictionary
[('a', 'Hello'), ('b', 1.0), ('c', [1, 2, 3, 4, 5]), ('d', ['hello', 8, 0.1])]

Warning

And empty string is a valid input because empty dictionary is a valid dictionary. You need to test this separately according to the circumstances.

gunittest.checkers.unify_projection(dic)[source]

Unifies names of projections.

Some projections are referred using different names like ‘Universal Transverse Mercator’ and ‘Universe Transverse Mercator’. This function replaces synonyms by a unified name.

Example of common typo in UTM replaced by correct spelling:

>>> unify_projection({"name": ["Universe Transverse Mercator"]})
{'name': ['Universal Transverse Mercator']}
Parameters

dic – The dictionary containing information about projection

Returns

The dictionary with the new values if needed or a copy of old one

gunittest.checkers.unify_units(dic)[source]

Unifies names of units.

Some units have different spelling although they are the same units. This functions replaces different spelling options by unified one.

Example of British English spelling replaced by US English spelling:

>>> unify_units({"units": ["metres"], "unit": ["metre"]})  
{'units': ['meters'], 'unit': ['meter']}
Parameters

dic – The dictionary containing information about units

Returns

The dictionary with the new values if needed or a copy of old one

gunittest.checkers.value_from_string(value)[source]

Create value of a most fitting type from a string.

Type conversions are applied in order int, float, string where string is no conversion.

>>> value_from_string("1")
1
>>> value_from_string("5.6")
5.6
>>> value_from_string("  5.6          ")
5.6
>>> value_from_string("hello")
'hello'
gunittest.checkers.values_equal(value_a, value_b, precision=1e-06)[source]
>>> values_equal(1.022, 1.02, precision=0.01)
True
>>> values_equal([1.2, 5.3, 6.8], [1.1, 5.2, 6.9], precision=0.2)
True
>>> values_equal(7, 5, precision=2)
True
>>> values_equal(1, 5.9, precision=10)
True
>>> values_equal("Hello", "hello")
False

gunittest.gmodules module

Specialized interfaces for invoking modules for testing framework

Copyright (C) 2014 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS GIS for details.

authors

Vaclav Petras, Soeren Gebbert

class gunittest.gmodules.SimpleModule(cmd, *args, **kargs)[source]

Bases: grass.pygrass.modules.interface.module.Module

Simple wrapper around pygrass.modules.Module to make sure that run_, finish_, stdout and stderr are set correctly.

>>> mapcalc = SimpleModule("r.mapcalc", expression="test_a = 1", overwrite=True)
>>> mapcalc.run()
Module('r.mapcalc')
>>> mapcalc.returncode
0
>>> colors = SimpleModule("r.colors", map="test_a", rules="-", stdin_="1 red")
>>> colors.run()
Module('r.colors')
>>> colors.returncode
0
>>> str(colors.inputs.stdin)
'1 red'
>>> str(colors.outputs.stdout)
''
>>> colors.outputs.stderr.strip()
"Color table for raster map <test_a> set to 'rules'"
gunittest.gmodules.call_module(module, stdin=None, merge_stderr=False, capture_stdout=True, capture_stderr=True, **kwargs)[source]

Run module with parameters given in kwargs and return its output.

>>> print(call_module("g.region", flags="pg"))  
projection=...
zone=...
n=...
s=...
w=...
>>> call_module("m.proj", flags="i", input="-", stdin="50.0 41.5")
'8642890.65|6965155.61|0.00\n'
>>> call_module(
...     "g.region", aabbbccc="notexist"
... )  
Traceback (most recent call last):
    ...
CalledModuleError: Module run g.region ... ended with error

If stdin is not set and kwargs contains input with value set to - (dash), the function raises an error.

Note that input nor output parameters are used by this function itself, these are usually module parameters which this function just passes to it. However, when input is in parameters the function checks if its values is correct considering value of stdin parameter.

Parameters
  • module (str) – module name

  • stdin – string to be used as module standard input (stdin) or None

  • merge_stderr – if the standard error output should be merged with stdout

  • kwargs – module parameters

Returns

module standard output (stdout) as string or None if capture_stdout is False

Raises
  • CalledModuleError – if module return code is non-zero

  • ValueError – if the parameters are not correct

Note

The data read is buffered in memory, so do not use this method if the data size is large or unlimited.

gunittest.gutils module

Utilities related to GRASS GIS for GRASS Python testing framework

Copyright (C) 2014 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS GIS for details.

authors

Vaclav Petras

gunittest.gutils.get_current_mapset()[source]

Get curret mapset name as a string

gunittest.gutils.is_map_in_mapset(name, type, mapset=None) → bool[source]

Check is map is present in the mapset (current mapset by default)

This function is different from what we would expect in GRASS because it cares only about specific mapset, the current one by default, and it does not care that the map is accessible in other mapset.

Parameters
  • name – name of the map

  • type – data type (‘raster’, ‘raster3d’, and ‘vector’)

gunittest.invoker module

GRASS Python testing framework test files invoker (runner)

Copyright (C) 2014 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS GIS for details.

authors

Vaclav Petras

class gunittest.invoker.GrassTestFilesInvoker(start_dir, clean_mapsets=True, clean_outputs=True, clean_before=True, testsuite_dir='testsuite', file_anonymizer=None, timeout=None)[source]

Bases: object

A class used to invoke test files and create the main report

Parameters
  • clean_mapsets (bool) – if the mapsets should be removed

  • clean_outputs (bool) – meaning is unclear: random tests outputs, saved images from maps, profiling?

  • clean_before (bool) – if mapsets, outputs, and results should be removed before the tests start (advantageous when the previous run left everything behind)

  • timeout (float) – maximum duration of one test in seconds

run_in_location(gisdbase, location, location_type, results_dir, exclude)[source]

Run tests in a given location

Returns an object with counting attributes of GrassTestFilesCountingReporter, i.e., a file-oriented reporter as opposed to testsuite-oriented one. Use only the attributes related to the summary, such as file_pass_per, not to one file as these will simply contain the last executed file.

gunittest.invoker.maketrans()

Return a translation table usable for str.translate().

If there is only one argument, it must be a dictionary mapping Unicode ordinals (integers) or characters to Unicode ordinals, strings or None. Character keys will be then converted to ordinals. If there are two arguments, they must be strings of equal length, and in the resulting dictionary, each character in x will be mapped to the character at the same position in y. If there is a third argument, it must be a string, whose characters will be mapped to None in the result.

gunittest.invoker.update_keyval_file(filename, module, returncode)[source]

gunittest.loader module

GRASS Python testing framework test loading functionality

Copyright (C) 2014 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS GIS for details.

authors

Vaclav Petras, Edouard Choinière

class gunittest.loader.GrassTestLoader(grass_location)[source]

Bases: unittest.loader.TestLoader

Class handles GRASS-specific loading of test modules.

all_tests_value = 'all'
discover(start_dir, pattern='test*.py', top_level_dir=None)[source]

Load test modules from in GRASS testing framework way.

files_in_testsuite = '*.py'
skip_dirs = ['.git', '.svn', 'dist.*', 'bin.*', 'OBJ.*']
testsuite_dir = 'testsuite'
universal_tests_value = 'universal'
class gunittest.loader.GrassTestPythonModule(name, module, file_type, tested_dir, file_dir, file_path, abs_file_path)

Bases: tuple

Create new instance of GrassTestPythonModule(name, module, file_type, tested_dir, file_dir, file_path, abs_file_path)

abs_file_path

Alias for field number 6

file_dir

Alias for field number 4

file_path

Alias for field number 5

file_type

Alias for field number 2

module

Alias for field number 1

name

Alias for field number 0

tested_dir

Alias for field number 3

gunittest.loader.discover_modules(start_dir, skip_dirs, testsuite_dir, grass_location, all_locations_value, universal_location_value, import_modules, add_failed_imports=True, file_pattern=None, file_regexp=None, exclude=None)[source]

Find all test files (modules) in a directory tree.

The function is designed specifically for GRASS testing framework test layout. It expects some directories to have a “testsuite” directory where test files (test modules) are present. Additionally, it also handles loading of test files which specify in which location they can run.

Parameters
  • start_dir – directory to start the search

  • file_pattern – pattern of files in a test suite directory (using Unix shell-style wildcards)

  • skip_dirs – directories not to recurse to (e.g. .svn)

  • testsuite_dir – name of directory where the test files are found, the function will not recurse to this directory

  • grass_location – string with an accepted location type (category, shortcut)

  • all_locations_value – string used to say that all locations should be loaded (grass_location can be set to this value)

  • universal_location_value – string marking a test as location-independent (same as not providing any)

  • import_modules – True if files should be imported as modules, False if the files should be just searched for the needed values

Returns

a list of GrassTestPythonModule objects

gunittest.loader.fnmatch_exclude_with_base(files: Iterable[str], base: str | os.PathLike, exclude: Iterable[str | os.PathLike | PurePath]) → list[str][source]

Return list of files not matching any exclusion pattern

Parameters
  • files – list of file names

  • base – directory (path) where the files are

  • exclude – list of fnmatch glob patterns for exclusion

gunittest.reporters module

GRASS Python testing framework module for report generation

Copyright (C) 2014 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS GIS for details.

authors

Vaclav Petras

class gunittest.reporters.FileAnonymizer(paths_to_remove, remove_gisbase=True, remove_gisdbase=False)[source]

Bases: object

anonymize(filenames)[source]
class gunittest.reporters.GrassTestFilesCountingReporter[source]

Bases: object

end_file_test(returncode, **kwargs)[source]
finish()[source]
start(results_dir)[source]
start_file_test(module)[source]
class gunittest.reporters.GrassTestFilesHtmlReporter(file_anonymizer, main_page_name='index.html')[source]

Bases: gunittest.reporters.GrassTestFilesCountingReporter

end_file_test(module, cwd, returncode, stdout, stderr, test_summary, timed_out=None)[source]
finish()[source]
start(results_dir)[source]
start_file_test(module)[source]
unknown_number = '<span style="font-size: 60%">unknown</span>'
class gunittest.reporters.GrassTestFilesKeyValueReporter(info=None)[source]

Bases: gunittest.reporters.GrassTestFilesCountingReporter

end_file_test(module, cwd, returncode, stdout, stderr, test_summary, timed_out=None)[source]
finish()[source]
start(results_dir)[source]
class gunittest.reporters.GrassTestFilesMultiReporter(reporters, forgiving=False)[source]

Bases: object

Interface to multiple repoter objects

For start and finish of the tests and of a test of one file, it calls corresponding methods of all contained reporters. For all other attributes, it returns attribute of a first reporter which has this attribute using the order in which the reporters were provided.

end_file_test(**kwargs)[source]
finish()[source]
start(results_dir)[source]
start_file_test(module)[source]
class gunittest.reporters.GrassTestFilesTextReporter(stream)[source]

Bases: gunittest.reporters.GrassTestFilesCountingReporter

end_file_test(module, cwd, returncode, stdout, stderr, test_summary, timed_out=None)[source]
finish()[source]
start(results_dir)[source]
start_file_test(module)[source]
class gunittest.reporters.NoopFileAnonymizer[source]

Bases: object

anonymize(filenames)[source]
class gunittest.reporters.TestsuiteDirReporter(main_page_name, testsuite_page_name='index.html', top_level_testsuite_page_name=None)[source]

Bases: object

report_for_dir(root, directory, test_files)[source]
report_for_dirs(root, directories)[source]
gunittest.reporters.color_error_line(line)[source]
gunittest.reporters.get_html_test_authors_table(directory, tests_authors)[source]
gunittest.reporters.get_source_url(path, revision, line=None)[source]
Parameters
  • path – directory or file path relative to remote repository root

  • revision – SVN revision (should be a number)

  • line – line in the file (should be None for directories)

gunittest.reporters.get_svn_info()[source]

Get important information from svn info

Returns

SVN info as dictionary or None if it is not possible to obtain it

gunittest.reporters.get_svn_path_authors(path, from_date=None)[source]
Returns

a set of authors

gunittest.reporters.get_svn_revision()[source]

Get SVN revision number

Returns

SVN revision number as string or None if it is not possible to get

gunittest.reporters.html_escape(text)[source]

Escape '&', '<', and '>' in a string of data.

gunittest.reporters.html_file_preview(filename)[source]
gunittest.reporters.html_unescape(text)[source]

Unescape '&amp;', '&lt;', and '&gt;' in a string of data.

gunittest.reporters.keyvalue_to_text(keyvalue, sep='=', vsep='\n', isep=',', last_vertical=None)[source]
gunittest.reporters.percent_to_html(percent)[source]
gunittest.reporters.replace_in_file(file_path, pattern, repl)[source]
Parameters

repl – a repl parameter of re.sub() function

gunittest.reporters.returncode_to_html_sentence(returncode)[source]
gunittest.reporters.returncode_to_html_text(returncode, timed_out=None)[source]
gunittest.reporters.returncode_to_success_html_par(returncode)[source]
gunittest.reporters.success_to_html_percent(total, successes)[source]
gunittest.reporters.success_to_html_text(total, successes)[source]
gunittest.reporters.to_web_path(path)[source]

Replace OS dependent path separator with slash.

Path on MS Windows are not usable in links on web. For MS Windows, this replaces backslash with (forward) slash.

gunittest.reporters.wrap_stdstream_to_html(infile, outfile, module, stream)[source]
gunittest.reporters.years_ago(date, years)[source]

gunittest.runner module

Testing framework module for running tests in Python unittest fashion

Copyright (C) 2014 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS GIS for details.

authors

Vaclav Petras

File content taken from Python’s unittest.runner, it will be used as a template. It is not expected that something will left.

class gunittest.runner.GrassTestRunner(stream=<_io.TextIOWrapper name='<stderr>' mode='w' encoding='utf-8'>, descriptions=True, verbosity=1, failfast=False, buffer=False, result=None)[source]

Bases: object

run(test)[source]

Run the given test case or test suite.

class gunittest.runner.KeyValueTestResult(stream, test_type=None)[source]

Bases: gunittest.runner.TestResult

A test result class that can print formatted text results to a stream.

Used by TextTestRunner.

separator1 = '======================================================================'
separator2 = '----------------------------------------------------------------------'
setTimes(start_time, end_time, time_taken)[source]
stopTest(test)[source]

Called when the given test has been run

stopTestRun()[source]

Called once after all tests are executed.

See stopTest for a method called after each test.

class gunittest.runner.MultiTestResult(results, forgiving=False, descriptions=None, verbosity=None)[source]

Bases: gunittest.runner.TestResult

addError(test, err)[source]

Called when an error has occurred. ‘err’ is a tuple of values as returned by sys.exc_info().

addExpectedFailure(test, err)[source]

Called when an expected failure/error occurred.

addFailure(test, err)[source]

Called when an error has occurred. ‘err’ is a tuple of values as returned by sys.exc_info().

addSkip(test, reason)[source]

Called when a test is skipped.

addSuccess(test)[source]

Called when a test has completed successfully

addUnexpectedSuccess(test)[source]

Called when a test was expected to fail, but succeed.

printErrors()[source]

Called by TestRunner after test run

setTimes(start_time, end_time, time_taken)[source]
startTest(test)[source]

Called when the given test is about to be run

startTestRun()[source]

Called once before any tests are executed.

See startTest for a method called before each test.

stopTest(test)[source]

Called when the given test has been run

stopTestRun()[source]

Called once after all tests are executed.

See stopTest for a method called after each test.

class gunittest.runner.TestResult(stream=None, descriptions=None, verbosity=None)[source]

Bases: unittest.result.TestResult

addSuccess(test)[source]

Called when a test has completed successfully

setTimes(start_time, end_time, time_taken)[source]
class gunittest.runner.TextTestResult(stream, descriptions, verbosity)[source]

Bases: gunittest.runner.TestResult

A test result class that can print formatted text results to a stream.

Used by TextTestRunner.

addError(test, err)[source]

Called when an error has occurred. ‘err’ is a tuple of values as returned by sys.exc_info().

addExpectedFailure(test, err)[source]

Called when an expected failure/error occurred.

addFailure(test, err)[source]

Called when an error has occurred. ‘err’ is a tuple of values as returned by sys.exc_info().

addSkip(test, reason)[source]

Called when a test is skipped.

addSuccess(test)[source]

Called when a test has completed successfully

addUnexpectedSuccess(test)[source]

Called when a test was expected to fail, but succeed.

getDescription(test)[source]
printErrorList(flavour, errors)[source]
printErrors()[source]

Called by TestRunner after test run

separator1 = '======================================================================'
separator2 = '----------------------------------------------------------------------'
setTimes(start_time, end_time, time_taken)[source]
startTest(test)[source]

Called when the given test is about to be run

stopTestRun()[source]

Called once after all tests are executed.

See stopTest for a method called after each test.

gunittest.utils module

GRASS Python testing framework utilities (general and test-specific)

Copyright (C) 2014 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS GIS for details.

authors

Vaclav Petras

gunittest.utils.add_gitignore_to_dir(directory)[source]
gunittest.utils.do_doctest_gettext_workaround()[source]

Setups environment for doing a doctest with gettext usage.

When using gettext with dynamically defined underscore function (_("For translation")), doctest does not work properly. One option is to use import as instead of dynamically defined underscore function but this would require change all modules which are used by tested module. This should be considered for the future. The second option is to define dummy underscore function and one other function which creates the right environment to satisfy all. This is done by this function.

gunittest.utils.ensure_dir(directory)[source]

Create all directories in the given path if needed.

gunittest.utils.safe_repr(obj, short=False)[source]
gunittest.utils.silent_rmtree(filename)[source]

Remove the file but do nothing if file does not exist.

gunittest.utils.xfail_windows(test_item)[source]

Marks a test as an expected failure or error only on Windows Equivalent to applying @unittest.expectedFailure only when running on Windows.

Module contents

GRASS Python testing framework module for running from command line

Copyright (C) 2014 by the GRASS Development Team This program is free software under the GNU General Public License (>=v2). Read the file COPYING that comes with GRASS GIS for details.

authors

Vaclav Petras, Soeren Gebbert

Initial version of gunittest was created during Google Summer of Code 2014 by Vaclav Petras as a student and Soeren Gebbert as a mentor.