Friday, May 17, 2013

Unit testing your Flask REST Application

If you are already convinced that unit testing is the way to go, skip the next section with the different examples.

Unit Testing Is Not Optional

As it says on the Flask website, "something that is untested is broken." While this obviously isn't always true, there is no way for you to know whether or not you have bugs in your code unless you test it. When you initially start writing your application, you probably think one of the following:
  1. Even if it takes only 10 minutes to write the unit test, that time could be spent writing the next great feature.
  2. Why bother wasting time writing test cases when one can just test the application by visiting the site and clicking on the various pages. Even with a REST API that doesn't have nice user interface, one could theoretically could use something like the Advanced REST Client Google Chrome plugin to inspect the JSON that is produced.
Although this is true when you first start out (i.e. the first week or two), you will quickly realize how unmanageable it becomes. How can you be 100% sure that when you change some line of code that it doesn't have a (negative) affect on some other, seemingly unrelated, bit of code? Enter unit testing.

Unit testing is the notion of testing the parts (units) of your code to ensure that they behave as expected. For example, if you have some code that verifies whether a password is correct for a given user, then the unit test should test all possible scenarios that this function may encounter. For example, what happens when you pass None to your function? What happens when you provide an integer password instead of a string password that you were expecting? What happens when you provide the correct password but for a different user in the system?

By testing each of your components independently, you can prove to yourself (and others!) that everything is behaving as expected. So, if in the future you then change one of the components (say you now have a faster way of searching for users in your database given their first name), you merely have to test it with the code that you have already written to verify that it is doing what is expected. If it returns the same results as before (assuming the new method doesn't change the ordering, of course!) then you know that even though the underlying search algorithm changed, it's still behaving the same way as before. Since it's still behaving the same way as before, any other bit of code that required the searching of users by email will also work just like before. Now you can feel free to pat yourself on the back and sleep easy that night.

The key to good unit testing is to ensure that you truly test each unit independently. In other words, one test should not have an affect on another. For example, if you have a test for adding a new user to a database, that test should not affect the data being used for another test. Thus, it's imperative that you setup and initialize dependencies (like databases) in each of the tests so that you know exactly what the starting point of the test is. If this wasn't the case, you will run into problems when you try to run, for instance, a test for counting the number of users in your database.

Although, the examples that I am providing below are in the context of Flask application development, the principles of unit testing are framework and language independent.

Now that I hopefully convinced you that unit testing is not something that should be an afterthought, but something that should be part of your day-to-day programming habits, let's take a look at some unit testing for Flask application.

Unit Testing Examples

To get started, I would highly recommend the great introduction to the basics of unit testing Flask applications on the Flask website. The examples that I have linked below are for slightly more complicated or specific things that I had to test.

No comments:

Post a Comment