Python Forum

Full Version: Unit testing - AssertRaises
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hi, I got this converter:

def nmea_to_dd(coordinate, direction):
    if direction not in ['N', 'S', 'W', 'E']:
        raise TypeError('only N, S, E or W are valid directions')

    if coordinate.find('.') is 5:
        """ longitude in the DDDMM.MMMMM format """
        dd = int(float(coordinate[:3].strip('0')))
        ss = float(coordinate) - dd * 100
        if direction == 'E':
            return round(dd + (ss / 60), 6)
        elif direction == 'W':
            return round(dd + (ss / 60), 6) * -1
        else:
            return 0.0
    if coordinate.find('.') is 4:
        """  latitude in the DDMM.MMMMM format """
        dd = int(float(coordinate) / 100)
        ss = float(coordinate) - dd * 100
        if direction == 'N':
            return round(dd + (ss / 60), 6)
        elif direction == 'S':
            return round(dd + (ss / 60), 6) * -1
        else:
            return 0.0
Here is the unittest file:
import unittest
from converter import *


class TestNmeaConverter(unittest.TestCase):
    def test_valid(self):
        self.assertAlmostEqual(nmea_to_dd('5132.0000', 'N'), 51.533333)
        self.assertAlmostEqual(nmea_to_dd('5132.0000', 'S'), -51.533333)
        self.assertAlmostEqual(nmea_to_dd('01323.629', 'E'), 13.393817)
        self.assertAlmostEqual(nmea_to_dd('01323.629', 'W'), -13.393817)

    def test_directions(self):
        self.assertRaises(TypeError, nmea_to_dd('5132.0000', 'A'))
I dont know how to use assertRaises with 2 parameters in the 13th line. I would like to make sure that the function raises TypeError if it's given another letter as the second parameter.
I will also parse the first parameter's correct form later.

Thanks,
For assert raises you want to pass the function object, not a call to the function object. That makes it possible for unittest to run the function in an environment where any exceptions can be caught and tested. If you want to set parameters for the call, you pass those parameters to assertRaises as a *args tuple (and/or a **kwargs dictionary).

Try:

    def test_directions(self):
        self.assertRaises(TypeError, nmea_to_dd, ('5132.0000', 'A'))
Note the extra comma after nmea_to_dd.
Thanks, in the meantime I got it working as well:

    def test_input(self):
        with self.assertRaises(TypeError):
            qtime_to_osmand_timestamp(True, False)
By the way I think appropriate exception is ValueError, not TypeError

Quote:exception ValueError - Raised when an operation or function receives an argument that has the right type but an inappropriate value, and the situation is not described by a more precise exception such as IndexError.

Quote:exception TypeError

Raised when an operation or function is applied to an object of inappropriate type. The associated value is a string giving details about the type mismatch.

This exception may be raised by user code to indicate that an attempted operation on an object is not supported, and is not meant to be. If an object is meant to support a given operation but has not yet provided an implementation, NotImplementedError is the proper exception to raise.

Passing arguments of the wrong type (e.g. passing a list when an int is expected) should result in a TypeError, but passing arguments with the wrong value (e.g. a number outside expected boundaries) should result in a ValueError.