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):

        bad_list = []
        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):
                bad_list.append(expected_file)

        assert not bad_list, "Expected config/&lt;stack_name&gt;.yaml files to exist: %s" % bad_list

    def testStacksetMk(self):

        bad_list = []
        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):
                bad_list.append(expected_file)

        assert not bad_list, "Expected stackset.mk file to exist: %s" % bad_list


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?
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/&lt;stack_name&gt;.yaml files to exist: %s" % bad_list




You can access unit test asserts from `TestCas
How:


self.assertTrue(expr, msg=None)
self.assertFalse(expr, msg=None)

More information at: https://docs.python.org/3.6/library/unittest.html#unittest.TestCase.assertTrue



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):
    bad_list = []
    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):
            bad_list.append(expected_file)

    self.assertFalse(bad_list, message_format.format(bad_list=bad_list))
```