[ python unit testing to test over the loop and not to break ]
def test2_1_wiered_chars(self):
for char in l_wchar:
self.assertFalse(is_number(char), msg='failed for char {}'.format(char) )
I was passing a list to the function is_number
to check if it is not a number. The list has the combination of letters and numbers. The test fails when it hits the first number as expected. But it breaks out of the loop and does not show how does it behave with the rest of the indexes of the list. what is correct way to test all the values of the list in one test case?
Answer 1
You should not have all test data within a single test case. The test data should be external to the test case. This should work for your purpose:
class CharTests(unittest.TestCase):
pass
def test_gen(char):
def test_method(self):
return self.assertTrue(char.isdigit())
return test_method
if __name__ == '__main__':
for index, char in enumerate(l_wchar):
test_name = 'test_{0}'.format(index)
test = test_gen(char)
setattr(CharTests, test_name, test)
suite = unittest.TestLoader().loadTestsFromTestCase(CharTests)
result = unittest.TextTestRunner(verbosity=2).run(suite)
For each character in the string, a test case method is appended to the class CharTests
, after which the suite is executed. This will give you in great detail which test cases failed
Answer 2
def test2_1_wiered_chars(self)
numbers = [char for char in l_wchar if is_number(char)]
self.assertFalse(numbers, msg='failed for char(s) {}'.format(numbers))
Create a new list of the objects that fail and assert that your new list is empty once it's done. Empty lists are falsey so this will fail if there are any integers in the list.
Note: This could potentially be extremely memory inefficient if l_wchar
is very large and contains a lot of numbers. Making two copies of it may not be practical or possible.
Answer 3
The aim of assert
is the opposite of what you are trying to do. When you are testing something - in your case, if there is a number among a list of chars - and it fails once somewhere, it makes no sense for the test to keep running - it has already failed.
If you want to know all cases where the char is a number, you should change your code to something like
results = []
for char in l_wchar:
if is_number(char):
msg='failed for char {}'.format(char)
print msg
results.append(True)
Then you'll have a list where all indexes with True
as value correspond to numbers in the other list.
To continue asserting
i.e. stating whether the test fails or not, just do it at the end
assertFalse(any(results))
However, it is important to notice that this is not an efficient and correct test. You do not have to test everything to know if a test fails or not. The test should fail (and stop) the first time something goes unexpected.