Tests need to exercise the boundaries of our code up to and beyond the range limits. In this recipe, we will dig into defining and testing edges with doctest.
With the following steps, we will see how to write code that tests the edges of our software.
recipe22.py
and use it to store all of our code for this recipe.def convert_to_basen(value, base): if base < 2 or base > 36: raise Exception("Only support bases 2-36") import math def _convert(remaining_value, base, exp): def stringify(value): if value > 9: return chr(value + ord('a')-10) else: return str(value) if remaining_value >= 0 and exp >= 0: factor = int(math.pow(base, exp)) if factor <= remaining_value: multiple = remaining_value / factor return stringify(multiple) + _convert(remaining_value-multiple*factor, base, exp-1) else: return "0" + _convert(remaining_value, base, exp-1) else: return "" return "%s/%s" % (_convert(value, base, int(math.log(value, base))), base)
def convert_to_basen(value, base): """Convert a base10 number to basen. These show the edges for base 2. >>> convert_to_basen(1, 2) '1/2' >>> convert_to_basen(2, 2) '10/2' >>> convert_to_basen(0, 2) Traceback (most recent call last): ... ValueError: math domain error These show the edges for base 36. >>> convert_to_basen(1, 36) '1/36' >>> convert_to_basen(35, 36) 'z/36' >>> convert_to_basen(36, 36) '10/36' >>> convert_to_basen(0, 36) Traceback (most recent call last): ... ValueError: math domain error These show the edges for base 37. >>> convert_to_basen(1, 37) Traceback (most recent call last): ... Exception: Only support bases 2-36 >>> convert_to_basen(36, 37) Traceback (most recent call last): ... Exception: Only support bases 2-36 >>> convert_to_basen(37, 37) Traceback (most recent call last): ... Exception: Only support bases 2-36 >>> convert_to_basen(0, 37) Traceback (most recent call last): ... Exception: Only support bases 2-36 """ if base < 2 or base > 36:
if __name__ == "__main__": import doctest doctest.testmod()
This version has a limit of handling base 2 through base 36.
We include several tests, including one for base 2 and base 36. We also test the maximum value before rolling over, and the next value, to show the rollover. For base 2, this is 1 and 2. For base 36, this is 35 and 36.
We have also included tests for 0 to show that our function doesn't handle this for any base. We also test base 37, which is invalid as well.
It's important that our software works for valid inputs. It's just as important that our software works as expected for invalid inputs. We have documentation that can be viewed by our users when using our software that documents these edges. And thanks to Python's doctest
module, we can test it and make sure that our software performs correctly.
Testing the edges section mentioned in Chapter 1
3.147.58.194