Terraform test conditional command attribute 'plan' or 'apply' for unit tests and integration tests

Hi,
I am using Terraform 1.9+ and writing hcl tests for unit testing and integration testing. Want to write ‘run’ blocks with asserts to support tests using command = plan for unit tests and command = apply for integration tests.
Example:

variables {
  datalake_bucket_name = "test-bkt-202408"
  plan = true
}
run "test_bucket_names" {
  command = var.plan ? plan : apply
  assert {
    condition     = aws_s3_bucket.datalake.bucket == var.datalake_bucket_name
    error_message = "Incorrect bucket name. Expected: ${var.datalake_bucket_name}, Got: ${aws_s3_bucket.datalake.bucket}"
  }
}

I want to be able to run this test as below to create the resource and run integration test. Also want to be able to use it for unit tests with plan=true

$ terraform test -var plan=false --filter=tests\test_s3_resource.tftest.hcl

But, I am getting the following error -

The "command" argument requires one of the following keywords without quotes: apply or plan.

Is there a way I can accomplish this, or the command attribute cannot take any variables or conditionals?

Hi @think_tank_77, unfortunately what you’re attempting here isn’t currently possibly.

I’d recommend filing a feature request for this: Terraform Issues. We can use that to gauge interest and assign priority to potentially implementing this in the future.

Thanks!

You could also take a look at this issue: Terraform Test - Add plan or apply as a command line variable · Issue #34359 · hashicorp/terraform · GitHub

That’s another potential approach to solving this kind of problem - but it is also awaiting prioritisation.

Thank you @liamcervante. This helps. On similar lines, is there a way to skip tests or use an attribute to ignore an assert statement within a run block?

There isn’t a way to skip individual run blocks currently.

You could ignore an assertion using the ternary operator. Something like condition = var.skip ? true : <actual assertion> would mean the assertion always passes if var.skip is assigned to true. There isn’t a built-in approach for this.

Thank you. That’s what I am currently doing. Thought there would be a cleaner approach/way of doing it.

unrelated to the issue but similar question – instead of specifying

command = plan

for every run block, is there a way to infer it globally for the entire test file or through command line or specifying at the start of the file or the first run block?

Sorry for the delayed response! That’s also not currently a way to specify this globally yet. We do have a tracking request for something similar as an enhancement here: Terraform Test - Add plan or apply as a command line variable · Issue #34359 · hashicorp/terraform · GitHub.

side note: you’ll probably want to add

  plan_options {
    refresh = false
  }

to that too.

Using a mock provider may be another option to consider for your unit tests; I’ve found there are some pros and cons.