Unit Test Structure Tutorial

A place where you can post Python-related tutorials you made yourself, or links to tutorials made by others.

Unit Test Structure Tutorial

Postby CleanCut » Fri Mar 27, 2015 7:20 pm

(This is based off of the tutorial I wrote for green. You can find the latest version of the tutorial here.)

Unit Test Structure Tutorial

This tutorial does cover:

  • External structure of your project (directory and file layout)
  • Skeleton of a real test module
  • How to import stuff from from your project into your test module
  • Gotchas about naming...everything.
  • Where to run green from and what the output could look like.

This tutorial does not cover:


This is what your project layout should look like with just one module in your package:

Code: Select all
proj                  # 'proj' is the package
├── __init__.py
├── foo.py            # 'foo' (or proj.foo) is the only "real" module
└── test              # 'test' is a sub-package
    ├── __init__.py
    └── test_foo.py   # 'test_foo' is the only "test" module


Notes:

  1. There is an __init__.py in every directory. Don't forget it. It can be an empty file, but it needs to exist.
  2. proj itself is a directory that you will be storing somewhere. We'll pretend it's in /home/user
  3. The test directory needs to start with test.
  4. The test modules need to start with test.

When your project starts adding code in sub-packages, you will need to make a choice on where you put their tests. I prefer to create a test subdirectory in each sub-package.

Code: Select all
proj
├── __init__.py
├── foo.py
├── subpkg
│   ├── __init__.py
│   ├── bar.py
│   └── test              # test subdirectory in every sub-package
│       ├── __init__.py
│       └── test_bar.py
└── test
    ├── __init__.py
    └── test_foo.py

The other option is to start mirroring your subpackage layout from within a single test directory.

Code: Select all
proj
├── __init__.py
├── foo.py
├── subpkg
│   ├── __init__.py
│   ├── bar.py
└── test
    ├── __init__.py
    ├── subpkg            # mirror sub-package layout inside test dir
    │   ├── __init__.py
    │   └── test_bar.py
    └── test_foo.py



Skeleton of Test Module

Assume foo.py contains the following contents:

Code: Select all
def answer():
    return 42

class School():

    def food(self):
        return 'awful'

    def age(self):
        return 300

Here's a possible version of test_foo.py you could have.

Code: Select all
# Import stuff you need for the unit tests themselves to work
import unittest

# Import stuff that you want to test.  Don't import extra stuff if you don't
# have to.
from proj.foo import answer, School

# If you need the whole module, you can do this:
#     from proj import foo
#
# Here's another reasonable way to import the whole module:
#     import proj.foo as foo
#
# In either case, you would obviously need to access objects like this:
#     foo.answer()
#     foo.School()

# Then write your tests

class TestAnswer(unittest.TestCase):

    def test_type(self):
        "answer() returns an integer"
        self.assertEqual(type(answer()), int)

    def test_expected(self):
        "answer() returns 42"
        self.assertEqual(answer(), 42)

class TestSchool(unittest.TestCase):

    def test_food(self):
        school = School()
        self.assertEqual(school.food(), 'awful')

    def test_age(self):
        school = School()
        self.assertEqual(school.age(), 300)

Notes:

  1. Your test class must subclass unittest.TestCase. Technically, neither unittest nor Green care what the test class is named, but to be consistent with the naming requirements for directories, modules, and methods we suggest you start your test class with Test.
  2. Start all your test method names with test.
  3. What a test class and/or its methods actually test is entirely up to you. In some sense it is an artform. Just use the test classes to group a bunch of methods that seem logical to go together. We suggest you try to test one thing with each method.
  4. The methods of TestAnswer have docstrings, while the methods on TestSchool do not. For more verbose output modes, green will use the method docstring to describe the test if it is present, and the name of the method if it is not. Notice the difference in the output below.

(This is based off of the tutorial I wrote for green. You can find the latest version of the tutorial here.)
Last edited by micseydel on Fri Mar 27, 2015 7:49 pm, edited 1 time in total.
Reason: First post lock.
CleanCut
 
Posts: 1
Joined: Fri Mar 27, 2015 7:00 pm

Re: Unit Test Structure Tutorial

Postby Mekire » Wed Apr 15, 2015 4:32 am

Anyone have any opinions here? I don't do nearly enough testing to have a strong opinion, but this looks pretty solid.
Any objections or possible additions to suggest before I move it over to Tutorials?
New Users, Read This
  • Use code tags when posting code.
  • Include any errors with your post (in code tags).
  • Describe your problem; not your chosen solution.
  • Make examples the minimum length to demonstrate your issue.
User avatar
Mekire
 
Posts: 1711
Joined: Thu Feb 07, 2013 11:33 pm
Location: Tucson, Arizona

Re: Unit Test Structure Tutorial

Postby micseydel » Wed Apr 15, 2015 7:19 am

Looks good to me.
Due to the reasons discussed here we will be moving to python-forum.io on October 1, 2016.

This forum will be locked down and no one will be able to post/edit/create threads, etc. here from thereafter. Please create an account at the new site to continue discussion.
User avatar
micseydel
 
Posts: 3000
Joined: Tue Feb 12, 2013 2:18 am
Location: Mountain View, CA


Return to Tutorials

Who is online

Users browsing this forum: No registered users and 1 guest