Skip to content

Instantly share code, notes, and snippets.

@niphlod
Last active December 6, 2016 21:50
Show Gist options
  • Save niphlod/f73c780109e30aa8435dcc3a8ab1ed32 to your computer and use it in GitHub Desktop.
Save niphlod/f73c780109e30aa8435dcc3a8ab1ed32 to your computer and use it in GitHub Desktop.
draft on how to approach testing

Writing tests that matter

Given the enormous expansion dbatools is seeing, adopting ANY automated test facility adds value. Tons of pages have been written about how to correctly test code, from pieces to full apps. Take a quick google search on "unittests", "integration tests", "regression tests", "behavioural tests", "pragmatic testing" to be overwhelmed with options and opinions. This is by no means a complete guide, but just a reminder for newcomers wanting to contribute to dbatools testing, now that "appveyor via pester" recently came into play.

In a large module like dbatools, offering all kinds of features in a wide range of environments (a quick calculation approximately sums up at least 600 different ones), things WILL definitely evolve/mature.

There's already a separation about "commands" (the "function" folder in dbatools) and shared bits that "commands" use as a base for more complicated operations (the "internals" folder).

Unittests are extremely good to avoid regressions, so if you think there can be one, start from there.

When starting writing unittests, which are the most simple to write, there are a few things to keep in mind before,after and always.

before

We need tests to make sure:

  • things don't break
  • things won't break
  • things play nicely with each other
  • things do what they've been created for

after

We wrote a good test when it improved dbatools:

  • We won't waste any more time making sure things work the way they're supposed to
  • We won't waste anyone else's time testing the same thing
  • We can happily welcome new features that won't break existing ones
  • We made sure a new feature can still be added without altering the original unittest
  • We know we'll receive praises from core-devs or code-refactors when they'll reinvent a better way to do the same thing, making sure they aren't breaking anything

always

  • Make sure the time is better spent writing unittests mocking a resource that can be easily declined in the aforementioned hundreds of envs VS handing off that piece of test to an integration test
  • Use comments to state WHY a test is there. Try to remember that any code will be READ several times more than WRITTEN or MODIFIED, by you and by other peoples.
  • You should keep the door open for all next iterations of both the code that tests something and the code that is being tested. This way, unittests will also serve as a documentation/overview, albeit strictly technical, about the design of the solution of a problem (which is what ALL code is for).
  • Unittests without comments are easy to cook, but then LOCK an entire piece of something to be served for the days to come. Nobody feels like changing the menu everybody is ordering from.

some general assumptions

Don't make the mistake of starting writing unittests that singularly test out a large piece (i.e. an entire "command") alltogether. The most useful unittests are on the internals, type checks, shared code and on little "utilities" functions.

When you code a new feature, put unittests where you know there are corner-cases that are hard to reproduce. This will prevent large refactors (again, dbatools will probably see lots of those) to break your carefully-crafted logic. It'll faster development on all sides: core devs and refactors will save tons of sweat touching a piece of core-logic in the future.

tl;dr for DBAs: always remember that writing unittests enforce a "WITH SCHEMABINDING" on things

tl;dr for everybody: TDD is a design process, not a testing one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment