Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running Django Tests with a Precommit Hook

I would like to run all my django tests using mercurial's precommit hook. Whenever a test fails the commit will be aborted.

The goal is to block build-breaking commits as often as possible.

edit: Ended up using the external script route. Here is the reletant portion of my hgrc:

[hooks]
precommit = python ./pinax/projects/lgr/manage.py test lgr_photos --verbosity=0 --noinput
commit = hg push

Here is my progress on the hook function:

from os.path import join, dirname
import sys
from django.core.management import call_command

def hook(ui, repo, **kwargs):
    project_path = join( dirname(repo.path), 'pinax', 'projects')
    sys.path.insert(0, project_path)

    from lgr.manage import *

    output = call_command('test', verbosity=0, interactive=False)
    #ui.warn(output)

What am I doing wrong here?

PS - It's giving a HUGE error traceback, which is included in it's entirety below

jim@ubuntu:~/workspace/lgr$ hg ci -m 'testing hooks'
No username found, using '[email protected]' instead
error: precommit hook raised an exception: '_demandmod' object is not iterable
** unknown exception encountered, details follow
** report bug details to http://mercurial.selenic.com/bts/
** or [email protected]
** Mercurial Distributed SCM (version 1.3.1)
** Extensions loaded: 
Traceback (most recent call last):
  File "/usr/bin/hg", line 27, in <module>
    mercurial.dispatch.run()
  File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 16, in run
    sys.exit(dispatch(sys.argv[1:]))
  File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 27, in dispatch
    return _runcatch(u, args)
  File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 43, in _runcatch
    return _dispatch(ui, args)
  File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 449, in _dispatch
    return runcommand(lui, repo, cmd, fullargs, ui, options, d)
  File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 317, in runcommand
    ret = _runcommand(ui, options, cmd, d)
  File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 501, in _runcommand
    return checkargs()
  File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 454, in checkargs
    return cmdfunc()
  File "/usr/lib/pymodules/python2.6/mercurial/dispatch.py", line 448, in <lambda>
    d = lambda: util.checksignature(func)(ui, *args, **cmdoptions)
  File "/usr/lib/pymodules/python2.6/mercurial/util.py", line 402, in check
    return func(*args, **kwargs)
  File "/usr/lib/pymodules/python2.6/mercurial/commands.py", line 667, in commit
    node = cmdutil.commit(ui, repo, commitfunc, pats, opts)
  File "/usr/lib/pymodules/python2.6/mercurial/cmdutil.py", line 1213, in commit
    return commitfunc(ui, repo, message, match(repo, pats, opts), opts)
  File "/usr/lib/pymodules/python2.6/mercurial/commands.py", line 665, in commitfunc
    editor=e, extra=extra)
  File "/usr/lib/pymodules/python2.6/mercurial/localrepo.py", line 886, in commit
    ret = self.commitctx(cctx, True)
  File "/usr/lib/pymodules/python2.6/mercurial/localrepo.py", line 915, in commitctx
    self.hook("precommit", throw=True, parent1=xp1, parent2=xp2)
  File "/usr/lib/pymodules/python2.6/mercurial/localrepo.py", line 139, in hook
    return hook.hook(self.ui, self, name, throw, **args)
  File "/usr/lib/pymodules/python2.6/mercurial/hook.py", line 119, in hook
    r = _pythonhook(ui, repo, name, hname, hookfn, args, throw) or r
  File "/usr/lib/pymodules/python2.6/mercurial/hook.py", line 52, in _pythonhook
    r = obj(ui=ui, repo=repo, hooktype=name, **args)

here is the important part:

  File "/home/jim/run_lgr_tests.py", line 11, in hook
    output = call_command('test', verbosity=0, interactive=False)

