summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/howto/index.txt1
-rw-r--r--docs/howto/windmill-tests.txt92
-rw-r--r--docs/index.txt4
-rw-r--r--docs/ref/index.txt1
-rw-r--r--docs/topics/testing.txt11
5 files changed, 104 insertions, 5 deletions
diff --git a/docs/howto/index.txt b/docs/howto/index.txt
index 1a27a2ebac..214f36e47f 100644
--- a/docs/howto/index.txt
+++ b/docs/howto/index.txt
@@ -25,6 +25,7 @@ you quickly accomplish common tasks.
outputting-csv
outputting-pdf
static-files
+ windmill-tests
.. seealso::
diff --git a/docs/howto/windmill-tests.txt b/docs/howto/windmill-tests.txt
new file mode 100644
index 0000000000..08931d8a97
--- /dev/null
+++ b/docs/howto/windmill-tests.txt
@@ -0,0 +1,92 @@
+.. _howto-windmill-tests:
+
+Writing a Functional Tests with Windmill
+=======================================
+
+.. currentmodule:: django.test
+
+If you need to provide custom file storage -- a common example is storing files
+on some remote system -- you can do so by defining a custom storage class.
+You'll need to follow these steps:
+
+#. Your custom storage system must be a subclass of
+ ``django.core.files.storage.Storage``::
+
+ from django.core.files.storage import Storage
+
+ class MyStorage(Storage):
+ ...
+
+#. Django must be able to instantiate your storage system without any arguments.
+ This means that any settings should be taken from ``django.conf.settings``::
+
+ from django.conf import settings
+ from django.core.files.storage import Storage
+
+ class MyStorage(Storage):
+ def __init__(self, option=None):
+ if not option:
+ option = settings.CUSTOM_STORAGE_OPTIONS
+ ...
+
+#. Your storage class must implement the ``_open()`` and ``_save()`` methods,
+ along with any other methods appropriate to your storage class. See below for
+ more on these methods.
+
+ In addition, if your class provides local file storage, it must override
+ the ``path()`` method.
+
+Your custom storage system may override any of the storage methods explained in
+:ref:`ref-files-storage`, but you **must** implement the following methods:
+
+ * :meth:`Storage.delete`
+ * :meth:`Storage.exists`
+ * :meth:`Storage.listdir`
+ * :meth:`Storage.size`
+ * :meth:`Storage.url`
+
+You'll also usually want to use hooks specifically designed for custom storage
+objects. These are:
+
+``_open(name, mode='rb')``
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+**Required**.
+
+Called by ``Storage.open()``, this is the actual mechanism the storage class
+uses to open the file. This must return a ``File`` object, though in most cases,
+you'll want to return some subclass here that implements logic specific to the
+backend storage system.
+
+``_save(name, content)``
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+Called by ``Storage.save()``. The ``name`` will already have gone through
+``get_valid_name()`` and ``get_available_name()``, and the ``content`` will be a
+``File`` object itself.
+
+Should return the actual name of name of the file saved (usually the ``name``
+passed in, but if the storage needs to change the file name return the new name
+instead).
+
+``get_valid_name(name)``
+------------------------
+
+Returns a filename suitable for use with the underlying storage system. The
+``name`` argument passed to this method is the original filename sent to the
+server, after having any path information removed. Override this to customize
+how non-standard characters are converted to safe filenames.
+
+The code provided on ``Storage`` retains only alpha-numeric characters, periods
+and underscores from the original filename, removing everything else.
+
+``get_available_name(name)``
+----------------------------
+
+Returns a filename that is available in the storage mechanism, possibly taking
+the provided filename into account. The ``name`` argument passed to this method
+will have already cleaned to a filename valid for the storage system, according
+to the ``get_valid_name()`` method described above.
+
+The code provided on ``Storage`` simply appends underscores to the filename
+until it finds one that's available in the destination directory.
diff --git a/docs/index.txt b/docs/index.txt
index 89ee463dfa..abf5580c60 100644
--- a/docs/index.txt
+++ b/docs/index.txt
@@ -142,7 +142,9 @@ The development process
:ref:`Overview <ref-django-admin>` |
:ref:`Adding custom commands <howto-custom-management-commands>`
- * **Testing:** :ref:`Overview <topics-testing>`
+ * **Testing:**
+ :ref:`Overview <topics-testing>` |
+ :ref:`Windmill <howto-windmill-tests>`
* **Deployment:**
:ref:`Overview <howto-deployment-index>` |
diff --git a/docs/ref/index.txt b/docs/ref/index.txt
index 6cc796d8e4..3ffa1fcce1 100644
--- a/docs/ref/index.txt
+++ b/docs/ref/index.txt
@@ -20,4 +20,3 @@ API Reference
signals
templates/index
unicode
-
diff --git a/docs/topics/testing.txt b/docs/topics/testing.txt
index 1256a61187..2a01df9e87 100644
--- a/docs/topics/testing.txt
+++ b/docs/topics/testing.txt
@@ -400,7 +400,7 @@ Some of the things you can do with the test client are:
a template context that contains certain values.
Note that the test client is not intended to be a replacement for Twill_,
-Selenium_, or other "in-browser" frameworks. Django's test client has
+Windmill_, or other "in-browser" frameworks. Django's test client has
a different focus. In short:
* Use Django's test client to establish that the correct view is being
@@ -409,10 +409,15 @@ a different focus. In short:
* Use in-browser frameworks such as Twill and Selenium to test *rendered*
HTML and the *behavior* of Web pages, namely JavaScript functionality.
-A comprehensive test suite should use a combination of both test types.
+A comprehensive test suite should use a combination of both test types. Which
+is why Django makes it easy to integrate with 3rd party test runners via the
+:setting:`TEST_RUNNER` setting. For convenience, Django ships a runner for
+the framework used in testing the :ref:`admin interface, <ref-contrib-admin>`
+Windmill_. Details on integrating Windmill tests with Django are available
+:ref:`here. <howto-windmill-test>`
.. _Twill: http://twill.idyll.org/
-.. _Selenium: http://www.openqa.org/selenium/
+.. _Windmill: http://www.getwindmill.com/
Overview and a quick example
~~~~~~~~~~~~~~~~~~~~~~~~~~~~