Over a million developers have joined DZone.

Developing (a.k.a. Testing) in Python - Part 2

· Web Dev Zone

Start coding today to experience the powerful engine that drives data application’s development, brought to you in partnership with Qlik.

In part one I talked about testing as Python’s version of compile-time checking. Fully testing a project is tricky business. This is true across languages; even advanced testing frameworks can only alleviate some problems. One particular pain point is testing components that strongly rely on databases. To run test code involving databases, we need scripts/functions that recreate our testing environment and put in basic data to get things running. Suppose we’re using MySQL and we want to start our database fresh for each test. We can run a fixtures script before each test that might look something like:

DROP DATABASE fiesta_dev;
CREATE DATABASE fiesta_dev;

CREATE TABLE `users` (^C
...wait what is the syntax again?
USE fiesta;
SHOW CREATE TABLE users;
CREATE ^C
USE fiesta_dev;
CREATE TABLE `users` (`id` INT PRIMARY KEY AUTO_INCREMENT,
                      `name` VARCHAR(64),
                      `password` CHAR(32),
                      `email_address` VARCHAR(128));

User.new_user('Daniel Gottlieb', 'some password hash', 'dan@corp.fiesta.cc')


And things are good. Until one day we realize that our user data model needs to support linking multiple email addresses. Oops. We add a new `email_addresses` table to our database. It has an index on `user_id` and on `email_address`. There’s a foreign key constraint on `user_id` to the `users` table. We now update our production code to work with a list of strings for email addresses instead of a single one. And we’re done. Except that now our tests don’t work. We have to add in a new “create table” to our script. We also have to update the `users` table in the test script. This leaves us with:

...
CREATE TABLE `users` (`id` INT PRIMARY KEY AUTO_INCREMENT,
                      `name` VARCHAR(64),
                      `password` CHAR(32));

CREATE TABLE `email_addresses` (`user_id` INT,
                                `email_address` VARCHAR(128),
                                INDEX (`email_address`),
                                CONSTRAINT FOREIGN KEY (`user_id`) REFERENCES `users` (`id`)
                                  ON DELETE CASCADE);

user_obj = User.new_user('Daniel Gottlieb', 'some password hash', 'dan@corp.fiesta.cc')
user_obj.add_email_address('dgottlieb@corp.fiesta.cc')


Let’s look at our fixture script if we use MongoDB (and pymongo) instead:

conn = pymongo.Connection()
conn.drop_database("fiesta_dev")

user_obj = User.new_user('Daniel Gottlieb', 'some password hash', 'dan@corp.fiesta.cc')


Now let’s add support for lists of emails and see how our fixtures script changes:

conn = pymongo.Connection()
conn.drop_database("fiesta_dev")

user_obj = User.new_user('Daniel Gottlieb', 'some password hash', 'dan@corp.fiesta.cc')
user_obj.add_email_address('dgottlieb@corp.fiesta.cc')


Admittedly, there is a little bit of “magic” here; particularly with generating indexes. The way Fiesta is setup, important sections of code will redundantly call create_index on a table. If the index is already created, MongoDB ignores the statement. This is similar to how MongoDB will silently create a new collection when its first document is inserted. Combined with the ability to add any field to any document in a collection, the fixtures script only needs to be aware of the database enough to clear all the data before the tests run.

I hope this offers some insight into why I think cleaner test code can be written with MongoDB than with a relational database. Feel free to ask questions or offer up your own tips in the comments below!

Party On,

Dan

 

source: http://blog.fiesta.cc/post/11668794861/developing-a-k-a-testing-in-python-part-two

Create data driven applications in Qlik’s free and easy to use coding environment, brought to you in partnership with Qlik.

Topics:

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}