and the rest:

  File "/usr/local/lib/python2.6/dist-packages/django/core/management/__init__.py", line 166, in call_command
    return klass.execute(*args, **defaults)
  File "/usr/local/lib/python2.6/dist-packages/django/core/management/base.py", line 213, in execute
    translation.activate('en-us')
  File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/__init__.py", line 73, in activate
    return real_activate(language)
  File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/__init__.py", line 43, in delayed_loader
    return g['real_%s' % caller](*args, **kwargs)
  File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 205, in activate
    _active[currentThread()] = translation(language)
  File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 194, in translation
    default_translation = _fetch(settings.LANGUAGE_CODE)
  File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 180, in _fetch
    app = import_module(appname)
  File "/usr/local/lib/python2.6/dist-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 84, in _demandimport
    return _origimport(name, globals, locals, fromlist)
  File "/home/jim/workspace/lgr/pinax/projects/lgr/apps/lgr_hacks.py", line 5, in <module>
    User.email = models.EmailField(_('email address'), blank=True, max_length=200)
  File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/__init__.py", line 62, in ugettext
    return real_ugettext(message)
  File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 286, in ugettext
    return do_translate(message, 'ugettext')
  File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 276, in do_translate
    _default = translation(settings.LANGUAGE_CODE)
  File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 194, in translation
    default_translation = _fetch(settings.LANGUAGE_CODE)
  File "/usr/local/lib/python2.6/dist-packages/django/utils/translation/trans_real.py", line 180, in _fetch
    app = import_module(appname)
  File "/usr/local/lib/python2.6/dist-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 84, in _demandimport
    return _origimport(name, globals, locals, fromlist)
  File "/home/jim/workspace/lgr/pinax/apps/external_apps/djangodblog/__init__.py", line 1, in <module>
    import djangodblog.admin
  File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 91, in _demandimport
    return _origimport(name, globals, locals, fromlist)
  File "/home/jim/workspace/lgr/pinax/apps/external_apps/djangodblog/admin.py", line 14, in <module>
    admin.site.register(ErrorBatch, ErrorBatchAdmin)
  File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/sites.py", line 90, in register
    validate(admin_class, model)
  File "/usr/local/lib/python2.6/dist-packages/django/contrib/admin/validation.py", line 22, in validate
    models.get_apps()
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 100, in get_apps
    self._populate()
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 58, in _populate
    self.load_app(app_name, True)
  File "/usr/local/lib/python2.6/dist-packages/django/db/models/loading.py", line 74, in load_app
    models = import_module('.models', app_name)
  File "/usr/local/lib/python2.6/dist-packages/django/utils/importlib.py", line 35, in import_module
    __import__(name)
  File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 84, in _demandimport
    return _origimport(name, globals, locals, fromlist)
  File "/home/jim/workspace/lgr/pinax/projects/lgr/apps/account/models.py", line 7, in <module>
    from timezones.fields import TimeZoneField
  File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 103, in _demandimport
    mod = _origimport(name, globals, locals)
  File "/home/jim/workspace/lgr/pinax/apps/external_apps/timezones/fields.py", line 12, in <module>
    default_tz = pytz.timezone(getattr(settings, "TIME_ZONE", "UTC"))
  File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 75, in __getattribute__
    self._load()
  File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 47, in _load
    mod = _origimport(head, globals, locals)
  File "/home/jim/workspace/lgr/pinax/libs/external_libs/pytz-2008b/pytz/__init__.py", line 29, in <module>
    from pkg_resources import resource_stream
  File "/usr/lib/pymodules/python2.6/mercurial/demandimport.py", line 103, in _demandimport
    mod = _origimport(name, globals, locals)
  File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 2562, in <module>
    working_set.require(__requires__)
  File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 626, in require
    needed = self.resolve(parse_requirements(requirements))
  File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 505, in resolve
    requirements = list(requirements)[::-1]  # set up the stack
  File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 2380, in parse_requirements
    for line in lines:
  File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 1814, in yield_lines
    for s in yield_lines(ss):
  File "/usr/lib/python2.6/dist-packages/pkg_resources.py", line 1813, in yield_lines
    for ss in strs:
TypeError: '_demandmod' object is not iterable

like image 879
Jiaaro Avatar asked Dec 14 '09 19:12

Jiaaro


People also ask

How do I run a specific test case in Django?

If you want to run a test case class which has the path <module_name>/tests/test_views.py , you can run the command python manage.py test <module_name>. tests. test_views.

How do you run a pre-commit hook?

If you want to manually run all pre-commit hooks on a repository, run pre-commit run --all-files . To run individual hooks use pre-commit run <hook_id> . The first time pre-commit runs on a file it will automatically download, install, and run the hook.

How do I test a Django project?

The preferred way to write tests in Django is using the unittest module built-in to the Python standard library. This is covered in detail in the Writing and running tests document. You can also use any other Python test framework; Django provides an API and tools for that kind of integration.

What are pre-commit hooks?

The pre-commit hook is run first, before you even type in a commit message. It's used to inspect the snapshot that's about to be committed, to see if you've forgotten something, to make sure tests run, or to examine whatever you need to inspect in the code.


1 Answers

It looks like Mercurial's way of importing modules is clashing with Django's somehow.

Before trying to dive in and sort that out, is there any reason to not just run the tests with the normal command?

[hooks]
precommit.runtests = python manage.py test
like image 126
Steve Losh Avatar answered Sep 23 '22 05:09

Steve Losh