Commit 0a4abf2d authored by Jessica Palka's avatar Jessica Palka
Browse files

Biggest changes: Corrected the relative path to an absolute path, added the...

Biggest changes: Corrected the relative path to an absolute path, added the beginning of the second test case and extended the test suite to execute the second test case, only when the first test case was successful.
parent cb1cc079
......@@ -13,8 +13,13 @@ the TIFF-image "L8_2bands_extract10x11_array.txt" in the directory "../tests/dat
is used. The outputs of the "GeoArray"-class functions are tested against the well
known properties of the test-image.
Note that the tests in the test case "Test_GeoarrayAppliedOnPathArray" follow the same
order as in the "GeoArray"-class (but they are executed in alphanumeric order).
The tests are divided into a total of two test cases. The order of execution is as
follows:
test case 1 (path) - test case 2 (path) - test case 1 (array) - test case 2 (array).
Note that the tests in the test case "Test_GeoarrayAppliedOnPathArray" and
"Test_GeoarrayFunctions" follow - with a few exceptions - the same order as in the
"GeoArray"-class (but they are executed in alphanumeric order inside the test case).
Functions that depend on each other are tested together.
Program started in Mai 2017.
......@@ -25,20 +30,30 @@ __author__ = 'Jessica Palka'
# Imports from the python standard library
import unittest
# Imports from the python standard library.
from collections import OrderedDict
import dill
import geopandas
import numpy as np
import os.path
import os
from os import path
import osgeo.osr
from unittest import TestLoader
import shapely
from shapely.geometry import Polygon
import time
import unittest
from unittest import TestLoader
# Imports regarding the created python module
# Imports regarding the created python module.
import geoarray
from geoarray import GeoArray
from geoarray import masks
from py_tools_ds.ptds.geo.vector import geometry
# Path of the tests-directory in the geoarray-package.
tests_path = os.path.abspath(path.join(geoarray.__file__,"../.."))
###################################################################################
# Test case: Test_GeoarrayAppliedOnPathArray
......@@ -51,7 +66,6 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
test. Note that the function set_gdalDataset_meta is tested indirectly by a
couple of tests in the test case (a notation is applied).
Since the "GeoArray"-class can be instanced with a file path or with a numpy
array and the corresponding geoinformation, the tests in this test case will
be executed two times in a row (the test case is parametrized). The order is
......@@ -81,18 +95,22 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
# First line of the test case output to ease the distinction between the test cases using different
# instances of the "GeoArray"-class.
print(' ')
print("GEOARRAY INSTANCED WITH {k}:".format(k=('PATH', 'NUMPY ARRAY')[k]))
print("Geoarray instanced with {l}, TEST CASE 1 ('basic functions'):".format(l=('PATH', 'NUMPY ARRAY')[cls.k]))
# Creating the instances of the "GeoArray"-class.
if cls.k == 0:
# Creating the "GeoArray"-instance with a FILE PATH.
cls.L8_2bands_extract10x11 = "../tests/data/L8_2bands_extract10x11.tif"
cls.L8_2bands_extract10x11 = "".join((tests_path,"/tests/data/L8_2bands_extract10x11.tif"))
cls.testtiff = GeoArray(cls.L8_2bands_extract10x11)
# Serialize the "GeoArray"-class to the "data"-directory
with open("".join((tests_path,"/tests/data/testtiff_path.tmp")), "wb") as f:
dill.dump(cls.testtiff, f)
if cls.k == 1:
# Loading the TIFF-image array from the "data"-directory.
array_path = "../tests/data/L8_2bands_extract10x11_array.txt"
array_path = "".join((tests_path, "/tests/data/L8_2bands_extract10x11_array.txt"))
cls.L8_2bands_extract10x11 = np.loadtxt(array_path, 'float32').reshape(10, 11, 2)
# Change the pszProj4-string in a WKT-string.
......@@ -104,6 +122,10 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
cls.testtiff = GeoArray(cls.L8_2bands_extract10x11, geotransform=cls.given_geotransform,
projection=cls.given_projection, nodata=cls.given_nodata)
# Serialize the "GeoArray"-class to the "data"-directory
with open("".join((tests_path,"/tests/data/testtiff_array.tmp")),"wb") as f:
dill.dump(cls.testtiff, f)
cls.TiffIsInstanceOfGeoarray(cls)
cls.ArrOfTiffIsInMemory(cls)
......@@ -137,6 +159,7 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
testtiff_basicfunctions = (self.testtiff.arr, self.testtiff.is_inmem)
expected_conditions = ((None, False), (True, True))
equal_arr_L8 = np.array_equal(testtiff_basicfunctions[0], self.L8_2bands_extract10x11)
# FILE PATH
if isinstance(self.L8_2bands_extract10x11, str) and os.path.isfile(self.L8_2bands_extract10x11):
......@@ -153,13 +176,14 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
elif isinstance(self.L8_2bands_extract10x11, np.ndarray):
try:
assert (isinstance(testtiff_basicfunctions[0], np.ndarray) == expected_conditions[1][0]) and \
equal_arr_L8 and \
(testtiff_basicfunctions[1] == expected_conditions[1][1])
except (AssertionError, AttributeError):
self.skipTest(Test_GeoarrayAppliedOnPathArray,
reason="A numpy.ndarray is passed to 'GeoArray'. But the output of the functions "
"arr and is_inmem do not match the expected output "
"(arr == given array? %s, is_inmem: %s/%s)!"
% (np.array_equal(testtiff_basicfunctions[0], self.L8_2bands_extract10x11),
% (equal_arr_L8,
testtiff_basicfunctions[1], expected_conditions[1][1]))
else:
......@@ -295,12 +319,147 @@ class Test_GeoarrayAppliedOnPathArray(unittest.TestCase):
###################################################################################
# Test case: Test_GeoarrayFunctions
# TODO: Completing the test case!
class Test_GeoarrayFunctions(unittest.TestCase):
"""
*** !!!
Note that the class "Test_GeoarrayFunctions" is NOT complete. Furthermore,
part of the tests that are contained in this test case are not completely
independent - some dependencies that can be found in the source code of the
function that is being tested is not yet considered. A respective comment
can be found at the beginning of the affected tests in the "TODO"-statement. ***
The class "Test_GeoarrayFunctions" is the second test case of the
"test_geoarray"-script and tests the functions of the "GeoArray"-class that are
not yet tested in the first test case. Since the basic functions on which most
functions of the "GeoArray"-class depend on were already tested in test case 1,
the tests of test case 2 can be considered moderately independent from these
functions. Note that if an error, failure or skip occurs in test case 1, test
case 2 will not be executed. If test case 1 was successful, test case 2 will be
executed twice - like test case 1 test case 2 is parametrized. The order of
execution is as follows:
After the first test case is executed using the "GeoArray"-instance created
with a file path, the second test case is executed using the same instance.
The second execution of the test cases uses the "GeoArray"-instance created
with a numpy array.
"""
# Variable for the parametrization of the test case (the same variable as in test case 1).
k = 0
@classmethod
def setUpClass(cls):
# Adaption of the source code from the setUpClass of test case 1 to ease the distinction between
# the test cases using different instances of the "GeoArray"-class.
# First line of the test case output.
print(' ')
print("Geoarray instanced with {l}, TEST CASE 2 ('functions'):".format(l=('PATH', 'NUMPY ARRAY')[cls.k]))
# Opening the temporary serialized variables (see setUpClass of test case 1) to re-use in the new test case
# without the need to inherit the variables from test case 1.
if cls.k == 0:
with open("".join((tests_path, "/tests/data/testtiff_path.tmp")), "rb") as f:
cls.testtiff = dill.load(f)
if cls.k == 1:
with open("".join((tests_path, "/tests/data/testtiff_array.tmp")), "rb") as f:
cls.testtiff = dill.load(f)
@classmethod
def tearDownClass(cls):
# Removing the temporary serialized variables from the 'data'-directory. If test case 2 is not executed,
# the files will be removed at the end of this script in the "if __name__ == '__main__'"-code segment.
if cls.k == 0:
os.remove("".join((tests_path, "/tests/data/testtiff_path.tmp")))
if cls.k == 1:
os.remove("".join((tests_path, "/tests/data/testtiff_array.tmp")))
def test_BoxIsInstanceOfBoxObj(self):
"""
Testing the function: box.
Test, if the output of the box-function is an instance boxObj (class, defined in geometry.py, py_tools_ds).
"""
self.assertIsInstance(self.testtiff.box, geometry.boxObj)
def test_MaskNodataIsInstanceOfNoDataMask(self):
# TODO: Consider the dependency of mask_nodata on the calc_mask_nodata-function.
"""
Testing the function: mask_nodata.
Test, if the output of the mask_nodata-function is an instance of "NoDataMask"(class, defined in masks.py).
"""
self.assertIsInstance(self.testtiff.mask_nodata, masks.NoDataMask)
def test_MaskBaddataIsNone(self):
# TODO: Setting a baddata mask and testing, if mask_baddata is an instance of the BadDataMask-class (masks.py).
"""
Testing the function: mask_baddata.
Test, if the output of the mask_baddata-function is "None" since a baddata-mask is not set within the used
TIFF-image.
"""
self.assertIsNone(self.testtiff.mask_baddata)
def test_FootprintPolyIsInstanceOfShapely(self):
# TODO: Test the validation of the footprint_poly-function.
# TODO: Consider the dependencies of the footprint_poly-function on mask_nodata, boxObj.
"""
Testing the function: footprint_poly.
Test, if the output of the footprint_poly-function is an instance of shapely.geometry.
"""
self.assertIsInstance(self.testtiff.footprint_poly, shapely.geometry.Polygon)
def test_MetadataIsInstanceOfGeodataframe(self):
# TODO test, if the metadata-function gives an output
"""
Testing the function: metadata.
Test, if the output of the metadata-function is an instance of GeoDataFrame.
"""
self.assertIsInstance(self.testtiff.metadata, geopandas.GeoDataFrame)
# ----> TODO: Write tests for the remaining functions!
# Parametrizing the test case to run twice.
# Note that 'time.sleep(0.5)' is called several times throughout the following code segment to prevent that the
# standard output of the tests is mixed up with the generated print-commandos.
# Source: renzop, 04 March 2016, "Python Testing how to run parameterised Testcases and pass a parameter to setupClass".
# [Online]. URL: https://stackoverflow.com/questions/35773976/python-testing-how-to-run-parameterised-testcases-and-pass-a-parameter-to-setupc
# [Accessed 30 Mai 2017].
if __name__ == '__main__':
for k in range(0, 2, 1):
# Creating a test suite for the first test case
suite = unittest.TestSuite()
loader = TestLoader()
test = None
......@@ -309,10 +468,11 @@ if __name__ == '__main__':
tests = loader.loadTestsFromTestCase(test)
suite.addTest(tests)
time.sleep(0.5)
testResult = unittest.TextTestRunner(verbosity=1).run(suite)
# Source End
# Extending the display of the test result since the verbosity of the test case output is 1.
# Extending the display of the test result of test case 1 since the verbosity of the test case output is 1.
time.sleep(0.5)
print("Summary:", testResult)
print("Test successful (errors, failures)? ", testResult.wasSuccessful(),
......@@ -324,3 +484,32 @@ if __name__ == '__main__':
for j in range(0, len(testResult.skipped),1):
print(j+1, ".Skipping occurred in: ", testResult.skipped[j][0], sep="")
print("Reason for ", j+1, ".skip: ", testResult.skipped[j][1], sep="")
# If-else loop: Creating and executing the second test suite (created with the tests of the test case 2), only
# if the first test case was successful and no test was skipped. Otherwise, a note will be printed as output to
# inform the user that test case 2 was skipped. Additionally, the serialized variable "testtiff" from test
# case 1 will be removed in the else-statement.
if testResult.wasSuccessful() and testResult.skipped == []:
other_suite = unittest.TestSuite()
more_test = None
more_test = Test_GeoarrayFunctions
more_test.k = k
more_tests = loader.loadTestsFromTestCase(more_test)
other_suite.addTest(more_tests)
time.sleep(0.5)
more_testResult = unittest.TextTestRunner(verbosity=2).run(other_suite)
# TODO: Extent the output of test case 2 (similar to test case 1) and
# TODO: Change the verbosity of the TextTestRunner to 1
else:
if k == 0:
os.remove("".join((tests_path, "/tests/data/testtiff_path.tmp")))
if k == 1:
os.remove("".join((tests_path, "/tests/data/testtiff_array.tmp")))
print("Test case 2: Since %s error/ %s failure/ %s skip occured in the first test case the second test "
"case 'Test_GeoarrayFunctions' will be skipped."
%(len(testResult.errors), len(testResult.failures), len(testResult.skipped)))
time.sleep(0.5)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment