Object-Oriented Programming/Unit Testing/Python3

test_temperature.py edit

import unittest
from temperature import *


class TemperatureTestCase(unittest.TestCase):
    """Tests Temperature class."""


    def setUp(self):
        pass


    def test_constructor_celsius_none(self):
        temperature = Temperature()
        self.assertEqual(temperature.celsius, None,
            "Temperature constructor not initializing celsius to None")


    def test_constructor_fahrenheit_none(self):
        temperature = Temperature()
        self.assertEqual(temperature.celsius, None,
            "Temperature constructor not initializing celsius to None")


    def test_to_celsius(self):
        temperature = Temperature()
        self.assertEqual(temperature.to_celsius(98.6), 37.0,
            "Temperature conversion to celsius incorrect")
        

    def test_to_fahrenheit(self):
        temperature = Temperature()
        self.assertEqual(temperature.to_fahrenheit(37.0), 98.6, 
            "Temperature conversion to fahrenheit incorrect")


    def test_constructor_celsius_zero(self):
        temperature = Temperature(celsius=0)
        self.assertEqual(temperature.celsius, 0,
            "Temperature constructor not initializing celsius to zero")


    def test_constructor_fahrenheit_zero(self):
        temperature = Temperature(fahrenheit=0)
        self.assertEqual(temperature.fahrenheit, 0,
            "Temperature constructor not initializing fahrenheit to zero")


    def test_constructor_fahrenheit_986(self):
        temperature = Temperature(fahrenheit=98.6)
        self.assertEqual(temperature.celsius, 37.0,
            "Temperature constructor not initializing celsius to 37.0 when fahrenheit set to 98.6")
        

    def test_constructor_celsius_37(self):
        temperature = Temperature(celsius=37.0)
        self.assertEqual(temperature.fahrenheit, 98.6,
            "Temperature constructor not initializing fahrenheit to 98.6 when celsius set to 37.0")
        

    def test_absolute_zero_celsius(self):
        temperature = Temperature()
        self.assertEqual(temperature.absolute_zero_celsius, -273.15,
            "Absolute zero celsius incorrect")
        

    def test_absolute_zero_fahrenheit(self):
        temperature = Temperature()
        self.assertEqual(temperature.absolute_zero_fahrenheit, -459.67,
            "Absolute zero fahrenheit incorrect")
        

    def test_validate_celsius_not_float(self):
        temperature = Temperature()
        self.assertRaises(ValueError, temperature._validate_celsius, 'a')


    def test_validate_celsius_below_absolute_zero(self):
        temperature = Temperature()
        self.assertRaises(ValueError, temperature._validate_celsius, -1000)


    def test_validate_fahrenheit_not_float(self):
        temperature = Temperature()
        self.assertRaises(ValueError, temperature._validate_fahrenheit, 'a')


    def test_validate_fahrenheit_below_absolute_zero(self):
        temperature = Temperature()
        self.assertRaises(ValueError, temperature._validate_fahrenheit, -1000)


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

temperature.py edit

"""Temperature container / converter.

Examples:
    from temperature import Temperature
    
    temperature = Temperature(celsius=37)
    print(temperature.fahrenheit)
    
    temperature = Temperature(fahrenheit=98.6)
    print(temperature.celsius)
    
    temperature = Temperature()
    temperature.celsius = 37
    print(temperature.fahrenheit)
    
    temperature = Temperature()
    temperature.fahrenheit = 98.6
    print(temperature.celsius)
    
    temperature = Temperature()
    print(temperature.to_celsius(98.6))
    print(temperature.to_fahrenheit(37))

"""


