Skip to content

Commit

Permalink
Unit tested and documented Django integration
Browse files Browse the repository at this point in the history
  • Loading branch information
CleanCut committed Jul 30, 2014
1 parent 69e0e86 commit 7ccf15a
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 10 deletions.
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ install:
- "pip install ."
- "pip install -r requirements.txt"
- "pip install coveralls"
- "pip install django"
script:
- "make test"
after_success: coveralls
8 changes: 7 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,13 @@ Version ? - ?

User Stuff

- Django...
- Django integration! There are two ways to use green while running Django
unit tests:
1) To just try it out, use the --testrunner option:
./manage.py test --testrunner=green.djangorunner.DjangoRunner
2) Make it persistent by adding the following line to your settings.py:
TEST_RUNNER=green.djangorunner.DjangoRunner
(Use green config files to customize the output)
- Switched from using stderr to stdout. This makes piping output to another
program much easier, and reserves stderr for actual errors running green
itself.
Expand Down
11 changes: 11 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,17 @@ Advanced Usage
For a list of all command-line and config-file options, please run `green --help`


Integration
-----------

### Django

- To just try it out, use the --testrunner option of `manage.py`:
./manage.py test --testrunner=green.djangorunner.DjangoRunner
- Make it persistent by adding the following line to your `settings.py`:
TEST_RUNNER=green.djangorunner.DjangoRunner


Unit Test Structure Tutorial
----------------------------

Expand Down
3 changes: 3 additions & 0 deletions green/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,9 @@ def mergeConfig(args, testing=False, coverage_testing=False): # pragma: no cover
'*/termstyle*',
'*/colorama*',
'*/mock*',
'*/django/*',
'*/pytz*', # pulled in by django
'*/pkg_resources*', # pulled in by django
tempfile.gettempdir() + '*']
if 'green' not in new_args.targets and (
False in [t.startswith('green.') for t in new_args.targets]):
Expand Down
38 changes: 30 additions & 8 deletions green/djangorunner.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
from __future__ import unicode_literals
"""
To try running Django tests using green you can run:
./manage.py test --testrunner=green.djangorunner.DjangoRunner
To make the change permanent for your project, in settings.py add:
TEST_RUNNER=green.djangorunner.DjangoRunner
"""

import os
import sys

Expand Down Expand Up @@ -48,15 +59,21 @@
# End of django fake config stuff


DjangoRunner = None
def django_missing():
raise ImportError("No django module installed")


try:
import django
if django.VERSION[:2] < (1, 6):
if django.VERSION[:2] < (1, 6): # pragma: no cover
raise ImportError("Green integration supports Django 1.6+")
from django.test.runner import DiscoverRunner



class DjangoRunner(DiscoverRunner):


def run_tests(self, test_labels, extra_tests=None, **kwargs):
"""
Run the unit tests for all the test labels in the provided list.
Expand All @@ -71,26 +88,31 @@ def run_tests(self, test_labels, extra_tests=None, **kwargs):
"""
# Django setup
self.setup_test_environment()
django_db = self.setup_databases()

# Green
if test_labels:
if type(test_labels) == tuple:
test_labels = list(test_labels)
else:
raise ValueError("test_labels should be a tuple of strings")
if not test_labels:
test_labels = ['.']
suite = loadTargets(test_labels)
old_config = self.setup_databases()

args = mergeConfig(default_args, default_args)
args.targets = test_labels
stream = GreenStream(sys.stdout, html = args.html)
runner = GreenTestRunner(verbosity = args.verbose, stream = stream,
termcolor=args.termcolor, subprocesses=args.subprocesses,
run_coverage=args.run_coverage, omit=args.omit)
suite = loadTargets(args.targets)
result = runner.run(suite)

# Django teardown
self.teardown_databases(old_config)
self.teardown_databases(django_db)
self.teardown_test_environment()
return self.suite_result(suite, result)

except ImportError:
pass


except ImportError: # pragma: no cover
DjangoRunner = django_missing
73 changes: 72 additions & 1 deletion green/test/test_djangorunner.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,77 @@
from __future__ import unicode_literals
try:
from io import StringIO
except:
from StringIO import StringIO
import sys
import unittest
try:
from unittest.mock import MagicMock
except:
from mock import MagicMock

from green import djangorunner


class TestDjangoMissing(unittest.TestCase):


def test_importError(self):
self.assertRaises(ImportError, djangorunner.django_missing)




class TestDjangoRunner(unittest.TestCase):
pass


def setUp(self):
try:
djangorunner.DjangoRunner()
except ImportError:
raise unittest.SkipTest("Django is not installed")
self.saved_stdout = sys.stdout
self.stream = StringIO()
sys.stdout = self.stream


def tearDown(self):
sys.stdout = self.saved_stdout


def test_run_testsWithLabel(self):
dr = djangorunner.DjangoRunner()
dr.setup_test_environment = MagicMock()
dr.setup_databases = MagicMock()
dr.teardown_databases = MagicMock()
dr.teardown_test_environment = MagicMock()

dr.run_tests(('green.test.test_version',))

self.assertIn('OK', self.stream.getvalue())


def test_run_testsWithoutLabel(self):
"Not passing in a label causes the targets to be ['.']"
dr = djangorunner.DjangoRunner()
dr.setup_test_environment = MagicMock()
dr.setup_databases = MagicMock()
dr.teardown_databases = MagicMock()
dr.teardown_test_environment = MagicMock()

saved_loadTargets = djangorunner.loadTargets
djangorunner.loadTargets = MagicMock()

dr.run_tests(())
djangorunner.loadTargets.assert_called_with(['.'])
djangorunner.loadTargets = saved_loadTargets
self.assertIn('No Tests Found', self.stream.getvalue())


def test_run_testsWithBadInput(self):
"Bad input causes a ValueError to be raised"
dr = djangorunner.DjangoRunner()
dr.setup_test_environment = MagicMock()
dr.setup_databases = MagicMock()

self.assertRaises(ValueError, dr.run_tests, None)

0 comments on commit 7ccf15a

Please sign in to comment.