Using test driven development for Add On development

Our Add on has grown a lot and i want to get this beast back into a good shape. So i started looking around how this could be done best and i found the concept of Test Driven Development. And i thought i give it a try. So here is what i found so far.

First of all i found 2 options:

  1. unittest is a python module that is directly available in Blender
  2. pytest seems to be some easy alternative but it must be installed separately to get it to work

Here is a comparison: https://www.slant.co/versus/9148/9149/~unittest_vs_pytest

After some nice chat with dr_sybren on IRC i decided to give it a try and install pytest. Here is how i finally got it to work inside the Blender console:

  1. Identify where in Blender the Python libraries are located
  2. use pip to install the pytest module into the blender directory.

An example:

cd cmake-build/bin/release/2.79/python
pip install -U pytest -t lib

Now i can open Blender and in the Console i can type:

import pytest, avastar
pytest.main([avastar.__file__])

this will run all the tests i have defined in the avastar __init__.py of my Addon and report in the blender console.

Follow up questions

  1. Although this all works somehow, i wonder what i could do to avoid reinstallation of pytest after rebuilding Blender.

  2. pytest allows to run unittest tests but it also supports its own pytest format which sounds like its easier to develop tests but its not the standard way to go. But is it it actually a good choice? Or should i concentrate on working only with unittest tests?

As a temporary measure, you could install into ~/.local/lib/python3.6/site-packages/, which is generally also part of the directory structure Python searches. Alternatively, make cmake-build/bin/release a symlink to blender-src/release and don’t run make install when you rebuild Blender.

pytest allows to run unittest tests but it also supports its own pytest format which sounds like its easier to develop tests but its not the standard way to go. But is it it actually a good choice? Or should i concentrate on working only with unittest tests?

I would opt for subclassing unittest.TestCase, but I have little experience with the pytest-specific tests. Can you maybe link an example that compares the two approaches?

Regarding comparing unittest vs pytest

I have been looking around a bit but i could not find any sharp critique against pytest, And from all the examples i have seen so far it looks like writing tests with pytest is somewhat easier. I was looking with google for the search string

pytest vs unittest

This link might be ok to read:

https://automationpanda.com/2017/03/14/python-testing-101-pytest/

But you better take your own round on this. For me it looks pretty much like pytest is the more appreciated thing here.

Hmmm I’m not too fond of the way pytest magically rewrites the assert statements, which can silently fail in certain situations. This isn’t an issue when subclassing unittest.TestCase and calling specific self.assertXXX() functions. Furthermore, to me it seems that not all assertXXX calls can be rewritten as simple assert statements; I wouldn’t know how to do self.assertAlmostEqual(value, 0.1, places=4) as an assert statement for example.

If I can, after years using unittests, my preference now goes to pytest, mostly due to the ability of the parametrized test and the fixtures features, which allow to generalise the tests themselves, which is a big time saver.

https://docs.pytest.org/en/2.9.0/parametrize.html
https://docs.pytest.org/en/latest/fixture.html

My2c
L.