class Temperature(object):
    """Supports Celsius and Fahrenheit temperatures."""
    
    def __init__(self, celsius=None, fahrenheit=None):
        """Creates a temperature object.
        
        Args:
            celius (float):     Optional Celius temperature.
            fahrenheit (float): Optional Fahrenheit temperature.

        Raises:
            ValueError: If both celsius and fahrenheit are initialized.

        """
        self._celsius = None
        self._fahrenheit = None
        
        if celsius != None and fahrenheit != None:
            raise ValueError("Only initialize celsius or fahrenheit, not both.")
    
        if celsius != None:
            celsius = self._validate_celsius(celsius)
            self.celsius = celsius
    
        if fahrenheit != None:
            fahrenheit = self._validate_fahrenheit(fahrenheit)
            self.fahrenheit = fahrenheit


    @property
    def absolute_zero_celsius(self):
        """Gets absolute zero Celsius.

        Returns:
            float: Absolute zero Celsius temperature.

        """
        return -273.15


    @property
    def absolute_zero_fahrenheit(self):
        """Gets absolute zero Fahrenheit.

        Returns:
            float: Absolute zero Fahrenheit temperature.

        """
        return -459.67


    @property
    def celsius(self):
        """Gets Celsius temperature.

        Returns:
            float: Celsius temperature

        """
        return self._celsius
    
        
    @celsius.setter
    def celsius(self, value):
        """Sets Celsius temperature.

        Args:
            value (float): Celsius temperature
    
        """
        value = self._validate_celsius(value)
        self._celsius = float(value)
        self._fahrenheit = self.to_fahrenheit(self.celsius)
        
    
    @property
    def fahrenheit(self):
        """Gets Fahrenheit temperature.

        Returns:
            float: Fahrenheit temperature

        """
        return self._fahrenheit
        
    
    @fahrenheit.setter
    def fahrenheit(self, value):
        """Sets Fahrenheit temperature.

        Args:
            value (float): Fahrenheit temperature
    
        Raises:
            ValueError: If Fahrenheit temperature is not a valid float.
            ValueError: If Fahrenheit temperature is below absolute zero.

        """
        value = self._validate_fahrenheit(value)
        self._fahrenheit = float(value)
        self._celsius = self.to_celsius(self.fahrenheit)
        
    
    def to_celsius(self, fahrenheit):
        """Converts Fahrenheit temperature to Celsius.
    
        Args:
            fahrenheit (float): Fahrenheit temperature to be converted
    
        Returns:
            float: Celsius temperature
    
        """
        fahrenheit = self._validate_fahrenheit(fahrenheit)
        return (fahrenheit - 32) * 5 / 9
        
    
    def to_fahrenheit(self, celsius):
        """Converts Celsius temperature to Fahrenheit.
    
        Args:
            celsius (float): Celsius temperature to be converted
    
        Returns:
            float: Fahrenheit temperature
    
        """
        celsius = self._validate_celsius(celsius)
        return celsius * 9 / 5 + 32


    def _validate_celsius(self, celsius):
        """Validates Celsius temperature.

        Args:
            value (float): Celsius temperature
    
        Returns:
            float: validated Celsius temperature
    
        Raises:
            ValueError: If Celsius temperature is not a valid float.
            ValueError: If Celsius temperature is below absolute zero.

        """
        try:
            celsius = float(celsius)
        except ValueError:
            raise ValueError("celsius must be a float. Received '" + str(celsius) + "'")
        except:
            raise        

        if celsius < self.absolute_zero_celsius:
            raise ValueError(
                "celsius must not be below absolute zero (%f). Received %f" % (self.absolute_zero_celsius, celsius))

        return celsius


    def _validate_fahrenheit(self, fahrenheit):
        """Validates Fahrenheit temperature.

        Args:
            value (float): Fahrenheit temperature
    
        Returns:
            float: validated Fahrenheit temperature
    
        Raises:
            ValueError: If Fahrenheit temperature is not a valid float.
            ValueError: If Fahrenheit temperature is below absolute zero.

        """
        try:
            fahrenheit = float(fahrenheit)
        except ValueError:
            raise ValueError("fahrenheit must be a float. Received '" + str(fahrenheit) + "'")
        except:
            raise        

        if fahrenheit < self.absolute_zero_fahrenheit:
            raise ValueError(
                "fahrenheit must not be below absolute zero (%f). Received %f" % (self.absolute_zero_fahrenheit, fahrenheit))

        return fahrenheit

Try It edit

Copy and paste the code above into one of the following free online development environments or use your own Python3 compiler / interpreter / IDE.

See Also edit