I am working on a +10k LOC program, and I need to ensure its output is always the same for given input. The program consists of dozens of modules and classes, inherited by a MainClass
. (The examples below are very simplified compared to the actual code.)
Initially I created tests ensuring multiple instances of MainClass
have the same output for given input.
def check_consistent_instances(input_dict):
"""Checks if all results for given input are the same."""
first_instance_result = MainClass(input_dict).result()
for i in range(10000):
result = MainClass(input_dict).result()
if first_instance_result != result:
raise Exception('Different result detected!!')
This however can't detect different results in multiple runs caused by sets/dicts having a different order due to a new hash seed in each run (this could in some rare cases affect the output).
For example:
class MyClass(object):
AVAILABLE_MONEY = 6
ITEMS_CATALOG = {'a': 5, 'b': 5, 'c': 5, 'd': 5, 'e': 3}
def buy_most_expensive(self):
"""Deducts the most expensive items from the available money."""
for i in self.ITEMS_CATALOG:
# Assume I made a mistake here! I should have used sorted(self.ITEMS_CATALOG, key=lambda x: self.ITEMS_CATALOG[x])
# but accidentally i used only self.ITEMS_CATALOG.
cost = self.ITEMS_CATALOG[i]
if cost <= self.AVAILABLE_MONEY:
self.AVAILABLE_MONEY -= cost
Code like the above would pass my check_consistent_instances()
test, since on each run the PYTHONHASHSEED
would have a specific value and all results would be the same during a specific run. The results would differ only between different runs.
Question:
Which are the best practices when it comes to checking whether a program's results are consistent?
OrderedDict
, which retains insertion order. But you may find you need totally deterministic output less often than you think, and you can still test the results appropriately when using vanilladict
orset
objects.