User Model and the Tdd

So I've got BMI name per specific bmi value. #10 issue.

I've started work on it. Went to master branch. Created feature-branch.

And then.... I've found out django-models that has no test-coverage or other things like that and looks a bit more then little as not TDD-approach.

Well... let's go and fix that, shall we ?

Fixing User Model not tested yet.

So I've figure out I'll first create test for checking if fields exists in model.

Initially I've created test method that was a bit product-specific, but then finally I've moved it to a GenericModelTestCase class and added test only in this generic-type class.

Then in specific-model-class I only inherited by this generic-type class and added cls and fields fields :)

The GenericModelTestCase looks like that (in generics.py module):

"""
All generic type of classes used in django-tests
"""
from django.test import TestCase
from django.contrib.auth.models import User as AuthUser


class GenericModelTestCase(TestCase):
    """
    Generic Model Test Case.
    Contains:
    - assert_fields - assertion for checking if all fields in model exists
    """
    cls = AuthUser
    fields = []

    def assert_fields(self, fields):
        """ asserting if fields exists in model"""
        fields_in_model = []
        # fields as django fields:
        for field in self.cls._meta.get_fields(include_hidden=True):
            if field.name in fields:
                fields_in_model.append(field.name)
        # method as fields:
        for method in self.cls.__dict__:
            if method in fields and method not in fields_in_model:
                fields_in_model.append(method)
        assert sorted(set(fields_in_model).intersection(fields)) == sorted(fields)

    def test_fields(self):
        """ Uses asserting fields for checking with naming convention of django-type """
        self.assert_fields(self.fields)

And the UserModelTestCase

"""
Unit tests for User model
"""
from web.models import User
from web.tests.django_type.generics import GenericModelTestCase


class UserModelTestCase(GenericModelTestCase):
    """ User Model TestCase """
    cls = User
    fields = ['id', 'name', 'surname', 'weight', 'height', 'bmi']

Clean and simple ! :)

Now... how about that feature branch, huh?

Yeah I know I should not mix feature branch with a fixing lack-of-tests branch, but for sake of simplicity I'll skip that this time.

Now moving to the feature it self.

It should be pretty simple, isn't it ?

Let's find it out ! :)

Feature branch code

At models.py, User class :

class User(models.Model):
    """
    User model for obtaining personal information about biking riders
    """
    name = models.CharField(max_length=50)
    surname = models.CharField(max_length=100, default="")
    weight = models.IntegerField(default=0)
    height = models.IntegerField(default=0)

    def __unicode__(self):
        """
        Returns User information when using str/printing
        """
        return self.name

    def bmi(self):
        """
        Body Mass Index calculator simplified to number
        """
        return (self.weight / (self.height * self.height)) * 10000

    def bmi_health_name(self):
        """
        BMI Health Name - Returns proper naming for value of BMI
        """
        if self.bmi() < 0:
            return None
        if self.bmi() >= 0 and self.bmi() <= 18.5:
            return "Underweight"
        if self.bmi() > 18.5 and self.bmi() <= 24.9:
            return "Normal weight"
        if self.bmi() > 24.9 and self.bmi() <= 29.9:
            return "Overweight"
        if self.bmi() > 29.9:
            return "Obesity"

At tests_user.py :

"""
Unit tests for User model
"""
from mock import MagicMock

from web.models import User
from web.tests.django_type.generics import GenericModelTestCase


class UserModelTestCase(GenericModelTestCase):
    """ User Model TestCase """
    cls = User
    fields = ['id', 'name', 'surname', 'weight', 'height', 'bmi']

    def setUp(self):
        """SetUp"""
        self.user = User()

    def assert_bmi_health(self, bmi, expected):
        """ Asserts BMI health name"""
        self.user.bmi = MagicMock(return_value=bmi)
        assert self.user.bmi_health_name() == expected

    def test_bmi_health_name(self):
        """ tests for bmi_health_name method """
        self.assert_bmi_health(-1, None)
        self.assert_bmi_health(0, "Underweight")
        self.assert_bmi_health(1, "Underweight")
        self.assert_bmi_health(18.5, "Underweight")
        self.assert_bmi_health(18.6, "Normal weight")
        self.assert_bmi_health(25.0, "Overweight")
        self.assert_bmi_health(30.0, "Obesity")

Code commits done for this post:

Tools and applications used:

Release

You can find release of source code here.

Acknowledgements of links I've found usefull while writing this article:

DjangoProjects.com:

StackOverFlow:

Accomplished:

TDD Approach for Django Models!

Final word! -> NEW BADGE UNLOCKED!

You have one new badge unlocked ! - Making Django Generic Model Test Case! - Huuuraaay ! :)

Check my 1st Milestone here

Will I be able to complete it till Sunday?

Give a comment in box below :)

Thanks ! Keep in touch :)



Comments

comments powered by Disqus