rabbl
rabbl

Reputation: 93

python unittest fails running all testMethods, while each testMethod runs well

I'm using PYCharm and unittest in python to test my Classes.

Running each testMethod one by one and all tests are passing well.
Running all tests together it fails with assertionErrors. The setup and teardown methods are set.

Here is the code of my testClass:

# -*- coding: utf-8 -*-

import unittest
import numpy as np
import os
import sys
from interpolation.interpolation import Interpolation
from StringIO import StringIO


class InterpolationTests(unittest.TestCase):

_interpolation = None

@classmethod
def setUpClass(cls):
    cls._interpolation = Interpolation()

@classmethod
def tearDownClass(cls):
    cls._interpolation = None

def test_load_valid_file(self):
    self._interpolation.from_file('./testfiles/valid.json')
    self.assertEqual('kriging', self._interpolation._method)
    self.assertEqual(1.0, self._interpolation._xMin)
    self.assertEqual(1.2, self._interpolation._xMax)
    self.assertEqual(2.1, self._interpolation._yMin)
    self.assertEqual(0.2, self._interpolation._yMax)
    self.assertEqual(12, self._interpolation._nX)
    self.assertEqual(13, self._interpolation._nY)
    self.assertEqual(2, len(self._interpolation._points))

    points = self._interpolation._points
    self.assertEqual(1.1, points[0]['x'])
    self.assertEqual(2.2, points[0]['y'])
    self.assertEqual(3.4, points[0]['value'])
    self.assertEqual(4.4, points[1]['x'])
    self.assertEqual(5.5, points[1]['y'])
    self.assertEqual(6.6, points[1]['value'])

def test_load_invalid_JSON_format(self):
    self._interpolation.from_file('./testfiles/invalid.json')
    saved_stdout = sys.stdout
    try:
        out = StringIO()
        sys.stdout = out
        self._interpolation.render_output()
        output = out.getvalue().strip()
        self.assertEqual('{"error":"Something went wrong with the json decoding"}',
                         output.encode('ascii', 'ignore'))
    finally:
        sys.stdout = saved_stdout

def test_load_empty_file(self):
    self._interpolation.from_file('./testfiles/empty.json')
    saved_stdout = sys.stdout
    try:
        out = StringIO()
        sys.stdout = out
        self._interpolation.render_output()
        output = out.getvalue().strip()
        self.assertEqual('{"error":"Something went wrong with the json decoding"}',
                         output.encode('ascii', 'ignore'))
    finally:
        sys.stdout = saved_stdout

def test_idw_with_file(self):
    self._interpolation.from_file('./testfiles/valid_idw.json')
    self._interpolation.calculate()
    self.assertEqual(50, len(self._interpolation._output))
    self.assertEqual(50, len(self._interpolation._output[0]))

def test_kriging(self):
    self._interpolation.from_file('./testfiles/valid.json')
    self._interpolation.calculate()
    self.assertEqual(13, len(self._interpolation._output))
    self.assertEqual(12, len(self._interpolation._output[0]))

def test_mean_with_file(self):
    self._interpolation.from_file('./testfiles/valid_mean.json')
    self._interpolation.calculate()
    self.assertEqual(60, len(self._interpolation._output))
    self.assertEqual(50, len(self._interpolation._output[0]))

def test_mean(self):
    mean = Interpolation.mean(10, 20, np.array([1.2, 1.3, 1.4, 1.6, 1.9]))
    self.assertEqual(20, len(mean))
    self.assertEqual(10, len(mean[1]))
    self.assertEqual(1.48, mean[1][2])

def test_gaussian(self):
    self._interpolation.from_file('./testfiles/valid_gaussian.json')
    self._interpolation.calculate()
    self.assertEqual(50, len(self._interpolation._output))
    self.assertEqual(50, len(self._interpolation._output[0]))

def test_with_two_points(self):
    self._interpolation.from_string(json_input='{"bounding_box":{"x_min":0,"x_max":10,"y_min":0,"y_max":10},"grid_size":{"n_x":10,"n_y":11},"point_values":[{"x":1,"y":5,"value":800},{"x":2,"y":8,"value":3}],"type":"gaussian"}')
    self._interpolation.calculate()
    self.assertEqual('Exception raised in calculation of method gaussian', self._interpolation._error_message)

if __name__ == '__main__':
    unittest.main()

Here is a part of the Results of the failing tests:

/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/bin/python2.7 "/Applications/PyCharm CE.app/Contents/helpers/pycharm/noserunner.py" /Users/Ralf/Projekte/inowas/inowas/py/pyprocessing/tests/test_interpolation.py
Testing started at 09:52 ...





..

..




Failure
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 329, in run
    testMethod()
  File "/Users/Ralf/Projekte/inowas/inowas/py/pyprocessing/tests/test_interpolation.py", line 77, in test_kriging
    self.assertEqual(13, len(self._interpolation._output))
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 513, in assertEqual
    assertion_func(first, second, msg=msg)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 506, in _baseAssertEqual
    raise self.failureException(msg)
