wagtail/docs/advanced_topics/testing.md

5.3 KiB

(reference)=

Testing your Wagtail site

Wagtail comes with some utilities that simplify writing tests for your site.

WagtailPageTests

class wagtail.test.utils.WagtailPageTests WagtailPageTests extends django.test.TestCase, adding a few new assert methods. You should extend this class to make use of its methods:

from wagtail.test.utils import WagtailPageTests
from myapp.models import MyPage

class MyPageTests(WagtailPageTests):
    def test_can_create_a_page(self):
        ...

assertCanCreateAt(parent_model, child_model, msg=None) Assert a particular child Page type can be created under a parent Page type. parent_model and child_model should be the Page classes being tested.

def test_can_create_under_home_page(self):
    # You can create a ContentPage under a HomePage
    self.assertCanCreateAt(HomePage, ContentPage)

assertCanNotCreateAt(parent_model, child_model, msg=None) Assert a particular child Page type can not be created under a parent Page type. parent_model and child_model should be the Page classes being tested.

def test_cant_create_under_event_page(self):
    # You can not create a ContentPage under an EventPage
    self.assertCanNotCreateAt(EventPage, ContentPage)

assertCanCreate(parent, child_model, data, msg=None) Assert that a child of the given Page type can be created under the parent, using the supplied POST data.

parent should be a Page instance, and child_model should be a Page subclass. data should be a dict that will be POSTed at the Wagtail admin Page creation method.

from wagtail.test.utils.form_data import nested_form_data, streamfield

def test_can_create_content_page(self):
    # Get the HomePage
    root_page = HomePage.objects.get(pk=2)

    # Assert that a ContentPage can be made here, with this POST data
    self.assertCanCreate(root_page, ContentPage, nested_form_data({
        'title': 'About us',
        'body': streamfield([
            ('text', 'Lorem ipsum dolor sit amet'),
        ])
    }))

See for a set of functions useful for constructing POST data.

assertAllowedParentPageTypes(child_model, parent_models, msg=None) Test that the only page types that child_model can be created under are parent_models.

The list of allowed parent models may differ from those set in Page.parent_page_types, if the parent models have set Page.subpage_types.

def test_content_page_parent_pages(self):
    # A ContentPage can only be created under a HomePage
    # or another ContentPage
    self.assertAllowedParentPageTypes(
        ContentPage, {HomePage, ContentPage})

    # An EventPage can only be created under an EventIndex
    self.assertAllowedParentPageTypes(
        EventPage, {EventIndex})

assertAllowedSubpageTypes(parent_model, child_models, msg=None) Test that the only page types that can be created under parent_model are child_models.

The list of allowed child models may differ from those set in Page.subpage_types, if the child models have set Page.parent_page_types.

def test_content_page_subpages(self):
    # A ContentPage can only have other ContentPage children
    self.assertAllowedSubpageTypes(
        ContentPage, {ContentPage})

    # A HomePage can have ContentPage and EventIndex children
    self.assertAllowedSubpageTypes(
        HomePage, {ContentPage, EventIndex})

(form_data_test_helpers)=

Form data helpers

.. automodule:: wagtail.test.utils.form_data

   .. autofunction:: nested_form_data

   .. autofunction:: rich_text

   .. autofunction:: streamfield

   .. autofunction:: inline_formset

Fixtures

Using dumpdata

Creating fixtures for tests is best done by creating content in a development environment, and using Django's dumpdata command.

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.

Manual modification

You could modify the dumped fixtures manually, or even write them all by hand. Here are a few things to be wary of.

Custom Page models

When creating customised Page models in fixtures, you will need to add both a wagtailcore.page entry, and one for your custom Page model.

Let's say you have a website module which defines a Homepage(Page) class. You could create such a homepage in a fixture with:

[
    {
        "model": "wagtailcore.page",
        "pk": 3,
        "fields": {
            "title": "My Customer's Homepage",
            "content_type": ["website", "homepage"],
            "depth": 2
        }
    },
    {
        "model": "website.homepage",
        "pk": 3,
        "fields": {}
    }
]

Treebeard fields

Filling in the path / numchild / depth fields is necessary in order for tree operations like get_parent() to work correctly. url_path is another field that can cause errors in some uncommon cases if it isn't filled in.

The Treebeard docs might help in understanding how this works.