When I started reading more into and practicing unit testing in python my first question was; “How did I not know about this, you jagweeds?” The truth is that unit testing is an incredibly important part of developing software. I consider myself at a level where I have moved beyond learning the basics and have graduated to actually putting together projects, building new sites, and learning to make tools to automate my life. Now it is up to me to learn about and make unit tests for my projects. I’d like to pass along what I have learned to others.
Now unit testing is a simple concept; you write some code that does something and you write a test to make sure the code does what it’s suppose to do. To do that in reverse is referred to as test driven development, you write the test, run it to test the test, then write the code. It’s a good way to write code, keeps you honest and tests for everything.
So let’s get down to it. Python uses a cool system to unit test sometimes referred to as PyUnit. It’s the standard unit testing framework to use with Python. Now we first begin by writing some of our test code. Note that I am running Python 2.7 and have not tested this in the new Python 3. I’ll explain some of the parts of unit testing:
import unittest from unit import new class UserTests(unittest.TestCase): def test_false(self): self.assertFalse(2 == 3) def test_cap(self): self.assertTrue(new.name.isupper()) def test_user(self): self.assertTrue(new.name) self.assertTrue(new.zipcode) if __name__ == '__main__': unittest.main()
This is our script we’ll be testing:
import random name = raw_input("Please Enter your name: ") name = name.title() class MyUser: 'Create new user class' def __init__(self, name, zipcode): self.name = name self.zipcode = zipcode str(zipcode) new = MyUser("Joey", 02302) print new
Now we import unittest like anything else in python. I also included our file that we wrote the test code for. So we start by creating a UserTests class, we include unittest.TestCase for a subclass. Each test is created using methods within the class. So our first test is an easy one, I only want to test that one thing is not equal to the other. Now we name the methods in a certain way. The name needs to start with the word test. I found this out through testing why my tests were throwing up errors I couldn’t explain. We add the self as an argument. Then we look into adding some methods into our tests. This is where our tests are written.
In the methods we setup we use the self argument and put our assertions to setup the tests. I set up a few. the first one was simple, and didn’t entirely pertain to script I wrote. I really only wrote it to display the false assertion. So we use the assertFalse method to test if the number two has the same value as number three (spoiler, it doesn’t). We then proceed to run our test.We open the command line, navigate to our test directory and run the test script:
When we run the test we get a success because those two numbers do not have the same value and are considered false.
As a side note, I like to add the -v sub command so that we get a verbose output. It shows us all of our tests so I know what passes and what doesn’t. It shows you without it but I like using the verbose output because it will actually show us our assertion.
python my_test.py -v
So after that we create another test method to test if the string we named name has a capital letter. We use the assertTrue method add our variable so that our test knows what to test. Note, the way you write your tests assumes you know how you’re going to layout your code so keep that in mind. We then run the test, and we get a fail message, we get the fail message because we haven’t written the code just yet. So we then write out our code:
name = raw_input("Please Enter your name: ") name = name.title()
This creates our name variable and lets us input it using the console. Then we use the title() method to capitalize the string. Then we run the test again and we get a passing message. Booya we have just performed test driven development. Now we are going to create a class and start doing some development.
We start by creating some new tests. First we want to make sure that the User class we are going to create works when we add info to it. We start by creating some new tests.
def test_user(self): self.assertTrue(new.name) self.assertTrue(new.zipcode)
We use the assertTrue method to make sure we have both a name and zipcode present in our new class instance. We run the test and then we get our failing message. Then we start creating our code to match our tests:
class MyUser: 'Create new user class' def __init__(self, name, zipcode): self.name = name self.zipcode = zipcode str(zipcode)
Then at the bottom of our test script we create an instance of our class:
new = MyUser("Joey", 02302)
Now when we run our tests again we get a success message. Yay! I just want to mention that we also make sure that we convert our zipcode into a string. Otherwise we can run into some bugs with integers starting with leading zeros, as some zipcodes do. The string still exists so our test passes.
Now this is a short version of the possibilities of testing. there are several other methods that we could use to create new tests. This is all stuff I got from the unit test section from python.org; there you can get a lot more info about unit testing in python. This is important and I’m happy that when I started getting more into python I started using unit testing. As a future web developing wizard it’s kind of important that we know how to test our code so that it doesn’t create gremlins when we aren’t looking. Feel free to comment if you have anything to add or questions for me!