Django

Code

Changeset 5153

Show
Ignore:
Timestamp:
05/05/07 22:59:37 (1 year ago)
Author:
adrian
Message:

Finally began proofreading docs/testing.txt. Did the intro for now; more to come

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/docs/testing.txt

    r5152 r5153  
    33=========================== 
    44 
    5 Automated testing is an extremely useful weapon in the bug-killing arsenal 
    6 of the modern developer. When initially writing code, a test suite can be 
    7 used to validate that code behaves as expected. When refactoring or 
    8 modifying code, tests serve as a guide to ensure that behavior hasn't 
    9 changed unexpectedly as a result of the refactor. 
    10  
    11 Testing a web application is a complex task, as there are many 
    12 components of a web application that must be validated and tested. To 
    13 help you test your application, Django provides a test execution 
    14 framework, and range of utilities that can be used to simulate and 
    15 inspect various facets of a web application. 
    16  
    17     This testing framework is currently under development, and may change 
     5Automated testing is an extremely useful bug-killing tool for the modern 
     6Web developer. You can use a collection of tests -- a **test suite** -- to 
     7to solve, or avoid, a number of problems: 
     8 
     9    * When you're writing new code, you can use tests to validate your code 
     10      works as expected. 
     11 
     12    * When you're refactoring or modifying old code, you can use tests to 
     13      ensure your changes haven't affected your application's behavior 
     14      unexpectedly. 
     15 
     16Testing a Web application is a complex task, because a Web application is made 
     17of several layers of logic -- from HTTP-level request handling, to form 
     18validation and processing, to template rendering. With Django's test-execution 
     19framework and assorted utilities, you can simulate requests, insert test data, 
     20inspect your application's output and generally verify your code is doing what 
     21it should be doing. 
     22 
     23The best part is, it's really easy. 
     24 
     25.. admonition:: Note 
     26 
     27    This testing framework is currently under development. It may change 
    1828    slightly before the next official Django release. 
    1929 
     
    217227``post(path, data={}, content_type=MULTIPART_CONTENT)`` 
    218228    Make a POST request on the provided ``path``. If you provide a content type 
    219     (e.g., ``text/xml`` for an XML payload), the contents of ``data`` will be  
    220     sent as-is in the POST request, using the content type in the HTTP  
     229    (e.g., ``text/xml`` for an XML payload), the contents of ``data`` will be 
     230    sent as-is in the POST request, using the content type in the HTTP 
    221231    ``Content-Type`` header. 
    222      
    223     If you do not provide a value for ``content_type``, the values in  
     232 
     233    If you do not provide a value for ``content_type``, the values in 
    224234    ``data`` will be transmitted with a content type of ``multipart/form-data``. 
    225235    The key-value pairs in the data dictionary will be encoded as a multipart 
    226236    message and used to create the POST data payload. 
    227      
    228     To submit multiple values for a given key (for example, to specify  
    229     the selections for a multiple selection list), provide the values as a  
     237 
     238    To submit multiple values for a given key (for example, to specify 
     239    the selections for a multiple selection list), provide the values as a 
    230240    list or tuple for the required key. For example, a data dictionary of 
    231241    ``{'choices': ('a','b','d')}`` would submit three selected rows for the 
    232242    field named ``choices``. 
    233      
     243 
    234244    Submitting files is a special case. To POST a file, you need only 
    235245    provide the file field name as a key, and a file handle to the file you wish to 
     
    249259``login(**credentials)`` 
    250260    ** New in Django development version ** 
    251      
     261 
    252262    On a production site, it is likely that some views will be protected from 
    253263    anonymous access through the use of the @login_required decorator, or some 
     
    256266    this method, the Client will have all the cookies and session data required 
    257267    to pass any login-based tests that may form part of a view. 
    258      
    259     In most cases, the ``credentials`` required by this method are the username  
    260     and password of the user that wants to log in, provided as keyword  
     268 
     269    In most cases, the ``credentials`` required by this method are the username 
     270    and password of the user that wants to log in, provided as keyword 
    261271    arguments:: 
    262      
     272 
    263273        c = Client() 
    264274        c.login(username='fred', password='secret') 
     
    267277    If you are using a different authentication backend, this method may 
    268278    require different credentials. 
    269      
    270     ``login()`` returns ``True`` if it the credentials were accepted and login  
    271     was successful.  
    272          
     279 
     280    ``login()`` returns ``True`` if it the credentials were accepted and login 
     281    was successful. 
     282 
    273283    Note that since the test suite will be executed using the test database, 
    274284    which contains no users by default. As a result, logins that are valid 
    275     on your production site will not work under test conditions. You will  
     285    on your production site will not work under test conditions. You will 
    276286    need to create users as part of the test suite (either manually, or 
    277287    using a test fixture). 
     
    374384-------- 
    375385 
    376 Normal python unit tests extend a base class of ``unittest.testCase``.  
    377 Django provides an extension of this base class - ``django.test.TestCase``  
    378 - that provides some additional capabilities that can be useful for  
    379 testing web sites.  
     386Normal python unit tests extend a base class of ``unittest.testCase``. 
     387Django provides an extension of this base class - ``django.test.TestCase`` 
     388- that provides some additional capabilities that can be useful for 
     389testing web sites. 
    380390 
    381391Moving from a normal unittest TestCase to a Django TestCase is easy - just 
    382 change the base class of your test from ``unittest.TestCase`` to  
     392change the base class of your test from ``unittest.TestCase`` to 
    383393``django.test.TestCase``. All of the standard Python unit test facilities 
    384394will continue to be available, but they will be augmented with some useful 
     
    390400 
    391401Every test case in a ``django.test.TestCase`` instance has access to an 
    392 instance of a Django `Test Client`_. This Client can be accessed as  
     402instance of a Django `Test Client`_. This Client can be accessed as 
    393403``self.client``. This client is recreated for each test. 
    394404 
     
    406416 
    407417.. note:: 
    408     If you have synchronized a Django project, you have already experienced  
     418    If you have synchronized a Django project, you have already experienced 
    409419    the use of one fixture -- the ``initial_data`` fixture. Every time you 
    410420    synchronize the database, Django installs the ``initial_data`` fixture. 
    411421    This provides a mechanism to populate a new database with any initial 
    412422    data (such as a default set of categories). Fixtures with other names 
    413     can be installed manually using ``django-admin.py loaddata``.  
    414  
    415 However, for the purposes of unit testing, each test must be able to  
     423    can be installed manually using ``django-admin.py loaddata``. 
     424 
     425However, for the purposes of unit testing, each test must be able to 
    416426guarantee the contents of the database at the start of each and every 
    417 test.  
     427test. 
    418428 
    419429To define a fixture for a test, all you need to do is add a class 
    420430attribute to your test describing the fixtures you want the test to use. 
    421 For example, the test case from `Writing unittests`_ would  
     431For example, the test case from `Writing unittests`_ would 
    422432look like:: 
    423433 
     
    427437    class AnimalTestCase(TestCase): 
    428438        fixtures = ['mammals.json', 'birds'] 
    429          
     439 
    430440        def setUp(self): 
    431441            # test definitions as before 
    432442 
    433443At the start of each test case, before ``setUp()`` is run, Django will 
    434 flush the database, returning the database the state it was in directly  
    435 after ``syncdb`` was called. Then, all the named fixtures are installed.  
     444flush the database, returning the database the state it was in directly 
     445after ``syncdb`` was called. Then, all the named fixtures are installed. 
    436446In this example, any JSON fixture called ``mammals``, and any fixture 
    437 named ``birds`` will be installed. See the documentation on  
     447named ``birds`` will be installed. See the documentation on 
    438448`loading fixtures`_ for more details on defining and installing fixtures. 
    439449 
    440450.. _`loading fixtures`: ../django-admin/#loaddata-fixture-fixture 
    441451 
    442 This flush/load procedure is repeated for each test in the test case, so you  
    443 can be certain that the outcome of a test will not be affected by  
     452This flush/load procedure is repeated for each test in the test case, so you 
     453can be certain that the outcome of a test will not be affected by 
    444454another test, or the order of test execution. 
    445455 
     
    448458** New in Django development version ** 
    449459 
    450 Normal Python unit tests have a wide range of assertions, such as  
    451 ``assertTrue`` and ``assertEquals`` that can be used to validate behavior.  
     460Normal Python unit tests have a wide range of assertions, such as 
     461``assertTrue`` and ``assertEquals`` that can be used to validate behavior. 
    452462``django.TestCase`` adds to these, providing some assertions 
    453463that can be useful in testing the behavior of web sites. 
     
    459469``assertContains(response, text, count=1)`` 
    460470    Assert that a response indicates that a page was retreived successfully, 
    461     (i.e., the HTTP status code was 200), and that ``text`` occurs ``count``  
     471    (i.e., the HTTP status code was 200), and that ``text`` occurs ``count`` 
    462472    times in the content of the response. 
    463      
     473 
    464474Running tests 
    465475============= 
     
    520530    FAILED (failures=1) 
    521531 
    522 The return code for the script is the total number of failed and erroneous  
     532The return code for the script is the total number of failed and erroneous 
    523533tests. If all the tests pass, the return code is 0. 
    524534 
    525535Regardless of whether the tests pass or fail, the test database is destroyed when 
    526 all the tests have been executed.  
     536all the tests have been executed. 
    527537 
    528538Using a different testing framework 
     
    535545 
    536546When you run ``./manage.py test``, Django looks at the ``TEST_RUNNER`` 
    537 setting to determine what to do. By default, ``TEST_RUNNER`` points to  
     547setting to determine what to do. By default, ``TEST_RUNNER`` points to 
    538548``django.test.simple.run_tests``. This method defines the default Django 
    539549testing behavior. This behavior involves: 
     
    565575    will be printed to the console; `0` is no output, `1` is normal output, 
    566576    and `2` is verbose output. 
    567      
     577 
    568578    This method should return the number of tests that failed. 
    569579