Showing posts with label DRY. Show all posts
Showing posts with label DRY. Show all posts

Monday, August 6, 2012

django factory boy - better test management

Django factory boy is an excellent replacement for fixtures, most of the time you will encounter problems with maintenance of fixtures.For instance if you do migrations often, the set of fixtures will become invalid and has to be edited to fit the new schema, this can be extremely painful if you have a complex schema and lots of data.
Factory boy makes it easy to create objects when you need them for tests.For example..

lets say you have this set of models,
from django.db import models

class Owner(models.Model):
    name = models.CharField(max_length=200)
    phone = models.CharField(max_length=50)

    def __unicode__(self):
        return self.name

class Car(models.Model):
    name = models.CharField(max_length=200)
    owner = models.ForeignKey(Owner)

    def __unicode__(self):
        return self.name

Then your factories.py for these two will correspond to something like this
import factory
from models import Owner, Car

class OwnerFactory(factory.Factory):
    FACTORY_FOR = Owner
    name = 'bruce'
    phone = '+254728037573'

class CarFactory(factory.Factory):
    FACTORY_FOR = Car
    name = 'jeep'
    owner = factory.lazy_attribute(lambda a: OwnerFactory())

The tests for the factories themselves go something like this
from models import Car,Owner
from django.test.testcases import TestCase

class FactoryTestCase(TestCase):

    def test_car_factory(self):
        car = CarFactory()
        self.assertTrue(isinstance(car, Car))

    def test_owner_factory(self):
        owner = OwnerFactory()
        self.assertTrue(isinstance(owner, Owner))
Many to many fields are a bit tricky to emulate but this does the trick. For instance lets say you have this set of models.
from django.db import models

class Pizza(models.Model):
    name = models.CharField(max_length=120)
    toppings = models.ManyToManyField(Topping)

    def __unicode__(self):
        return self.name

class Topping(models.Model):
    name = models.CharField(max_length=200)

    def __unicode__(self):
        return self.name

Then your factories will go something like this.
from models import Pizza, Topping
import factory

class ToppingFactory(factory.Factory):
    FACTORY_FOR = Topping

    name = 'mushrooms'

class PizzaFactory(factory.Factory):
    FACTORY_FOR = Pizza

    name = 'mushroom delight'

    @classmethod
    def _prepare(cls, create, **kwargs):
        topping = ToppingFactory()
        pizza = super(PizzaFactory, cls)._prepare(create, **kwargs)
        pizza.toppings.add(topping)
        return pizza

So the key here is to override the _prepare method and assign the manytomanyfield objects here, since you have and instance of the object. In conclusion factories are a good alternative to fixtures when used in the right way.

Thursday, April 12, 2012

building web applications

The best method to use when building web applications is to use frameworks. Frameworks save on time and adhere to the principle of not repeating code all the time (DRY). So if you decide to use a framework, what should your choice be.There are many frameworks out there and therefore it would not be okay just to point you to one.To gain a deeper understanding of building web applications using frameworks it is advisable to go down the path of discovery.

  1. Pick a framework based on any language you know of and learn it, this should be the beginning.
  2. After taking a week or two to learn the new framework, do a side project with it, not a serious one but something far from the basics.Try to implement some idea you've always had.
  3. Add the side project to your portfolio and start over again from step 1 this time with another framework which is related.
After going through the first iteration, try implement the idea you had done using the new framework you have just learned.This aids you in discovering weaknesses and strengths in a framework.

Be patient
Nothing comes easy, everything requires time and effort, so don't expect to excel at it immediately.With continuous practice and diligent effort you will notice your skills and knowledge increasing.
I wish to stress the importance of persistence here.It's what will bear the results.