Wagtail-Bird-Skinny

My first Wagtail tests

April 20, 2022

So with the Wagtail 3.0 release candidate already out in the wild, I'm starting to think about what it would take to transition this website to Wagtail 3.0, and later on to Wagtail 4.0. Given that I'm running Wagtail 2.13.1, I've got just a weeeeeeee bit of work to do around here.

I've got just a few chores on my website maintenance list around here, but I've decided that I'm going to teach myself some tests because 1) I feel like it, 2) there are much fewer consequences if I break this site, and 3) I have no tests on this site whatsoever right now.

Yup, that's right. No tests. My testing goat just fainted.

Fainting Goat

Can't have an unconscious testing goat. I need that beast around to headbutt me into keeping my code in line. So let's see if I can revive it by learning some Wagtail tests.

A good place to start as usual is with the Wagtail documentation. Turns out the Wagtail Core Team anticipated some of the tests that most Wagtail sites are going to need, so they've already created some shortcuts. Thank you Wagtail Core Team!

There are just a few authorities on the Internet screaming about you should test, test again, then test some more. I did hear them the first 1,000 times, but writing tests has always been about as fun for me as doing my taxes by hand with an ink quill. Also, most of my projects have been small, inconsequential things that other people aren't relying on to work. I mean, if that goat gif suddenly disappeared from my blog, how many people would honestly be sad about it? Probably just me, and maybe Kalob. Because he seems like someone who'd be sad about the Internet having one less goat gif.

Anyhoo, the path to building a good habit is to take the smallest of steps. So I'm just going to learn ONE simple test today. This test will confirm that two of my child page types, BlogIndexPage and BlogPage, can be created under their respective parent page types.

Before we even get to the code for the test itself, knowing where to put the testing files is an important thing. Most tutorials recommend a structure like this:

file/
  /tests/
    __init__.py
    test_models.py
    test_forms.py
    test_views.py

Turns out that the "__init.py__" file isn't optional. I totally forgot to create one when I create my test_models.py file in a tests directory and Django couldn't find my tests as a result. So when you set your tests up, if you put them in a new directory, don't forget that init file!

All right, on to the test. Let's have a look at the full code and then we'll break things down a a bit. Here is all the code from my test_models.py file.

from wagtail.tests.utils import WagtailPageTests

from home.models import HomePage
from blog.models import BlogIndexPage, BlogPage


class BlogTests(WagtailPageTests):

    def test_can_create_blog_index_page_under_home_page(self):
        self.assertCanCreateAt(HomePage, BlogIndexPage)

    def test_can_create_chapter_page_under_chapters_index_page(self):
        self.assertCanCreateAt(BlogIndexPage, BlogPage)

For the import statements, I called on wagtail.tests.utils first because the utils directory in the tests directory of Wagtail is where the test I want, WagtailPageTests, can be found. I also imported the models for the pages I'm testing, including the all-important HomePage, my BlogIndexPage, and the child of the index page BlogPage.

As the documentation shows, WagtailPageTests includes an assert method called assertCanCreateAt that tests if a particular child page can be created under a particular parent page. A test like this helps make sure that new pages can be created because a content management system isn't really all that useful if there's a bug that keeps you from making new pages.

The basic recipe for this test is to come up with a unique def name that starts with test (because apparently Django won't recognize your test as a test if it doesn't start with "test"), and then insert the parent page and the child page models in the parentheses of self.assertCanCreateAt.

Now that I have those written out and saved, I'm going to type manage.py test in the terminal with my virtual environment running to run my tests.

You think that work would be rewarded with some fireworks or something. Maybe even in a mini-parade of text emojis, but instead the output is "Ran 2 tests in 0.194s" and "OK". I mean I'd rather get "OK" than an error message, but it seems like an underwhelming outcome for a test passing. Especially since in my experience, passing a test is a danceworthy occasion.

My testing goat is dancing now though, so I think it agrees that adding even two simple tests to my site is a great start. 🤣

Dancing Goat