classes: test_classes


how to make a class in Python

  • use the class keyword

  • use TitleCase for the name

  • use a name that tells what the collection of attributes and methods (functions) does - this is hard to do and is something I am still learning


test_defining_classes_w_pass

red: make it fail

I make a new file called test_classes.py in the tests directory

import unittest
import classes


class TestClasses(unittest.TestCase):

    def test_defining_classes_w_pass(self):
        self.assertIsInstance(classes.ClassWithPass(), object)

the terminal shows ModuleNotFoundError because I have an import statement for a module called classes

green: make it pass

  • I add ModuleNotFoundError to the list of Exceptions encountered

    # Exceptions Encountered
    # AssertionError
    # ModuleNotFoundError
    
  • I make Python module called classes.py and the terminal shows AttributeError which I add to the list of Exceptions encountered

    # Exceptions Encountered
    # AssertionError
    # ModuleNotFoundError
    # AttributeError
    
  • I then add the name ClassWithPass to the module

    ClassWithPass
    

    and the terminal shows NameError because ClassWithPass is not defined anywhere

  • I add the error to the list of Exceptions encountered

    # Exceptions Encountered
    # AssertionError
    # ModuleNotFoundError
    # AttributeError
    # NameError
    
  • I point the name to None

    ClassWithPass = None
    
  • and then redefine the variable as a class using thePython class keyword

    class ClassWithPass:
    

    the terminal shows IndentationError because I declared a class without adding any indented text

  • I add the new error to the list of Exceptions encountered

    # Exceptions Encountered
    # AssertionError
    # ModuleNotFoundError
    # AttributeError
    # NameError
    # IndentationError
    
  • Python has the pass keyword to use as a placeholder for moments like this cue Kelly Clarkson

    class ClassWithPass:
    
        pass
    

    and the terminal shows passing tests

refactor: make it better

Here is a quick review of what has happened so far

  • pass is a placeholder

  • self.assertIsInstance is a unittest.TestCase method that checks if the first input to the method is an instance of the second input

  • the test self.assertIsInstance(classes.ClassWithPass(), object) checks if ClassWithPass is an object

  • in Python everything is an object , which means if it exists in Python there is a class definition for it somewhere or it inherits from a class


test_defining_classes_w_parentheses

red: make it fail

I add another test to TestClasses in test_classes.py to show another way to make a class

def test_defining_classes_w_parentheses(self):
    self.assertIsInstance(classes.ClassWithParentheses(), object)

the terminal shows AttributeError

green: make it pass

  • I add a class definition like ClassWithPass to classes.py

    class ClassWithParentheses:
    
        pass
    

    the terminal shows passing tests

  • When I make the definition include parentheses

    class ClassWithParentheses():
    
        pass
    

    the terminal shows all tests are still passing.

  • I can confidently say that in Python

    • I can define classes with parentheses

    • I can define classes without parentheses

    • pass is a placeholder


test_defining_classes_w_object

In object oriented programming there is a concept called Inheritance). With Inheritance I can define new objects that inherit from existing objects.

Making new objects is easier because I do not have to reinvent or rewrite things that already exist, I can inherit them instead and change the new objects for my specific use case

To use inheritance I specify the “parent” in parentheses when I define the new object (the child) to make the relationship

red: make it fail

I add another test to TestClasses in test_classes.py

def test_defining_classes_w_object(self):
    self.assertIsInstance(classes.ClassWithObject(), object)

and the terminal shows AttributeError

green: make it pass

  • I add a class definition to classes.py

    class ClassWithObject():
    
        pass
    

    the terminal shows all tests passed

  • then I change the definition to explicitly state the parent object

    class ClassWithObject(object):
    
        pass
    

    and the terminal still shows passing tests

Here is a little summary

  • classes can be defined

    • with parentheses stating what object the class inherits from

    • with parentheses without stating what object the class inherits from

    • without parentheses

    • pass is a placeholder

  • classes by default inherit from the object class, because in each of the tests, whether the parent is stated or not, each class I defined is an instance of an object

Zen of Python (PEP 20)

I prefer to use the explicit form of class definitions with the parent object in parentheses, from the Zen of Python: Explicit is better than implicit

Would you like to classes: attributes and methods?


classes: tests and solutions