Lien
Lien

Reputation: 126

How can you run a unit test on all files in a directory?

I am a TA for an intro CS class learning Python and I was wondering if there is a way to run one unit test file on multiple .py files in a folder.

For example, if I make Homework1UnitTest.py and I want it to run on all .py files in the folder C:/Users/Lien/Desktop/StudentSubmissionsHW1, how would I do that?

The StudentSubmissionsHW1 is populated with .py files like: jsmithhw1.py bjoneshw1.py sscotthw1.py and so on.

Also, as I was learning about unit tests, I read about passing verbosity arguments to the unittest call. Is there something similar to this where I can see ALL of the tests that failed?

For example, if I have something like:

  def test_is_int(self):
      self.assertEqual(is_int("-51"), True)
      self.assertEqual(is_int("-5.1"), False)
      self.assertEqual(is_int("5.1"), False)
      self.assertEqual(is_int("51"), True)
      self.assertEqual(is_int("0"), True)
      self.assertEqual(is_int("-5-4"), False)
      self.assertEqual(is_int("5..1"), False)
      self.assertEqual(is_int("5-"), False)
      self.assertEqual(is_int("5f"), False)
      self.assertEqual(is_int("-"), False)

can I set up my results to show ALL the assertEqual() functions that failed instead of just the first one?

Thanks!

Upvotes: 3

Views: 1348

Answers (1)

lemonhead
lemonhead

Reputation: 5518

Yes, the discover feature was designed with just this use case:

cd project_directory
python -m unittest discover

By default, it will only run on files that match the pattern test*.py, but if you want it to run on every .py file, you can do instead:

python -m unittest discover -p "*.py"

As to your second question, the first assert that fails will stop the other tests within the function from even being run; if you need more granularity, you are better off creating a separate test function for each assert as described here

Update: Re-reading your question, it sounds like you have a single unittest file, but want to run those unittests on multiple files. How to do this would depend what running it on a file entails for your particular use case. However, if you mean those files have some input that you want as additional "argument" to each of your test cases, one way would be to nest each of your tests in a forloop that loops through all the files in the directory. Another thing I've done before is to setup a decorator that will automatically setup this forloop for you on all decorated methods, e.g. something like:

def all_files(func):
    def wrapped(self, **kwargs):
        root = 'C:\Users\Lien\Desktop\StudentSubmissionsHW1'
        kwargs.pop('filepath',None)
        for filepath in glob.glob(os.path.join(root, '*.py')):
            func(self, filepath=filepath, **kwargs)   
    return wrapped

And then you could use it like this:

class TestStringMethods(unittest.TestCase):

    @all_files
    def test_is_int(self, filepath=None):
        # run your test(s) using file filelpath...
        with open(filepath) as fobj:
            self.assertEqual(fobj.read().strip(), 'foobar')

Upvotes: 1

Related Questions