Code style for tests: boring is better?

Hi all,

I’m helping put together some automated tests for a large Python project, and a question has arisen - how should test code style relate to library/application code style?

From reading various test suites over the years, I’ve observed that tests have fewer abstractions! It’s common for test suites to be quite “boring”. There may be a few utility functions, but usually not complex class or object ownership hierarchies. This makes the code more repetitive and probably violates DRY and some other acronyms.

I think the aim here is to make the learning curve for any given test a little gentler. If I see a test fail and need to debug it, I don’t need to understand anything about the test suite architecture - I just need to read the test. The cost of this is that the overall test architecture may be less elegant and more repetitive.

My understanding here is broadly intuitive and I’d like to:

  1. Check it’s actually right!
  2. Find some more scientific grounding for this approach

Does anyone have any views on the topic? Or any recommended reading? (Books, blog posts, etc?)

Thanks!

1 Like

[…]

My understanding here is broadly intuitive and I’d like to:

  1. Check it’s actually right!
  2. Find some more scientific grounding for this approach

Does anyone have any views on the topic? Or any recommended
reading? (Books, blog posts, etc?)

This may be bias from working primarily on OpenStack-related
and similar (s)testr/testing-cabal using projects for the past
decade, but the primary non-boring features I see used frequently in
unit testing are decorators and class inheritance to DRY up a lot of
the otherwise tediously repetitive test setup boilerplate. A random
example:

The other reason is that the more complex your code is, the more likely it has bugs. You don’t want to have to have a test suite for your test suite, so you want to keep them simple. To handle the repetitiveness, features like parameterised tests push the complexity into the test runner which presumably has its own tests.

Are you using a test framework?

You probably should be using doctest or unittest in the std library, or
some third party framework.

You should use whatever abstractions are available in the framework.

The main reason you should avoid adding more and more complexity to your
test code is that the test code itself can contain bugs. If you use a
framework like unittest, at least you know that thousands of other
people have already used it and tested it and it works reliably. If you
write your own test abstrations, unless you have tests for your tests
they are probably buggy as hell.