testing.rst 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  1. .. _reference:
  2. =========================
  3. Testing your Wagtail site
  4. =========================
  5. Wagtail comes with some utilities that simplify writing tests for your site.
  6. .. automodule:: wagtail.tests.utils
  7. WagtailPageTests
  8. ================
  9. .. class:: WagtailPageTests
  10. ``WagtailPageTests`` extends ``django.test.TestCase``, adding a few new ``assert`` methods. You should extend this class to make use of its methods:
  11. .. code-block:: python
  12. from wagtail.tests.utils import WagtailPageTests
  13. from myapp.models import MyPage
  14. class MyPageTests(WagtailPageTests):
  15. def test_can_create_a_page(self):
  16. ...
  17. .. automethod:: assertCanCreateAt
  18. .. code-block:: python
  19. def test_can_create_under_home_page(self):
  20. # You can create a ContentPage under a HomePage
  21. self.assertCanCreateAt(HomePage, ContentPage)
  22. .. automethod:: assertCanNotCreateAt
  23. .. code-block:: python
  24. def test_cant_create_under_event_page(self):
  25. # You can not create a ContentPage under an EventPage
  26. self.assertCanNotCreateAt(EventPage, ContentPage)
  27. .. automethod:: assertCanCreate
  28. .. code-block:: python
  29. from wagtail.tests.utils.form_data import nested_form_data, streamfield
  30. def test_can_create_content_page(self):
  31. # Get the HomePage
  32. root_page = HomePage.objects.get(pk=2)
  33. # Assert that a ContentPage can be made here, with this POST data
  34. self.assertCanCreate(root_page, ContentPage, nested_form_data({
  35. 'title': 'About us',
  36. 'body': streamfield([
  37. ('text', 'Lorem ipsum dolor sit amet'),
  38. ])
  39. }))
  40. See :ref:`form_data_test_helpers` for a set of functions useful for constructing POST data.
  41. .. automethod:: assertAllowedParentPageTypes
  42. .. code-block:: python
  43. def test_content_page_parent_pages(self):
  44. # A ContentPage can only be created under a HomePage
  45. # or another ContentPage
  46. self.assertAllowedParentPageTypes(
  47. ContentPage, {HomePage, ContentPage})
  48. # An EventPage can only be created under an EventIndex
  49. self.assertAllowedParentPageTypes(
  50. EventPage, {EventIndex})
  51. .. automethod:: assertAllowedSubpageTypes
  52. .. code-block:: python
  53. def test_content_page_subpages(self):
  54. # A ContentPage can only have other ContentPage children
  55. self.assertAllowedSubpageTypes(
  56. ContentPage, {ContentPage})
  57. # A HomePage can have ContentPage and EventIndex children
  58. self.assertAllowedParentPageTypes(
  59. HomePage, {ContentPage, EventIndex})
  60. .. _form_data_test_helpers:
  61. Form data helpers
  62. =================
  63. .. automodule:: wagtail.tests.utils.form_data
  64. .. autofunction:: nested_form_data
  65. .. autofunction:: rich_text
  66. .. autofunction:: streamfield
  67. .. autofunction:: inline_formset
  68. Fixtures
  69. ========
  70. Using ``dumpdata``
  71. ------------------
  72. Creating :doc:`fixtures <django:howto/initial-data>` for tests is best done by creating content in a development
  73. environment, and using Django's dumpdata_ command.
  74. Note that by default ``dumpdata`` will represent ``content_type`` by the primary key; this may cause consistency issues when adding / removing models, as content types are populated separately from fixtures. To prevent this, use the ``--natural-foreign`` switch, which represents content types by ``["app", "model"]`` instead.
  75. Manual modification
  76. -------------------
  77. You could modify the dumped fixtures manually, or even write them all by hand.
  78. Here are a few things to be wary of.
  79. Custom Page models
  80. ~~~~~~~~~~~~~~~~~~
  81. When creating customised Page models in fixtures, you will need to add both a
  82. ``wagtailcore.page`` entry, and one for your custom Page model.
  83. Let's say you have a ``website`` module which defines a ``Homepage(Page)`` class.
  84. You could create such a homepage in a fixture with:
  85. .. code-block:: json
  86. [
  87. {
  88. "model": "wagtailcore.page",
  89. "pk": 3,
  90. "fields": {
  91. "title": "My Customer's Homepage",
  92. "content_type": ["website", "homepage"],
  93. "depth": 2
  94. }
  95. },
  96. {
  97. "model": "website.homepage",
  98. "pk": 3,
  99. "fields": {}
  100. }
  101. ]
  102. Treebeard fields
  103. ~~~~~~~~~~~~~~~~
  104. Filling in the ``path`` / ``numchild`` / ``depth`` fields is necessary in order for tree operations like ``get_parent()`` to work correctly.
  105. ``url_path`` is another field that can cause errors in some uncommon cases if it isn't filled in.
  106. The `Treebeard docs`_ might help in understanding how this works.
  107. .. _dumpdata: https://docs.djangoproject.com/en/stable/ref/django-admin/#django-admin-dumpdata
  108. .. _Treebeard docs: https://django-treebeard.readthedocs.io/en/latest/mp_tree.html