AssertionError: 13 != 50
-------------------- >> begin captured stdout << ---------------------
<type 'exceptions.Exception'> Matrix is not positive definite

--------------------- >> end captured stdout << ----------------------

F

..

..

..

..




Failure
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 329, in run
    testMethod()
  File "/Users/Ralf/Projekte/inowas/inowas/py/pyprocessing/tests/test_interpolation.py", line 83, in test_mean_with_file
    self.assertEqual(60, len(self._interpolation._output))
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 513, in assertEqual
    assertion_func(first, second, msg=msg)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 506, in _baseAssertEqual
    raise self.failureException(msg)
AssertionError: 60 != 50

F

Failure
Traceback (most recent call last):
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 329, in run
    testMethod()
  File "/Users/Ralf/Projekte/inowas/inowas/py/pyprocessing/tests/test_interpolation.py", line 101, in test_with_two_points
    self.assertEqual('Exception raised in calculation of method gaussian', self._interpolation._error_message)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 513, in assertEqual
    assertion_func(first, second, msg=msg)
  File "/usr/local/Cellar/python/2.7.11/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/case.py", line 506, in _baseAssertEqual
    raise self.failureException(msg)
AssertionError: 'Exception raised in calculation of method gaussian' != 'Something went wrong with the json decoding'

F

