[PATCH] New factory which creates arbitrary model objects to be used in tests.

Dirk Wallenstein halsmit at t-online.de
Sat Feb 26 20:05:00 EST 2011


On Fri, Feb 25, 2011 at 04:35:51PM -0300, Guilherme Salgado wrote:
> 
> ---
> If there's interest in this I'd be happy to move the stuff from
> patchwork/tests/utils.py to here and change tests to use the factory.
> 
>  apps/patchwork/tests/factory.py |   88 +++++++++++++++++++++++++++++++++++++++
>  1 files changed, 88 insertions(+), 0 deletions(-)
>  create mode 100644 apps/patchwork/tests/factory.py
> 
> diff --git a/apps/patchwork/tests/factory.py b/apps/patchwork/tests/factory.py
> new file mode 100644
> index 0000000..9aa5ec3
> --- /dev/null
> +++ b/apps/patchwork/tests/factory.py
> @@ -0,0 +1,88 @@
> +# Patchwork - automated patch tracking system
> +# Copyright (C) 2011 Jeremy Kerr <jk at ozlabs.org>
> +#
> +# This file is part of the Patchwork package.
> +#
> +# Patchwork is free software; you can redistribute it and/or modify
> +# it under the terms of the GNU General Public License as published by
> +# the Free Software Foundation; either version 2 of the License, or
> +# (at your option) any later version.
> +#
> +# Patchwork is distributed in the hope that it will be useful,
> +# but WITHOUT ANY WARRANTY; without even the implied warranty of
> +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
> +# GNU General Public License for more details.
> +#
> +# You should have received a copy of the GNU General Public License
> +# along with Patchwork; if not, write to the Free Software
> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
> +
> +from itertools import count
> +from random import randint
> +
> +from django.contrib.auth.models import User
> +
> +from patchwork.models import Patch, Person, Project, State
> +
> +
> +class ObjectFactory(object):
> +    """Factory methods for creating basic Python objects."""
> +
> +    def __init__(self):
> +        # Initialise the unique identifier.
> +        self.integer = count(randint(0, 1000000))
> +
> +    def getUniqueEmailAddress(self):
> +        return "%s at example.com" % self.getUniqueString('email')
> +
> +    def getUniqueString(self, prefix=None):
> +        """Return a string unique to this factory instance.
> +
> +        :param prefix: Used as a prefix for the unique string. If unspecified,
> +            defaults to 'generic-string'.
> +        """
> +        if prefix is None:
> +            prefix = "generic-string"
> +        string = "%s%s" % (prefix, self.getUniqueInteger())
> +        return string.lower()
> +
> +    def getUniqueInteger(self):
> +        """Return an integer unique to this factory instance."""
> +        return self.integer.next()
> +
> +    def makeUser(self):
> +        userid = password = self.getUniqueString()
> +        user = User.objects.create_user(
> +            userid, self.getUniqueEmailAddress(), password)
> +        user.save()
> +        return user
> +
> +    def makeProject(self):
> +        name = self.getUniqueString()
> +        project = Project(
> +            linkname=name, name=name,
> +            listid=self.getUniqueString(),
> +            listemail=self.getUniqueEmailAddress())
> +        project.save()
> +        return project
> +
> +    def makePerson(self, is_user=True):
> +        if is_user:
> +            user = self.makeUser()
> +        person = Person(
> +            email=self.getUniqueEmailAddress(), name=self.getUniqueString(),
> +            user=user)
                     ^^^ might not exist


> +        person.save()
> +        return person
> +
> +    def makePatch(self, project=None, submitter=None):
> +        if project is None:
> +            project = self.makeProject()
> +        if submitter is None:
> +            submitter = self.makePerson()
> +        patch = Patch(
> +            project=project, msgid=self.getUniqueString(),
The email package has a helper to format msgids in 
    email.utils.make_msgid()

> +            name=self.getUniqueString(), submitter=submitter,
> +            state=State.objects.get(name='New'))
> +        patch.save()
> +        return patch

I guess you want to solve the problem of creating an initial db state.
I personally would prefer a fixture that creates a state with more
reasonable names like:
    TestProjectA
    TestProjectB
    TestUserA
    TestUserB
    TestMaintainer
    etc and/or similar
That would make it much easier to inspect than arbitrary numbers (eg in
test mails).
Maybe have a TestFixtureMixIn class that has a 'fixtures' attribute and
that makes those models available as properties (wrap the lookup).
I assume that would cover most of the testing needs and clients would
not have to create it themselves.

-- 
Greetings,
Dirk


More information about the Patchwork mailing list