Writing Pelican Plugin tests
A New Plugin
So you wrote a plugin for pelican, good for you! But how do you test that it does what it should do and how do you handle
Looking at the pelican-plugins repository, only very little testing is done.
You might argue that for simple content modification no tests are necessary, but since you should cover both
python3 it is highly likely that there is something out there that will make your plugin crash.
It is always a good idea to point the finger at yourself when describing ‘bad’ behaviour.
So let’s look what could go wrong what you are not expecting.
For example, have a look at pelican-toc#1.
I clearly did not think about
python2 behaviour, mixing Unicode with different encodings.
Of course it is not really viable to test your plugins on your own blog with different settings and it first looks like a huge task to setup unittests for your plugin, since you probably don’t need to initialize and run the complete pelican application just to test some content formatting. But what is really needed to test your plugins?
Pelican strikes back
The pelican-source code looks kind of intimidating for someone new to
python or even just new to pelican.
There is a lot of clutter because of back wards compatibility and lots of (maybe to many) features.
It is an ongoing afford to clean it up and provide better documentation for potential contributors.
Basically, what pelican does is the following:
- Pull all settings from files and command line arguments and issue warnings where needed
- initialize plugins
- initialize Generators
- generate Generator context, this is where the heavy lifting gets done and your content get parsed via Readers
- Write the aggregated content into output, while for example, fixing URLs
So, what do we really need of this long list to write some tests for our context modifying plugin?
Return of unittest
First get an example configuration, you can either go with the one provided in the pelican-plugins
test_data folder or leverage the
get_settings function from
You probably also want to read some test files, most likely
reStructuredText formatted, since that is what most commonly used to input content into pelican, so you need some
Readers from pelican-readers.
Next step is to save the output from your reader.
In Pelican this is done by pelican-contents.
Contents would be
That is all that is needed to simulate some parsed articles, now let us look at how it is done.
These are the imports for the pelican related stuff mentioned earlier.
from pelican.readers import MarkdownReader from pelican.contents import Article from pelican.tests.support import get_settings
Other imports needed are our testing environment
unittest as well as our plugin
import unittest import toc
And now for the main part, a Class extending
unittest.TestCase, which contains the tests.
We can pull default settings and our reader class wide.
Then we can parse our test article and compare it to what it should look like.
class TestToCGeneration(unittest.TestCase): settings = get_settings() md_reader = MarkdownReader(settings) def _handle_article_generation(self, path): content, metadata = self.md_reader.read(path) return Article(content=content, metadata=metadata) def test_toc_generation(self): article_with_headers_path = "test_data/article_with_headers.md" article_with_headers_toc_path = "test_data/article_with_headers_toc.html" article_with_headers = self._handle_article_generation( article_with_headers_path) toc.generate_toc(article_with_headers) with open(article_with_headers_toc_path, 'r') as f: test_toc = f.read() self.assertEqual( article_with_headers.toc, test_toc, "bad toc generated") if __name__ == "__main__": unittest.main()
Sweet right? Nothing complex, just pull some default settings, initialize a Reader, read from formatted source files and compare the output with what it should look like. Now go and write some simple tests, no more excuses!