7VoltCrayon 7VoltCrayon - 2 months ago 19
Python Question

Unit testing very simple functions

Say I have a simple function of the form:

def square(x):
return x**2


If I write a unit test for testing correctness, is it considered bad practice to do something like:

def test_square(self):
for _ in range(50):
rand_num = random.uniform(-10,10)
self.assertAlmostEqual(square(rand_num), rand_num**2, msg= "Failed for input: {}".format(rand_num))


Where essentially instead of writing manual cases, I'm in a sense rewriting the function inside the unit test? Why or why won't this be considered good practice.

I'm assuming there are other tests which check for invalid inputs and stuff; I'm asking this for the very specific case of testing correctness of the function.

Answer

Random inputs is almost never what you want. It wouldn't be very helpful if your tests succeeded sometimes but failed on others because of the different random input your tests generated

You only need to test the bare minimum to ensure correct results. If you have a bug or regression, you add additional tests as necessary.

This would be sufficient

def test():
    assert square(3) == 9

Notice that the test doesn't depend on any specific implementation details (i.e. it only includes the computed 9 rather than 3**2). In general, you want your tests to have the least amount of dependencies and complexity as possible. Generally, you're trying to test one thing at a time, and fewer dependencies means you're actually testing the thing you want rather than the interaction with some dependency.

If you noticed a bug with negative numbers, then you could add an additional test

def test():
    assert square(3) == 9
    assert square(-3) == 9

Often, people will either add unit tests after they've already developed the function, or they'll try to create the entire unit test function at once in the very beginning.

The best method is usually to test one feature at a time, and add one feature at a time, and develop the tests and function together.

Comments