diff options
| author | Jason Pellerin <jpellerin@gmail.com> | 2006-09-04 02:20:26 +0000 |
|---|---|---|
| committer | Jason Pellerin <jpellerin@gmail.com> | 2006-09-04 02:20:26 +0000 |
| commit | b17f250907351923f39f8a50b87a35b26d2ca307 (patch) | |
| tree | bd0202dea501c6678a0b56b8e108194aab78468d /docs | |
| parent | 5a58772a1ee470e2890d3c716ce4918555100a55 (diff) | |
[multi-db] Merge trunk to [3661]
git-svn-id: http://code.djangoproject.com/svn/django/branches/multiple-db-support@3712 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/add_ons.txt | 9 | ||||
| -rw-r--r-- | docs/contributing.txt | 13 | ||||
| -rw-r--r-- | docs/django-admin.txt | 29 | ||||
| -rw-r--r-- | docs/faq.txt | 6 | ||||
| -rw-r--r-- | docs/settings.txt | 24 | ||||
| -rw-r--r-- | docs/sitemaps.txt | 320 | ||||
| -rw-r--r-- | docs/sites.txt | 11 | ||||
| -rw-r--r-- | docs/templates_python.txt | 19 | ||||
| -rw-r--r-- | docs/testing.txt | 303 |
9 files changed, 726 insertions, 8 deletions
diff --git a/docs/add_ons.txt b/docs/add_ons.txt index 6507f3b139..a0377700d7 100644 --- a/docs/add_ons.txt +++ b/docs/add_ons.txt @@ -153,6 +153,15 @@ See the `sites documentation`_. .. _sites documentation: http://www.djangoproject.com/documentation/sites/ +sitemaps +======== + +A framework for generating Google sitemap XML files. + +See the `sitemaps documentation`_. + +.. _sitemaps documentation: http://www.djangoproject.com/documentation/sitemaps/ + syndication =========== diff --git a/docs/contributing.txt b/docs/contributing.txt index 9d116cac10..3d101c3241 100644 --- a/docs/contributing.txt +++ b/docs/contributing.txt @@ -168,6 +168,19 @@ Please follow these coding standards when writing code for inclusion in Django: {{foo}} + * In Django views, the first parameter in a view function should be called + ``request``. + + Do this:: + + def my_view(request, foo): + # ... + + Don't do this:: + + def my_view(req, foo): + # ... + * Please don't put your name in the code. While we appreciate all contributions to Django, our policy is not to publish individual developer names in code -- for instance, at the top of Python modules. diff --git a/docs/django-admin.txt b/docs/django-admin.txt index eb7b2dccd6..672200c5e7 100644 --- a/docs/django-admin.txt +++ b/docs/django-admin.txt @@ -292,6 +292,13 @@ this command to install the default apps. If you're installing the ``django.contrib.auth`` application, ``syncdb`` will give you the option of creating a superuser immediately. +test +---- + +Discover and run tests for all installed models. See `Testing Django applications`_ for more information. + +.. _testing django applications: ../testing/ + validate -------- @@ -338,6 +345,17 @@ setting the Python path for you. Displays a help message that includes a terse list of all available actions and options. +--noinput +--------- + +Inform django-admin that the user should NOT be prompted for any input. Useful if +the django-admin script will be executed as an unattended, automated script. + +--noreload +---------- + +Disable the use of the auto-reloader when running the development server. + --version --------- @@ -348,6 +366,17 @@ Example output:: 0.9.1 0.9.1 (SVN) +--verbosity +----------- + +Example usage:: + + django-admin.py syncdb --verbosity=2 + +Verbosity determines the amount of notification and debug information that +will be printed to the console. '0' is no output, '1' is normal output, +and `2` is verbose output. + Extra niceties ============== diff --git a/docs/faq.txt b/docs/faq.txt index d39e203c76..204c69244d 100644 --- a/docs/faq.txt +++ b/docs/faq.txt @@ -103,10 +103,10 @@ Lawrence, Kansas, USA. On IRC, Simon goes by ``SimonW``. `Wilson Miner`_ - Wilson's design-fu makes us all look like rock stars. By day, he's an + Wilson's design-fu makes us all look like rock stars. By day, he's an interactive designer for `Apple`. Don't ask him what he's working on, or he'll have to kill you. He lives in San Francisco. - + On IRC, Wilson goes by ``wilsonian``. .. _`World Online`: http://code.djangoproject.com/wiki/WorldOnline @@ -641,7 +641,7 @@ How can I get started contributing code to Django? Thanks for asking! We've written an entire document devoted to this question. It's titled `Contributing to Django`_. -.. _Contributing do Django: http://www.djangoproject.com/documentation/contributing/ +.. _Contributing to Django: http://www.djangoproject.com/documentation/contributing/ I submitted a bug fix in the ticket system several weeks ago. Why are you ignoring my patch? -------------------------------------------------------------------------------------------- diff --git a/docs/settings.txt b/docs/settings.txt index d9df111155..b927b62ca7 100644 --- a/docs/settings.txt +++ b/docs/settings.txt @@ -754,6 +754,30 @@ misspelled) variables. See `How invalid variables are handled`_. .. _How invalid variables are handled: http://www.djangoproject.com/documentation/templates_python/#how-invalid-variables-are-handled +TEST_RUNNER +----------- + +**New in Django development version** + +Default: ``'django.test.simple.run_tests'`` + +The name of the method to use for starting the test suite. See +`Testing Django Applications`_. + +.. _Testing Django Applications: ../testing/ + +TEST_DATABASE_NAME +------------------ + +**New in Django development version** + +Default: ``None`` + +The name of database to use when running the test suite. If a value of +``None`` is specified, the test database will use the name ``'test_' + settings.DATABASE_NAME``. See `Testing Django Applications`_. + +.. _Testing Django Applications: ../testing/ + TIME_FORMAT ----------- diff --git a/docs/sitemaps.txt b/docs/sitemaps.txt new file mode 100644 index 0000000000..fec65572f2 --- /dev/null +++ b/docs/sitemaps.txt @@ -0,0 +1,320 @@ +===================== +The sitemap framework +===================== + +**New in Django development version**. + +Django comes with a high-level sitemap-generating framework that makes +creating `Google Sitemap`_ XML files easy. + +.. _Google Sitemap: http://www.google.com/webmasters/sitemaps/docs/en/protocol.html + +Overview +======== + +A sitemap is an XML file on your Web site that tells search-engine indexers how +frequently your pages change and how "important" certain pages are in relation +to other pages on your site. This information helps search engines index your +site. + +The Django sitemap framework automates the creation of this XML file by letting +you express this information in Python code. + +It works much like Django's `syndication framework`_. To create a sitemap, just +write a ``Sitemap`` class and point to it in your URLconf_. + +.. _syndication framework: http://www.djangoproject.com/documentation/syndication/ +.. _URLconf: http://www.djangoproject.com/documentation/url_dispatch/ + +Installation +============ + +To install the sitemap app, follow these steps: + + 1. Add ``'django.contrib.sitemaps'`` to your INSTALLED_APPS_ setting. + 2. Make sure ``'django.template.loaders.app_directories.load_template_source'`` + is in your TEMPLATE_LOADERS_ setting. It's in there by default, so + you'll only need to change this if you've changed that setting. + 3. Make sure you've installed the `sites framework`_. + +(Note: The sitemap application doesn't install any database tables. The only +reason it needs to go into ``INSTALLED_APPS`` is so that the +``load_template_source`` template loader can find the default templates.) + +.. _INSTALLED_APPS: http://www.djangoproject.com/documentation/settings/#installed-apps +.. _TEMPLATE_LOADERS: http://www.djangoproject.com/documentation/settings/#template-loaders +.. _sites framework: http://www.djangoproject.com/documentation/sites/ + +Initialization +============== + +To activate sitemap generation on your Django site, add this line to your +URLconf_: + + (r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}) + +This tells Django to build a sitemap when a client accesses ``/sitemap.xml``. + +The name of the sitemap file is not important, but the location is. Google will +only index links in your sitemap for the current URL level and below. For +instance, if ``sitemap.xml`` lives in your root directory, it may reference any +URL in your site. However, if your sitemap lives at ``/content/sitemap.xml``, +it may only reference URLs that begin with ``/content/``. + +The sitemap view takes an extra, required argument: ``{'sitemaps': sitemaps}``. +``sitemaps`` should be a dictionary that maps a short section label (e.g., +``blog`` or ``news``) to its ``Sitemap`` class (e.g., ``BlogSitemap`` or +``NewsSitemap``). It may also map to an *instance* of a ``Sitemap`` class +(e.g., ``BlogSitemap(some_var)``). + +.. _URLconf: http://www.djangoproject.com/documentation/url_dispatch/ + +Sitemap classes +=============== + +A ``Sitemap`` class is a simple Python class that represents a "section" of +entries in your sitemap. For example, one ``Sitemap`` class could represent all +the entries of your weblog, while another could represent all of the events in +your events calendar. + +In the simplest case, all these sections get lumped together into one +``sitemap.xml``, but it's also possible to use the framework to generate a +sitemap index that references individual sitemap files, one per section. (See +`Creating a sitemap index`_ below.) + +``Sitemap`` classes must subclass ``django.contrib.sitemaps.Sitemap``. They can +live anywhere in your codebase. + +A simple example +================ + +Let's assume you have a blog system, with an ``Entry`` model, and you want your +sitemap to include all the links to your individual blog entries. Here's how +your sitemap class might look:: + + from django.contrib.sitemaps import Sitemap + from mysite.blog.models import Entry + + class BlogSitemap(Sitemap): + changefreq = "never" + priority = 0.5 + + def items(self): + return Entry.objects.filter(is_draft=False) + + def lastmod(self, obj): + return obj.pub_date + +Note: + + * ``changefreq`` and ``priority`` are class attributes corresponding to + ``<changefreq>`` and ``<priority>`` elements, respectively. They can be + made callable as functions, as ``lastmod`` was in the example. + * ``items()`` is simply a method that returns a list of objects. The objects + returned will get passed to any callable methods corresponding to a + sitemap property (``location``, ``lastmod``, ``changefreq``, and + ``priority``). + * ``lastmod`` should return a Python ``datetime`` object. + * There is no ``location`` method in this example, but you can provide it + in order to specify the URL for your object. By default, ``location()`` + calls ``get_absolute_url()`` on each object and returns the result. + +Sitemap class reference +======================= + +A ``Sitemap`` class can define the following methods/attributes: + +``items`` +--------- + +**Required.** A method that returns a list of objects. The framework doesn't +care what *type* of objects they are; all that matters is that these objects +get passed to the ``location()``, ``lastmod()``, ``changefreq()`` and +``priority()`` methods. + +``location`` +------------ + +**Optional.** Either a method or attribute. + +If it's a method, it should return the absolute URL for a given object as +returned by ``items()``. + +If it's an attribute, its value should be a string representing an absolute URL +to use for *every* object returned by ``items()``. + +In both cases, "absolute URL" means a URL that doesn't include the protocol or +domain. Examples: + + * Good: ``'/foo/bar/'`` + * Bad: ``'example.com/foo/bar/'`` + * Bad: ``'http://example.com/foo/bar/'`` + +If ``location`` isn't provided, the framework will call the +``get_absolute_url()`` method on each object as returned by ``items()``. + +``lastmod`` +----------- + +**Optional.** Either a method or attribute. + +If it's a method, it should take one argument -- an object as returned by +``items()`` -- and return that object's last-modified date/time, as a Python +``datetime.datetime`` object. + +If it's an attribute, its value should be a Python ``datetime.datetime`` object +representing the last-modified date/time for *every* object returned by +``items()``. + +``changefreq`` +-------------- + +**Optional.** Either a method or attribute. + +If it's a method, it should take one argument -- an object as returned by +``items()`` -- and return that object's change frequency, as a Python string. + +If it's an attribute, its value should be a string representing the change +frequency of *every* object returned by ``items()``. + +Possible values for ``changefreq``, whether you use a method or attribute, are: + + * ``'always'`` + * ``'hourly'`` + * ``'daily'`` + * ``'weekly'`` + * ``'monthly'`` + * ``'yearly'`` + * ``'never'`` + +``priority`` +------------ + +**Optional.** Either a method or attribute. + +If it's a method, it should take one argument -- an object as returned by +``items()`` -- and return that object's priority, as either a string or float. + +If it's an attribute, its value should be either a string or float representing +the priority of *every* object returned by ``items()``. + +Example values for ``priority``: ``0.4``, ``1.0``. The default priority of a +page is ``0.5``. See Google's documentation for more documentation. + +.. _Google's documentation: http://www.google.com/webmasters/sitemaps/docs/en/protocol.html + +Shortcuts +========= + +The sitemap framework provides a couple convenience classes for common cases: + +``FlatPageSitemap`` +------------------- + +The ``django.contrib.sitemaps.FlatPageSitemap`` class looks at all flatpages_ +defined for the current ``SITE_ID`` (see the `sites documentation`_) and +creates an entry in the sitemap. These entries include only the ``location`` +attribute -- not ``lastmod``, ``changefreq`` or ``priority``. + +.. _flatpages: http://www.djangoproject.com/documentation/flatpages/ +.. _sites documentation: http://www.djangoproject.com/documentation/sites/ + +``GenericSitemap`` +------------------ + +The ``GenericSitemap`` class works with any `generic views`_ you already have. +To use it, create an instance, passing in the same ``info_dict`` you pass to +the generic views. The only requirement is that the dictionary have a +``queryset`` entry. It may also have a ``date_field`` entry that specifies a +date field for objects retrieved from the ``queryset``. This will be used for +the ``lastmod`` attribute in the generated sitemap. You may also pass +``priority`` and ``changefreq`` keyword arguments to the ``GenericSitemap`` +constructor to specify these attributes for all URLs. + +.. _generic views: http://www.djangoproject.com/documentation/generic_views/ + +Example +------- + +Here's an example of a URLconf_ using both:: + + from django.conf.urls.defaults import * + from django.contrib.sitemaps import FlatPageSitemap, GenericSitemap + from mysite.blog.models import Entry + + info_dict = { + 'queryset': Entry.objects.all(), + 'date_field': 'pub_date', + } + + sitemaps = { + 'flatpages': FlatPageSitemap, + 'blog': GenericSitemap(info_dict, priority=0.6), + } + + urlpatterns = patterns('', + # some generic view using info_dict + # ... + + # the sitemap + (r'^sitemap.xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}) + ) + +.. _URLconf: http://www.djangoproject.com/documentation/url_dispatch/ + +Creating a sitemap index +======================== + +The sitemap framework also has the ability to create a sitemap index that +references individual sitemap files, one per each section defined in your +``sitemaps`` dictionary. The only differences in usage are: + + * You use two views in your URLconf: ``django.contrib.sitemaps.views.index`` + and ``django.contrib.sitemaps.views.sitemap``. + * The ``django.contrib.sitemaps.views.sitemap`` view should take a + ``section`` keyword argument. + +Here is what the relevant URLconf lines would look like for the example above:: + + (r'^sitemap.xml$', 'django.contrib.sitemaps.views.index', {'sitemaps': sitemaps}) + (r'^sitemap-(?P<section>.+).xml$', 'django.contrib.sitemaps.views.sitemap', {'sitemaps': sitemaps}) + +This will automatically generate a ``sitemap.xml`` file that references +both ``sitemap-flatpages.xml`` and ``sitemap-blog.xml``. The ``Sitemap`` +classes and the ``sitemaps`` dict don't change at all. + +Pinging Google +============== + +You may want to "ping" Google when your sitemap changes, to let it know to +reindex your site. The framework provides a function to do just that: +``django.contrib.sitemaps.ping_google()``. + +``ping_google()`` takes an optional argument, ``sitemap_url``, which should be +the absolute URL of your site's sitemap (e.g., ``'/sitemap.xml'``). If this +argument isn't provided, ``ping_google()`` will attempt to figure out your +sitemap by performing a reverse looking in your URLconf. + +``ping_google()`` raises the exception +``django.contrib.sitemaps.SitemapNotFound`` if it cannot determine your sitemap +URL. + +One useful way to call ``ping_google()`` is from a model's ``save()`` method:: + + from django.contrib.sitemaps import ping_google + + class Entry(models.Model): + # ... + def save(self): + super(Entry, self).save() + try: + ping_google() + except Exception: + # Bare 'except' because we could get a variety + # of HTTP-related exceptions. + pass + +A more efficient solution, however, would be to call ``ping_google()`` from a +cron script, or some other scheduled task. The function makes an HTTP request +to Google's servers, so you may not want to introduce that network overhead +each time you call ``save()``. diff --git a/docs/sites.txt b/docs/sites.txt index cca9f14f31..8c5f1fc64b 100644 --- a/docs/sites.txt +++ b/docs/sites.txt @@ -266,7 +266,18 @@ this:: If you attempt to use ``CurrentSiteManager`` and pass a field name that doesn't exist, Django will raise a ``ValueError``. +Finally, note that you'll probably want to keep a normal (non-site-specific) +``Manager`` on your model, even if you use ``CurrentSiteManager``. As explained +in the `manager documentation`_, if you define a manager manually, then Django +won't create the automatic ``objects = models.Manager()`` manager for you. +Also, note that certain parts of Django -- namely, the Django admin site and +generic views -- use whichever manager is defined *first* in the model, so if +you want your admin site to have access to all objects (not just site-specific +ones), put ``objects = models.Manager()`` in your model, before you define +``CurrentSiteManager``. + .. _manager: http://www.djangoproject.com/documentation/model_api/#managers +.. _manager documentation: http://www.djangoproject.com/documentation/model_api/#managers How Django uses the sites framework =================================== diff --git a/docs/templates_python.txt b/docs/templates_python.txt index 62069ffd6a..aa7fa901b0 100644 --- a/docs/templates_python.txt +++ b/docs/templates_python.txt @@ -300,13 +300,22 @@ If ``TEMPLATE_CONTEXT_PROCESSORS`` contains this processor, every * ``user`` -- An ``auth.User`` instance representing the currently logged-in user (or an ``AnonymousUser`` instance, if the client isn't logged in). See the `user authentication docs`. - * ``messages`` -- A list of ``auth.Message`` objects for the currently - logged-in user. - * ``perms`` -- An instance of ``django.core.context_processors.PermWrapper``, - representing the permissions that the currently logged-in user has. See - the `permissions docs`_. + + * ``messages`` -- A list of messages (as strings) for the currently + logged-in user. Behind the scenes, this calls + ``request.user.get_and_delete_messages()`` for every request. That method + collects the user's messages and deletes them from the database. + + Note that messages are set with ``user.add_message()``. See the + `message docs`_ for more. + + * ``perms`` -- An instance of + ``django.core.context_processors.PermWrapper``, representing the + permissions that the currently logged-in user has. See the `permissions + docs`_. .. _user authentication docs: http://www.djangoproject.com/documentation/authentication/#users +.. _message docs: http://www.djangoproject.com/documentation/authentication/#messages .. _permissions docs: http://www.djangoproject.com/documentation/authentication/#permissions django.core.context_processors.debug diff --git a/docs/testing.txt b/docs/testing.txt new file mode 100644 index 0000000000..98ed1e8aec --- /dev/null +++ b/docs/testing.txt @@ -0,0 +1,303 @@ +=========================== +Testing Django applications +=========================== + +**New in Django development version**. + +Automated testing is an extremely useful weapon in the bug-killing arsenal +of the modern developer. When initially writing code, a test suite can be +used to validate that code behaves as expected. When refactoring or +modifying code, tests serve as a guide to ensure that behavior hasn't +changed unexpectedly as a result of the refactor. + +Testing an web application is a complex task, as there are many +components of a web application that must be validated and tested. To +help you test your application, Django provides a test execution +framework, and range of utilities that can be used to stimulate and +inspect various facets of a web application. + + This testing framework is currently under development, and may change + slightly before the next official Django release. + + (That's *no* excuse not to write tests, though!) + +Writing tests +============= + +Tests in Django come in two forms: doctests and unit tests. + +Writing doctests +---------------- + +Doctests use Python's standard doctest_ module, which searches for tests in +your docstrings. Django's test runner looks for doctests in your ``models.py`` +file, and executes any that it finds. Django will also search for a file +called ``tests.py`` in the application directory (i.e., the directory that +holds ``models.py``). If a ``tests.py`` is found, it will also be searched +for doctests. + +.. admonition:: What's a **docstring**? + + A good explanation of docstrings (and some guidlines for using them + effectively) can be found in :PEP:`257`: + + A docstring is a string literal that occurs as the first statement in + a module, function, class, or method definition. Such a docstring + becomes the ``__doc__`` special attribute of that object. + + Since tests often make great documentation, doctest lets you put your + tests directly in your docstrings. + +You can put doctest strings on any object in your ``models.py``, but it's +common practice to put application-level doctests in the module docstring, and +model-level doctests in the docstring for each model. + +For example:: + + from django.db import model + + class Animal(models.Model): + """ + An animal that knows how to make noise + + # Create some animals + >>> lion = Animal.objects.create(name="lion", sound="roar") + >>> cat = Animal.objects.create(name="cat", sound="meow") + + # Make 'em speak + >>> lion.speak() + 'The lion says "roar"' + >>> cat.speak() + 'The cat says "meow"' + """ + + name = models.CharField(maxlength=20) + sound = models.CharField(maxlength=20) + + def speak(self): + return 'The %s says "%s"' % (self.name, self.sound) + +When you `run your tests`_, the test utility will find this docstring, notice +that portions of it look like an interactive Python session, and execute those +lines while checking that the results match. + +For more details about how doctest works, see the `standard library +documentation for doctest`_ + +.. _doctest: http://docs.python.org/lib/module-doctest.html +.. _standard library documentation for doctest: doctest_ + +Writing unittests +----------------- + +Like doctests, Django's unit tests use a standard library module: unittest_. +As with doctests, Django's test runner looks for any unit test cases defined +in ``models.py``, or in a ``tests.py`` file in your application directory. + +An equivalent unittest test case for the above example would look like:: + + import unittest + from myapp.models import Animal + + class AnimalTestCase(unittest.TestCase): + + def setUp(self): + self.lion = Animal.objects.create(name="lion", sound="roar") + self.cat = Animal.objects.create(name="cat", sound="meow") + + def testSpeaking(self): + self.assertEquals(self.lion.speak(), 'The lion says "roar"') + self.assertEquals(self.cat.speak(), 'The cat says "meow"') + +When you `run your tests`_, the test utility will find all the test cases +(that is, subclasses of ``unittest.TestCase``) in ``tests.py``, automatically +build a test suite out of those test cases, and run that suite. + +For more details about ``unittest``, see the `standard library unittest +documentation`_. + +.. _unittest: http://docs.python.org/lib/module-unittest.html +.. _standard library unittest documentation: unittest_ +.. _run your tests: `Running tests`_ + +Which should I use? +------------------- + +Choosing a test framework is often contentious, so Django simply supports +both of the standard Python test frameworks. Choosing one is up to each +developer's personal tastes; each is supported equally. Since each test +system has different benefits, the best approach is probably to use both +together, picking the test system to match the type of tests you need to +write. + +For developers new to testing, however, this choice can seem +confusing, so here are a few key differences to help you decide weather +doctests or unit tests are right for you. + +If you've been using Python for a while, ``doctest`` will probably feel more +"pythonic". It's designed to make writing tests as easy as possible, so +there's no overhead of writing classes or methods; you simply put tests in +docstrings. This gives the added advantage of given your modules automatic +documentation -- well-written doctests can kill both the documentation and the +testing bird with a single stone. + +For developers just getting started with testing, using doctests will probably +get you started faster. + +The ``unittest`` framework will probably feel very familiar to developers +coming from Java. Since ``unittest`` is inspired by Java's JUnit, if +you've used testing frameworks in other languages that similarly were +inspired by JUnit, ``unittest`` should also feel pretty familiar. + +Since ``unittest`` is organized around classes and methods, if you need +to write a bunch of tests that all share similar code, you can easily use +subclass to abstract common tasks; this makes test code shorter and cleaner. +There's also support for explicit setup and/or cleanup routines, which give +you a high level of control over the environment your test cases run in. + +Again, remember that you can use both systems side-by-side (even in the same +app). In the end, most projects will eventually end up using both; each shines +in different circumstances. + +Testing utilities +================= + +Test Client +----------- + +A dummy browser; instruments the template generation process... + +Fixtures +-------- + +Feature still to come... + + +Running tests +============= + +Run your tests using your project's ``manage.py`` utility:: + + $ ./manage.py test + +If you only want to run tests for a particular application, add the +application name to the command line. For example, if your +``INSTALLED_APPS`` contains ``myproject.polls`` and ``myproject.animals``, +but you only want to run the animals unit tests, run:: + + $ ./manage.py test animals + +When you run your tests, you'll see a bunch of text flow by as the test +database is created and models are initialized. This test database is +created from scratch every time you run your tests. + +By default, the test database gets its name by prepending ``test_`` to +the database name specified by the ``DATABASE_NAME`` setting; all other +database settings will the same as they would be for the project normally. +If you wish to use a name other than the default for the test database, +you can use the ``TEST_DATABASE_NAME`` setting to provide a name. + +Once the test database has been established, Django will run your tests. +If everything goes well, at the end you'll see:: + + ---------------------------------------------------------------------- + Ran 22 tests in 0.221s + + OK + +If there are test failures, however, you'll see full details about what tests +failed:: + + ====================================================================== + FAIL: Doctest: ellington.core.throttle.models + ---------------------------------------------------------------------- + Traceback (most recent call last): + File "/dev/django/test/doctest.py", line 2153, in runTest + raise self.failureException(self.format_failure(new.getvalue())) + AssertionError: Failed doctest test for myapp.models + File "/dev/myapp/models.py", line 0, in models + + ---------------------------------------------------------------------- + File "/dev/myapp/models.py", line 14, in myapp.models + Failed example: + throttle.check("actor A", "action one", limit=2, hours=1) + Expected: + True + Got: + False + + ---------------------------------------------------------------------- + Ran 2 tests in 0.048s + + FAILED (failures=1) + +When the tests have all been executed, the test database is destroyed. + +Using a different testing framework +=================================== + +Doctest and Unittest are not the only Python testing frameworks. While +Django doesn't provide explicit support these alternative frameworks, +it does provide a mechanism to allow you to invoke tests constructed for +an alternative framework as if they were normal Django tests. + +When you run ``./manage.py test``, Django looks at the ``TEST_RUNNER`` +setting to determine what to do. By default, ``TEST_RUNNER`` points to ``django.test.simple.run_tests``. This method defines the default Django +testing behaviour. This behaviour involves: + +#. Creating the test database +#. Running ``syncdb`` to install models and initial data into the test database +#. Looking for Unit Tests and Doctests in ``models.py`` and ``tests.py`` file for each installed application +#. Running the Unit Tests and Doctests that are found +#. Destroying the test database. + +If you define your own test runner method and point ``TEST_RUNNER`` +at that method, Django will execute your test runner whenever you run +``./manage.py test``. In this way, it is possible to use any test +framework that can be executed from Python code. + +Defining a test runner +---------------------- +By convention, a test runner should be called ``run_tests``; however, you +can call it anything you want. The only requirement is that it accept two +arguments: + +``run_tests(module_list, verbosity=1)`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The module list is the list of Python modules that contain the models to be +tested. This is the same format returned by ``django.db.models.get_apps()`` + +Verbosity determines the amount of notification and debug information that +will be printed to the console; '0' is no output, '1' is normal output, +and `2` is verbose output. + +Testing utilities +----------------- + +To assist in the creation of your own test runner, Django provides +a number of utility methods in the ``django.test.utils`` module. + +``create_test_db(verbosity=1, autoclobber=False)``: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Creates a new test database, and run ``syncdb`` against it. + +``verbosity`` has the same behaviour as in the test runner. + +``Autoclobber`` describes the behavior that will occur if a database with +the same name as the test database is discovered. If ``autoclobber`` is False, +the user will be asked to approve destroying the existing database. ``sys.exit`` +is called if the user does not approve. If autoclobber is ``True``, the database +will be destroyed without consulting the user. + +``create_test_db()`` has the side effect of modifying +``settings.DATABASE_NAME`` to match the name of the test database. + +``destroy_test_db(old_database_name, verbosity=1)``: +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Destroys the database with the name ``settings.DATABASE_NAME`` matching, +and restores the value of ``settings.DATABASE_NAME`` to the provided name. + +``verbosity`` has the same behaviour as in the test runner. |
