user131983
user131983

Reputation: 3937

Unit Test in Python involving two lists

I am carrying out a Unit Test in Python, where I am trying to check if the elements within two lists are within a certain range of each other. The two lists I am considering are yields and list_of_yields and was considering doing self.assertEqual(round(yields-list_of_yields, 7), 0). However - is an unsupported type for lists, so my two issues are how to check if elements are within a certain range and how to carry out an assert on multiple elements as I've been told that having multiple asserts is bad practice. I saw this answer, but my question is slightly different.

Thank You

Upvotes: 4

Views: 646

Answers (2)

jwde
jwde

Reputation: 650

Here's a functional approach

assert(0 == (reduce(lambda a,b:a+b, map(lambda c:round(c[0]-c[1], 7), zip(yields, list_of_yeilds))))

Breaking that down: take the zip of yields and list_of_yields to get a list of pairs:

[(yields[0], list_of_yields[0]), (yields[1], list_of_yields[1]), ...]

Then map the function lambda c:round(c[0]-c[1], 7) over each pair to get the pairwise difference of yields and list_of_yields, rounded to 7 decimals.

[round(yields[0] - list_of_yields[0], 7), round(yields[1] - list_of_yields[1], 7), ...]

The last step is to check if any of the elements in this list are non-zero (in which case the lists aren't close enough). Just reduce with addition and check against 0 and you're done.

0 == round(yields[0] - list_of_yields[0], 7) + round(yields[1] - list_of_yields[1], 7) + ...

Upvotes: 0

shuttle87
shuttle87

Reputation: 15934

If the elements are to be compared in the exact order in which they appear you can create a a utility function that takes parameters and checks that they satisfy some condition:

def close_round(item1, item2, rounding_param):
    """Determines closeness for our test purposes"""
    return round(item1, rounding_param) == round(item2, rounding_param)

Then you can use this in a test case like so:

assert len(yields1) == len(list_of_yields)
index = 0
for result, expected in zip(yields, list_of_yields):
    self.assertTrue(close_round(result, expected, 7),
                    msg="Test failed: got {0} expected {1} at index {2}".format(result, expected, index))
    index+=1

You might find this type of pattern useful in which case you could create a function that does this:

def test_lists_close(self, lst1, lst2, comp_function):
    """Tests if lst1 and lst2 are equal by applying comp_function
    to every element of both lists"""
    assert len(lst1) == len(lst2)
    index = 0
    for result, expected in zip(yields, list_of_yields):
        self.assertTrue(comp_function(result, expected),
                        msg="Test failed: got {0} expected {1} at index {2}".format(result, expected, index))
        index+=1

If you used it a lot you would probably want to test this function too.

Upvotes: 1

Related Questions