Can we write re-usable assertion blocks?

Example use case…

We tag all our resources with a standard set of tags and repeating this handful of assertions through our tests is very repetitive and noisy.

As far as I can tell, this is not currently possible, so this might actually be a feature request.

Hi @WillGibson, you’re right that this is not currently possible. I think it’s a good candidate for a feature request. If you filed this within the Terraform repo it would come to the attention of our product team: Issues · hashicorp/terraform · GitHub

Thanks!

1 Like

Hi @WillGibson,

Although it’s not exactly what you asked about, I would suggest considering some of the other ways that Terraform allows declaring assertions/conditions directly inside your module, instead of writing them in the test scenario files:

  • check blocks specify assertions that should be checked after each apply
  • Preconditions and postconditions are checks that can directly block further work during either the plan or apply phase (depending on what the condition is testing and whether it can be decided during plan)

The test framework considers these features to be essentially inline test assertions, and so they are a good way to describe things that ought to hold true regardless of how the module is used – and thus can be checked generally for all instances of your module – whereas the assertions in run blocks are for the situation where an outcome is unique to a specific test scenario.

This strategy of writing general assertions that Terraform can check both during testing and at runtime is a good way to get the most out of your efforts to describe the intended behavior of your module, because you can get benefits from it both during your own testing of the module and at runtime when the module is being used for “real work”, without any duplication.

Of course, it does mean that you need to describe the intended behavior in more general terms. For example, instead of writing an assertion like “given this specific example input, the module should produce this specific output” you might describe it as a relationship: “this particular output should always be equal to this particular input” (likely with some kind of transformation between the two also encoded in the condition).

This is a lightweight form of Design by Contract intended to make the most of Terraform’s declarative nature, where it’s more straightforward than it might be in some other languages to describe general rules about a module’s intended behavior, instead of relying only on tables of fixed examples of input and output.

1 Like