I want to perform a functional test, but the purpose of this test is to check the result of another function - need_to_test, it should not be a module test, I want to make sure that when starting test_func, another function, namely need_to_test, returns the result I need.
class Need_test_func:
def need_to_test(self):
return 'Red'
def start_another_funk(self):
return self.need_to_test() + ' Green'
def test_func(self):
self.start_another_funk()
return
def test_check():
need_test_func = Need_test_func()
color = 'Red'
assert next(need_test_func().test_func()) == 'Red Green'
my task is to write a functional test i.e. start working with the Need_test_func class from the test_func function and make sure that it works properly but I can't do a unit test and just check if need_to_test returns the right color I need to start with test_func and make sure that during the operation of this function, need_to_test is launched and returns the value I need
How i can do this?
I want to make sure that when starting test_func, another function, namely need_to_test, returns the result I need.
It sounds like you need a mock function that returns a specific value for the test. Then you can patch that function. In this particular situation, you can just assign the function on the object to whatever you want. For example:
def test_check():
need_test_func = Need_test_func()
def mock_func(self):
return 'Blue'
need_test_func.need_to_test = mock_func
result = need_test_func.test_func()
Then you can assert the result of test_func(). In the current version of your question, test_func() isn't affected by need_to_test(), so I don't know what this assert would be. I assume this is a simplified version of a more complex project you are working on. I'll leave the assert as an exercise for the reader.
Related
Context
I am trying to cache executions in a data processing framework (kedro). For this, I want to develop a unique hash for a python function to determine if anything in the function body (or the functions and modules this function calls) has changed. I looked into __code__.co_code. While that nicely ignores comments, spacing etc, it also doesn't change when two functions are obviously different. E.g.
def a():
a = 1
return a
def b():
b = 2
return b
assert a.__code__.co_code != b.__code__.co_code
fails. So the byte code for these two functions is equal.
The ultimate goal: Determine if either a function's code or any of its data inputs have changed. If not and the result already exists, skip execution to save runtime.
Question: How can one get a fingerprint of a functions code in python?
Another idea brought forward by a colleague was this:
import dis
def compare_instructions(func1, func2):
"""compatre instructions of two functions"""
func1_instructions = list(dis.get_instructions(func1))
func2_instructions = list(dis.get_instructions(func2))
# compare every attribute of instructions except for starts_line
for line1, line2 in zip(func1_instructions, func2_instructions):
assert line1.opname == line2.opname
assert line1.opcode == line2.opcode
assert line1.arg == line2.arg
assert line1.argval == line2.argval
assert line1.argrepr == line2.argrepr
assert line1.offset == line2.offset
return True
This seems rather like a hack. Other tools like pytest-testmon try to solve this as well but they appear to be using a number of heuristics.
__code__.co_code returns the byte_code which doesn't reference the constants. Ignore the constants in your functions and they are the same.
__code__.co_consts contains information about the constants so would need to be accounted for in your comparison.
assert a.__code__.co_code != b.__code__.co_code \
or a.__code__.co_consts != b.__code__.co_consts
Looking at inspect highlights a few other considerations for 'sameness'. For example, to ensure the functions below are considered different, default arguments must be accounted for.
def a(a1, a2=1):
return a1 * a2
def b(b1, b2=2):
return b1 * b2
One way to finger print is to use the built-in hash function. Assume the same function defintions as in the OP's example:
def finger_print(func):
return hash(func.__code__.co_consts) + hash(func.__code__.co_code)
assert finger_print(a) != finger_print(b)
I have a common function that I want to use as a side effect for two different functions. Based on the function being mocked , they should return a different value.
The code is:
def sleep_three(*args, **kwargs):
logging.info('Sleeping 3 seconds')
time.sleep(3)
Used as a side effect for two different functions:
self.foo.side_effect = sleep_three
self.bar.side_effect = sleep_three
For foo, I want a specific return value, whereas for bar I want a different return value. I know how to obtain different return values based on different arguments being passed in to side_effect function. In this case though both foo and bar are being passed in the same argument, they just need to return different values.
My options are:
Write two different functions for side_effect : sleep_three_foo and sleep_three_bar and then match up return values accordingly. This goes against DRY principles though and I would like to avoid it.
My question is : Is there a way within sleep_three to obtain the original function being mocked?
Something like
if original_mocked_function == foo:
return a
elif original_mocked_function == bar:
return b
Any pointers appreciated!
Define a function that takes the desired return value of the side-effect function as an argument and returns the appropriate function.
def make_sleeper(rv):
def _(*args, **kwargs):
logging.info("Sleeping 3 seconds")
time.sleep(3)
return rv
return _
self.foo.side_effect = make_sleeper(5)
self.bar.side_effect = make_sleeper(9)
I'm using Pytest to test some SQL queries my team runs programmatically over time.
My SQL queries are lists of JSONs - one JSON corresponds to one row of data.
I've got a function that diffs the JSON key:value pairs so that we can point to exactly which values are different for a given row. Ideally, I'd output a list of these diffs instead of the standard output of an assert statement, which ends up looking clunky and not-very-useful for the end user.
You can use Python built-in capability to show custom exception message:
assert response.status_code == 200, "My custom message: actual status code {}".format(response.status_code)
Check it out: https://wiki.python.org/moin/UsingAssertionsEffectively
Pytest give us the hook pytest_assertrepr_compare to add a custom explanation about why an assertion failed.
You can create a class to wrap the JSON string and implement your comparator algorithm overloading the equal operator.
class JSONComparator:
def __init__(self, lst):
self.value = value
def __eq__(self, other):
# Here your algorithm to compare two JSON strings
...
# If they are different, save that information
# We will need it later
self.diff = "..."
return True
# Put the hook in conftest.py or import it in order to make pytest aware of the hook.
def pytest_assertrepr_compare(config, op, left, right):
if isinstance(left, JSONComparator) and op == "==":
# Return the diff inside an array.
return [left.diff]
# Create a reference as an alias if you want
compare = JSONComparator
Usage
def test_somethig():
original = '{"cartoon": "bugs"}'
expected = '{"cartoon": "bugs"}'
assert compare(original) == expected
I understand that functions are useful for code which will be used multiple times so I tried creating a function to save myself time and make my code look neater. The function I had looks like this:
def drawCard():
drawnCard = random.choice(cardDeck)
adPos = cardDeck.index(drawnCard)
drawnCardValue = cardValues[adPos]
However, I am not sure how to return these variables as they are local(?). Therefore, I can not use these variables outside the function. I am just wondering if someone could help edit this function in a way where I could use the drawnCard and drawnCardValue variables outside the function?
Use return:
def drawCard():
drawnCard = random.choice(cardDeck)
adPos = cardDeck.index(drawnCard)
drawnCardValue = cardValues[adPos]
return drawnCard, drawnCardValue
drawnCard, drawnCardValue = drawnCard()
Note, you could also write drawCard this way:
def drawCard():
adPos = random.randrange(len(cardDeck))
drawnCard = cardDeck[adPos]
drawnCardValue = cardValues[adPos]
return drawnCard, drawnCardValue
These two functions behave differently if cardDeck contains duplicates, however. cardDeck.index would always return the first index, so drawnCardValue would always correspond to the first item which is a duplicate. It would never return the second value (which in theory could be different.)
If you use adPos = random.randrange(len(cardDeck)) then every item in cardValue has an equal chance of being selected -- assuming len(cardValue) == len(cardDeck).
I have a situation where I have six possible situations which can relate to four different results. Instead of using an extended if/else statement, I was wondering if it would be more pythonic to use a dictionary to call the functions that I would call inside the if/else as a replacement for a "switch" statement, like one might use in C# or php.
My switch statement depends on two values which I'm using to build a tuple, which I'll in turn use as the key to the dictionary that will function as my "switch". I will be getting the values for the tuple from two other functions (database calls), which is why I have the example one() and zero() functions.
This is the code pattern I'm thinking of using which I stumbled on with playing around in the python shell:
def one():
#Simulated database value
return 1
def zero():
return 0
def run():
#Shows the correct function ran
print "RUN"
return 1
def walk():
print "WALK"
return 1
def main():
switch_dictionary = {}
#These are the values that I will want to use to decide
#which functions to use
switch_dictionary[(0,0)] = run
switch_dictionary[(1,1)] = walk
#These are the tuples that I will build from the database
zero_tuple = (zero(), zero())
one_tuple = (one(), one())
#These actually run the functions. In practice I will simply
#have the one tuple which is dependent on the database information
#to run the function that I defined before
switch_dictionary[zero_tuple]()
switch_dictionary[one_tuple]()
I don't have the actual code written or I would post it here, as I would like to know if this method is considered a python best practice. I'm still a python learner in university, and if this is a method that's a bad habit, then I would like to kick it now before I get out into the real world.
Note, the result of executing the code above is as expected, simply "RUN" and "WALK".
edit
For those of you who are interested, this is how the relevant code turned out. It's being used on a google app engine application. You should find the code is considerably tidier than my rough example pattern. It works much better than my prior convoluted if/else tree.
def GetAssignedAgent(self):
tPaypal = PaypalOrder() #Parent class for this function
tAgents = []
Switch = {}
#These are the different methods for the actions to take
Switch[(0,0)] = tPaypal.AssignNoAgent
Switch[(0,1)] = tPaypal.UseBackupAgents
Switch[(0,2)] = tPaypal.UseBackupAgents
Switch[(1,0)] = tPaypal.UseFullAgents
Switch[(1,1)] = tPaypal.UseFullAndBackupAgents
Switch[(1,2)] = tPaypal.UseFullAndBackupAgents
Switch[(2,0)] = tPaypal.UseFullAgents
Switch[(2,1)] = tPaypal.UseFullAgents
Switch[(2,2)] = tPaypal.UseFullAgents
#I'm only interested in the number up to 2, which is why
#I can consider the Switch dictionary to be all options available.
#The "state" is the current status of the customer agent system
tCurrentState = (tPaypal.GetNumberofAvailableAgents(),
tPaypal.GetNumberofBackupAgents())
tAgents = Switch[tCurrentState]()
Consider this idiom instead:
>>> def run():
... print 'run'
...
>>> def walk():
... print 'walk'
...
>>> def talk():
... print 'talk'
>>> switch={'run':run,'walk':walk,'talk':talk}
>>> switch['run']()
run
I think it is a little more readable than the direction you are heading.
edit
And this works as well:
>>> switch={0:run,1:walk}
>>> switch[0]()
run
>>> switch[max(0,1)]()
walk
You can even use this idiom for a switch / default type structure:
>>> default_value=1
>>> try:
... switch[49]()
... except KeyError:
... switch[default_value]()
Or (the less readable, more terse):
>>> switch[switch.get(49,default_value)]()
walk
edit 2
Same idiom, extended to your comment:
>>> def get_t1():
... return 0
...
>>> def get_t2():
... return 1
...
>>> switch={(get_t1(),get_t2()):run}
>>> switch
{(0, 1): <function run at 0x100492d70>}
Readability matters
It is a reasonably common python practice to dispatch to functions based on a dictionary or sequence lookup.
Given your use of indices for lookup, an list of lists would also work:
switch_list = [[run, None], [None, walk]]
...
switch_list[zero_tuple]()
What is considered most Pythonic is that which maximizes clarity while meeting other operational requirements. In your example, the lookup tuple doesn't appear to have intrinsic meaning, so the operational intent is being lost of a magic constant. Try to make sure the business logic doesn't get lost in your dispatch mechanism. Using meaningful names for the constants would likely help.