# Assertions about data in infrastructure code as unit tests

I have some Python tests I have written, but these are for making assertions about data in infrastructure code (AWS CloudFormation templates). I am using the Unittest framework.

I have code like this:

class TestData(unittest.TestCase):

def testConfigStackYaml(self):

for stack in glob('*/config'):

stack_name = os.path.dirname(stack)
expected_file = "%s/config/%s.yaml" % (stack_name, stack_name)

if not os.path.isfile(expected_file):

def testStacksetMk(self):

for stack in glob('*/config'):

stack_name = os.path.dirname(stack)
expected_file = "%s/stackset.mk" % stack_name

if not os.path.isfile(expected_file):



These are just two of my test cases. I have plenty more.

As can be seen, there is a problem with this code. The for loop for each test case is repeated for each test case, resulting in code duplication and inefficient code.

I have done it this way, however, because I want each test case to yield a helpful, specific message about what is wrong.

Can anyone see a cleaner way to implement this, so that I have the best of both worlds: duplication refactored out, but I still get to have a separate test case for each logical test?

• Title of the question doesn't convey your business requirement. Can you change it to something that describes what you are trying to do. How about Assertions about data in infrastructure code as unit tests Dec 22 '19 at 13:26
• @bhathiya-perera ok, done. Dec 22 '19 at 13:27

This is an interesting code.

Criticism:

def testConfigStackYaml(self):

• Can we rename these functions to snake_case such as test_config_stack_yaml maybe.
assert not bad_list, "Expected config/<stack_name>.yaml files to exist: %s" % bad_list

expected_file = "%s/config/%s.yaml" % (stack_name, stack_name)

• I personally like using the new formatter. % is more unreadable compared to "{stack_name}/config/{stack_name}".format(stack_name=stack_name)
• We can also use os.path.join to join sections of a path. This makes our intention clear.
if __name__ == "__main__":
unittest.main()

• If you add this to the end of the file you can run these test files individually as a simple script.

Creating a custom assert

• I recommend creating a memeber function named assert_config_exists.
• Parameters: path_format, message_format
def assert_config_exists(self, path_format: str, message_format: str):
for stack in glob('*/config'):

stack_name = os.path.dirname(stack)
expected_file = path_format.format(stack_name=stack_name)

if not os.path.isfile(expected_file):
$$$$
`