======================================================================
FAIL: test_kriging (test_interpolation.InterpolationTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/Ralf/Projekte/inowas/inowas/py/pyprocessing/tests/test_interpolation.py", line 77, in test_kriging
    self.assertEqual(13, len(self._interpolation._output))
AssertionError: 13 != 50
-------------------- >> begin captured stdout << ---------------------
<type 'exceptions.Exception'> Matrix is not positive definite

--------------------- >> end captured stdout << ----------------------

======================================================================
FAIL: test_mean_with_file (test_interpolation.InterpolationTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/Ralf/Projekte/inowas/inowas/py/pyprocessing/tests/test_interpolation.py", line 83, in test_mean_with_file
    self.assertEqual(60, len(self._interpolation._output))
AssertionError: 60 != 50

======================================================================
FAIL: test_render_to_file (test_interpolation.InterpolationTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/Ralf/Projekte/inowas/inowas/py/pyprocessing/tests/test_interpolation.py", line 122, in test_render_to_file
    self.assertTrue(os.path.isfile(output_filename))
AssertionError: False is not true
-------------------- >> begin captured stdout << ---------------------
{"error":"Something went wrong with the json decoding"}

--------------------- >> end captured stdout << ----------------------


Ran 11 tests in 0.826s

FAILED (failures=5)


Process finished with exit code 0

Finally here is the Interpolation-Class:

#! /usr/env python

from pyKriging.krige import kriging
from sklearn.gaussian_process import GaussianProcess
import demjson
import numpy as np


class Interpolation:
    """The interpolation class"""

    _method = ""
    _xMin = 0.0
    _xMax = 0.0
    _yMin = 0.0
    _yMax = 0.0
    _nX = 0
    _nY = 0
    _dX = 0.0
    _dY = 0.0
    _X = []
    _Y = []
    _points = []
    _output = ""
    _json_output = ""
    _error = False
    _error_message = ""

    def __init__(self):
        pass

    def from_file(self, input_file):
        try:
            _file = open(input_file, 'r')
            json_input = _file.read()
        except IOError as exc:
            self._error = True
            self._error_message = str(exc)
            return
        except Exception as exc:
            self._error = True
            self._error_message = str(exc)
            return

        self.decode_json(json_input)

    def from_string(self, json_input):
        self.decode_json(json_input)

    def decode_json(self, json_input):
        try:
            json_dict = demjson.decode(json_input)
        except Exception as exc:
            self._error = True
            self._error_message = "Something went wrong with the json decoding"
            return

        if 'type' in json_dict:
            self._method = json_dict['type']

        if 'bounding_box' in json_dict:
            bounding_box = json_dict['bounding_box']

            if 'x_min' in bounding_box:
                self._xMin = float(bounding_box['x_min'])

            if 'x_max' in bounding_box:
                self._xMax = float(bounding_box['x_max'])

            if 'y_min' in bounding_box:
                self._yMin = float(bounding_box['y_min'])

            if 'y_max' in bounding_box:
                self._yMax = float(bounding_box['y_max'])

        if 'grid_size' in json_dict:
            grid_size = json_dict['grid_size']

            if 'n_x' in grid_size:
                self._nX = grid_size['n_x']

            if 'n_y' in grid_size:
                self._nY = grid_size['n_y']

        self._dX = (self._xMax - self._xMin) / self._nX
        self._dY = (self._yMax - self._yMin) / self._nY

        if 'point_values' in json_dict:
            self._points = json_dict['point_values']

        for point in self._points:
            if 'x' in point and 'y' in point:
                self._X.append([point['x'], point['y']])

            if 'value' in point:
                self._Y.append(point['value'])

    def calculate(self):
        if not self._error:
            try:
                if self._method == 'kriging':
                    self._output = self.kriging(self._nX, self._nY, self._X, self._Y, self._xMin, self._yMin, self._dX, self._dY)
                elif self._method == 'mean':
                    self._output = self.mean(self._nX, self._nY, self._Y)
                elif self._method == 'gaussian':
                    self._output = self.gaussian_process(self._nX, self._nY, self._X, self._Y, self._xMin, self._yMin, self._dX, self._dY)
                elif self._method == 'idw':
                    self._output = self.inverse_distance_weighting(self._nX, self._nY, self._X, self._Y, self._xMin, self._yMin, self._dX, self._dY)
                else:
                    self._error = True
                    self._error_message = 'Method %s is not supported' % self._method
            except:
                self._error = True
                self._error_message = 'Exception raised in calculation of method %s' % self._method

    def render_output(self, output_file=''):
        if self._error:
            self.render_error()
            return

        output = self.render(self._method, self._output)
        if output_file == '':
            print output
        else:
            try:
                output_file = open(output_file, 'w')
                output_file.truncate()
                output_file.write(output)
                output_file.close()
            except IOError as exc:
                self._error = True
                self._error_message = str(exc)
                self.render_error()
                return

            self.render_success()

    def render_success(self):
        result = {"success": self._method}
        print demjson.encode(result)

    def render_error(self):
        result = {"error": self._error_message}
        print demjson.encode(result)

    @staticmethod
    def render(method, output):
        if (method == 'kriging') or (method == 'mean') or (method == 'gaussian') or (method == 'idw'):
            result = {"raster": output, "method": method}
            return demjson.encode(result)

    @staticmethod
    def kriging(nx, ny, x, y, x_min, y_min, dx, dy):
        grid = np.zeros((ny, nx))

        k = kriging(np.array(x), np.array(y))
        k.train()
        for i in range(ny):
            for j in range(nx):
                cell = np.array([y_min + dy * j + .5 * dy, x_min + dx * i + .5 * dx])
                grid[i][j] = k.predict(cell)
        return grid

    @staticmethod
    def mean(nx, ny, values):
        mean_value = np.mean(values)
        grid = mean_value * np.ones((ny, nx))
        return grid

    @staticmethod
    def gaussian_process(nx, ny, X, y, x_min, y_min, dx, dy):
        """
        Gausian process method. To replace kriging.
        Description:
        http://scikit-learn.org/stable/modules/generated/sklearn.gaussian_process.GaussianProcess.html#sklearn.gaussian_process.GaussianProcess.predict
        The scikit learn python library should be installed
        Should be tested
        """

        # Prediction is very sensetive to the parameters below, method to be used carefully!
        gp = GaussianProcess(regr='quadratic', corr='cubic', theta0=0.1, thetaL=.001, thetaU=1., nugget=0.01)
        gp.fit(X, y)
        X_grid_x = np.linspace(x_min, x_min+dx*nx, nx)
        X_grid_y = np.linspace(y_min, y_min+dy*ny, ny)
        xv, yv = np.meshgrid(X_grid_x, X_grid_y)

        X_grid = np.dstack(( xv.flatten(), yv.flatten()))[0]
        grid = np.reshape(gp.predict(X_grid, eval_MSE=False, batch_size=None), (ny, nx))
        return grid

    @staticmethod
    def inverse_distance_weighting(nx, ny, X, y, x_min, y_min, dx, dy):
        """
        Inverse-distance weighting interpolation method
        """

        def pointValue(x, y, power, smoothing, xv, yv, values):
            """ This function is used inside the inverse_distance_weighting method. """
            from math import pow  
            from math import sqrt

            nominator=0  
            denominator=0  
            for i in range(0,len(values)):  
                dist = sqrt((x-xv[i])*(x-xv[i])+(y-yv[i])*(y-yv[i])+smoothing*smoothing)
                #If the point is really close to one of the data points, return the data point value to avoid singularities  
                if(dist<0.0000000001):  
                    return values[i]
                nominator=nominator+(values[i]/pow(dist,power))  
                denominator=denominator+(1/pow(dist,power))  
            #Return NODATA if the denominator is zero  
            if denominator > 0:  
                value = nominator/denominator  
            else: 
                value = -9999
            return value

        power, smoothing = 5, 0
        xv = [i[0] for i in X]
        yv = [i[1] for i in X]    
        grid = np.zeros((ny, nx))

        for i in range(nx):
            for j in range(ny):  
                grid[j][i] = pointValue((x_min + dx/2)+dx*i, (y_min + dy/2)+dy*j, power, smoothing, xv, yv, y)
        return grid

Upvotes: 3

Views: 1548

Answers (1)

taleinat
taleinat

Reputation: 8701

You are using setUpClass() and tearDownClass(), which are called just once for the entire class. This is causing your different test methods to interfere with each other by changing the _interpolation attribute.

You could use setUp() and tearDown() instead, which would be called once before/after each test method.

Better yet, since you're initializing this object from a file in each test, just have each test method create its own Interpolation object at the beginning.

Upvotes: 1

Related Questions