mirror of
https://github.com/wagtail/wagtail.git
synced 2024-11-29 17:36:49 +01:00
158 lines
5.4 KiB
Markdown
158 lines
5.4 KiB
Markdown
|
(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:
|
||
|
|
||
|
```python
|
||
|
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.
|
||
|
|
||
|
```python
|
||
|
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.
|
||
|
|
||
|
```python
|
||
|
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.
|
||
|
|
||
|
```python
|
||
|
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 [](form_data_test_helpers) 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`.
|
||
|
|
||
|
```python
|
||
|
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`.
|
||
|
|
||
|
```python
|
||
|
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.assertAllowedParentPageTypes(
|
||
|
HomePage, {ContentPage, EventIndex})
|
||
|
```
|
||
|
|
||
|
(form_data_test_helpers)=
|
||
|
|
||
|
## Form data helpers
|
||
|
|
||
|
```{eval-rst}
|
||
|
.. automodule:: wagtail.test.utils.form_data
|
||
|
|
||
|
.. autofunction:: nested_form_data
|
||
|
|
||
|
.. autofunction:: rich_text
|
||
|
|
||
|
.. autofunction:: streamfield
|
||
|
|
||
|
.. autofunction:: inline_formset
|
||
|
```
|
||
|
|
||
|
## Fixtures
|
||
|
|
||
|
### Using `dumpdata`
|
||
|
|
||
|
Creating [fixtures](django:howto/initial-data) for tests is best done by creating content in a development
|
||
|
environment, and using Django's [dumpdata](https://docs.djangoproject.com/en/stable/ref/django-admin/#django-admin-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:
|
||
|
|
||
|
```json
|
||
|
[
|
||
|
{
|
||
|
"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](https://django-treebeard.readthedocs.io/en/latest/mp_tree.html) might help in understanding how this works.
|