Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

For loop in unittest

Is there a way to tell the python unittest execute all assertion in a method and show all cases it fails, instead of stop at the first failed.

class MyTestCase(TestCase):
    def test_a(self):
        with open('testcase.txt') as ifile: 
            for iline in ifile:
                self.assertEqual(iline, 'it is a test!')
like image 856
lucemia Avatar asked Oct 20 '14 04:10

lucemia


People also ask

Can you use a for loop in a unit test?

Yes you can have loops in unit test, but with caution. As mentioned by Alex York, loops are acceptable if you test one thing; i.e. one expectation. If you use loops, then I recommend that you must do two things: As mentioned above, test for a non-empty iteration set.

How do you test a loop unit?

unit-testing Unit testing of Loops (Java) Single loop test These are loops in which their loop body contains no other loops (the innermost loop in case of nested). In order to have loop coverage, testers should exercise the tests given below. Consider the below code example which applies all the conditions specified.


2 Answers

Python 3.4 introduced the subTest context manager. Your code will look like

class MyTestCase(TestCase):
    def test_a(self):
        with open('testcase.txt') as ifile: 
            for iline in ifile:
                with self.subTest(line=iline):
                    self.assertEqual(iline, 'it is a test!')

The ugly way to achieve this without subTest is to make self.assert* calls within a try block, print the errors caught, and raise the AssertionError explicitly after the loop if at least one test failed.

like image 188
vaultah Avatar answered Oct 01 '22 23:10

vaultah


Alternatively, you can make a data-driven-test with the help of ddt package:

DDT (Data-Driven Tests) allows you to multiply one test case by running it with different test data, and make it appear as multiple test cases.

import unittest
from ddt import ddt, data

@ddt
class FooTestCase(unittest.TestCase):
    @data('it is a test!', 'it is a test!', 'something else')
    def test_lines(self, value):
        self.assertEqual(value, 'it is a test!')

ddt can also have the data coming from a file, but it has to be a JSON file.

like image 40
alecxe Avatar answered Oct 01 '22 22:10

alecxe