Note: A new GRASS GIS stable version has been released: GRASS GIS 7.8. Go directly to the new manual page here
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 |
---|
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.
Test the existence of a file.
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()
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.
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.
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.
Test that module fails with a non-zero return code.
Works like assertModule() but expects module to fail.
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.
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().
Checks if the 3D raster map does not exist in current mapset
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).
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.
Test that 3D raster map minimum and maximum are within limits.
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()
Checks if the raster map does not exist in current mapset
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 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.
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.
Test that raster map minimum and maximum are within limits.
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()
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.
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.
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.
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.
Test that two GRASS ASCII vector files are equal.
Checks if the vector map does not exist in current mapset
Test that vector is equal to the vector stored in GRASS ASCII file.
Test that two vectors are equal.
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.
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.
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.
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.
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.
This method should not be used to test v.buffer, v.overlay or v.select.
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.
Remove the temporary region.
Unsets WIND_OVERRIDE and removes any region named by it.
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 |
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.
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 |
---|
>>> 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
>>> 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
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.
Check equality of two files according to their MD5 sums
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: |
|
---|---|
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.
Test if two PROJ_UNITS texts are equal.
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: |
|
---|
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: |
|
---|---|
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.
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 |
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 |
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'
>>> 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
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 |
---|
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.popen.returncode
0
>>> colors = SimpleModule('r.colors',
... map='test_a', rules='-', stdin_='1 red')
>>> colors.run()
Module('r.colors')
>>> colors.popen.returncode
0
>>> str(colors.inputs.stdin)
'1 red'
>>> str(colors.outputs.stdout)
''
>>> colors.outputs.stderr.strip()
u"Color table for raster map <test_a> set to 'rules'"
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
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: |
|
---|---|
Returns: | module standard output (stdout) as string or None if apture_stdout is False |
Raises: |
|
Note
The data read is buffered in memory, so do not use this method if the data size is large or unlimited.
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 |
---|
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: |
|
---|
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 |
---|
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 |
---|
Bases: unittest.loader.TestLoader
Class handles GRASS-specific loading of test modules.
Load test modules from in GRASS testing framework way.
Bases: tuple
GrassTestPythonModule(name, module, file_type, tested_dir, file_dir, abs_file_path)
Alias for field number 5
Alias for field number 4
Alias for field number 2
Alias for field number 1
Alias for field number 0
Alias for field number 3
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: |
|
---|---|
Returns: | a list of GrassTestPythonModule objects |
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 |
---|
Bases: object
Bases: gunittest.reporters.GrassTestFilesCountingReporter
Bases: object
Bases: object
Parameters: |
|
---|
Get important information from svn info
Returns: | SVN info as dictionary or None if it is not possible to obtain it |
---|
Returns: | a set of authors |
---|
Get SVN revision number
Returns: | SVN revision number as string or None if it is not possible to get |
---|
Unescape '&', '<', and '>' in a string of data.
Parameters: | repl – a repl parameter of re.sub() function |
---|
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.
Bases: object
Bases: gunittest.runner.TestResult
A test result class that can print formatted text results to a stream.
Used by TextTestRunner.
Bases: gunittest.runner.TestResult
Bases: unittest.result.TestResult
Bases: gunittest.runner.TestResult
A test result class that can print formatted text results to a stream.
Used by TextTestRunner.
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 |
---|
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.
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.
Note: A new GRASS GIS stable version has been released: GRASS GIS 7.8. Go directly to the new manual page here
Help Index | Topics Index | Keywords Index | Full Index
© 2003-2020 GRASS Development Team, GRASS GIS 7.6.2dev Reference Manual