python something like assertFunctionNotCalled? - python

Edit: This question refers to python 3.5
In python unit testing, is there a way to assert that a given block of code is not called?
I have a function I am testing that can follow either of two branches: a faster, more reliable branch if the user has logged in before, or a slower less reliable branch if this is their first visit. Basically, the first time a user logs in, the program has to request information about them from separate server, which can be slow (and, occasionally, down). Once it has the information, however, it caches it locally and should just use the local cache for the data on subsequent logins.
The end result of the function is the same either way, so there is no way for me to know which code branch it took to get the information by simply looking at the output of the function. So ideally I'd like to be able to do effectively an assertFunctionNotCalled to test that it is pulling from the local cache on the second (and subsequent) login attempt. How should I best test this?

Use the bool called like so:
from mock import patch
with patch('something') as mock_something:
self.assertFalse(mock_something.called)

Related

Please help understand the use case of unit testing

I have 2 scripts.
It runs a load test using locust, collects the output in dict format, then pass it to the 2nd script.
2nd script will accept a dict as input from script-1, parses it, creates a json payload and sends the data to an api endpoint where it stores in some db.
The application starts running from the 1st script and all the functionalities are working well. I have never worked on a unit testing. My question here is:
What can be tested here using unit testing in order to keep proper standard of building an application.
script-1. (suppose locust is running in already)
def on_slave_report(data):
send_to_db(data)
events.slave_report += on_slave_report
script-2.
def send_to_db(data):
send_it(take_only_needed(data))
def take_only_needed(data):
needed=data[stats]
payload = json.dumps({'stats' : needed, 'bla': bla})
return payload
def send_it(payload):
requests.request("POST", url, data=payload, headers=headers)
For the two functions send_to_db and send_it, unit-testing does not make much sense: Both functions consist only of interactions with other components/functions. Since unit-testing aims at finding those bugs which can be found in the isolated units, there are no bugs which unit-testing could find. Bugs in such interaction dominated code lie more in the following area: Are you calling the right functions in the right order with the right values for the parameters, are the parameters in the right order, are the results/return values delivered in the expected way and format? And, answers for all these questions can not be found in the isolated code, but only in code where the respective components truly interact - and this is integration-testing rather than unit-testing.
The only function in your script-2 that makes sense to unit-test is take_only_needed: This function performs actual computations. It also has the nice property that it only has dependencies which (probably) do not cause testing problems and thus probably don't need mocking.
Conclusion: Perform unit-testing for take_only_needed, for the others skip unit-testing and test them during interaction testing.

Ndb strong consistency and frequent writes

I'm trying to achieve strong consistency with ndb using python.
And looks like I'm missing something as my reads behave like they're not strongly consistent.
The query is:
links = Link.query(ancestor=lead_key).filter(Link.last_status ==
None).fetch(keys_only=True)
if links:
do_action()
The key structure is:
Lead root (generic key) -> Lead -> Website (one per lead) -> Link
I have many tasks that are executed concurrently using TaskQueue and this query is performed at the end of every task. Sometimes I'm getting "too much contention" exception when updating the last_status field but I deal with it using retries. Can it break strong consistency?
The expected behavior is having do_action() called when there are no links left with last_status equal to None. The actual behavior is inconsistent: sometimes do_action() is called twice and sometimes not called at all.
Using an ancestor key to get strong consistency has a limitation: you're limited to one update per second per entity group. One way to work around this is to shard the entity groups. Sharding Counters describes the technique. It's an old article, but as far as I know, the advise is still sound.
Adding to Dave's answer which is the 1st thing to check.
One thing which isn't well documented and can be a bit surprising is that the contention can be caused by read operations as well, not only by the write ones.
Whenever a transaction starts the entity groups being accessed (by read or write ops, doesn't matter) are marked as such. The too much contention error indicates that too many parallel transactions simultaneously try to access the same entity group. It can happen even if none of the transactions actually attempts to write!
Note: this contention is NOT emulated by the development server, it can only be seen when deployed on GAE, with the real datastore!
What can add to the confusion is the automatic re-tries of the transactions, which can happen after both actual write conflicts or just plain access contention. These retries may appear to the end-user as suspicious repeated execution of some code paths - which I suspect could explain your reports of do_action() being called twice.
Usually when you run into such problems you have to re-visit your data structures and/or the way you're accessing them (your transactions). In addition to solutions maintaining the strong consistency (which can be quite expensive) you may want to re-check if consistency is actually a must. In some cases it's added as a blanket requirement just because appears to simplify things. From my experience it doesn't :)
There is nothing in your sample that ensures that your code is only called once.
For the moment, I am going to assume that your "do_action" function does something to the Link entities, specifically that it sets the "last_status" property.
If you do not perform the query and the write to the Link Entity inside a transaction, then it is possible for two different requests (task queue tasks) to get results back from the query, then both write their new value to the Link entity (with the last write overwriting the previous value).
Remember that even if you do use a transaction, you don't know until the transaction is successfully completed that nobody else tried to perform a write. This is important if you are trying to do something external to datastore (for example, making a http request to an external system), as you may see http requests from transactions that would eventually fail with a concurrent modification exception.

How to unit test helper methods in Python scheduled job?

I've read quite a few answers on here about testing helper methods (not necessarily private) in my unit tests and I'm still not quite sure what the best approach should be for my current situation.
I currently have a block of logic that runs as a scheduled job. It does a number of mostly related things like update local repositories, convert file types, commit these to other repos, clean up old repos, etc. I need all of this code to run in a specific order, so rather than setting a bunch of scheduled jobs, I took a lot of these small methods and put them into one large method that would enforce the order in which the code is run:
def mainJob():
sync_repos()
convert_files()
commit_changes()
and so on. Now I'm not sure how to write my tests for this thing. It's frustrating to test the entire mainJob() function because it does so many things and is really more of a reliability feature anyway. I see a lot of people saying I should only test the public interface, but I worry that there will potentially be code that isn't directly verified.

Understand programmatically a python code without executing it

I am implementing a workflow management system, where the workflow developer overloads a little process function and inherits from a Workflow class. The class offers a method named add_component in order to add a component to the workflow (a component is the execution of a software or can be more complex).
My Workflow class in order to display status needs to know what components have been added to the workflow. To do so I tried 2 things:
execute the process function 2 times, the first time allow to gather all components required, the second one is for the real execution. The problem is, if the workflow developer do something else than adding components (add element in a databases, create a file) this will be done twice!
parse the python code of the function to extract only the add_component lines, this works but if some components are in a if / else statement and the component should not be executed, the component apears in the monitoring!
I'm wondering if there is other solution (I thought about making my workflow being an XML or something to parse easier but this is less flexible).
You cannot know what a program does without "executing" it (could be in some context where you mock things you don't want to be modified but it look like shooting at a moving target).
If you do a handmade parsing there will always be some issues you miss.
You should break the code in two functions :
a first one where the code can only add_component(s) without any side
effects, but with the possibility to run real code to check the
environment etc. to know which components to add.
a second one that
can have side effects and rely on the added components.
Using an XML (or any static format) is similar except :
you are certain there are no side effects (don't need to rely on the programmer respecting the documentation)
much less flexibility but be sure you need it.

How to use doctest on a Client script?

I am playing with Google Calendar API, creating some useful function.
I another hand, I want to do it right puting some useful doctest and starting agile development.
How to write doctest since the result of each function is not really predictible (Depending of what is new on the server) :
>>> calendar = GoogleCalendar(user='blabla', password='blablabla')
>>> calendar.list()
login#trunat.fr's Calendar List
0. ...
...
If I don't want to leave the password in the source code, How do I do ?
How to write test for all the function of a class without writing each time the same thing to each function ?
>>> calendar = GoogleCalendar(user='blabla', password='blablabla')
>>> calendar.myFunction()
For each function of GoogleCalendar, I will have to create first the object ?
Thank you for your help
If you do decide to test an external service, you can use a test fixture:
Write a make_test_server() function, which will return a new server connection to simplify your tests.
Make it a test fixture (dummy of the server) make_dummy_test_server() with predictable output.
Test it, and make sure that all cases (connection errors, empty set returned) have been thought of.
It depends on how exhaustive your tests should be. If you are getting a lot of bugs from that area of code, then you might need more tests. If your code works, it might not be worth sweating.
Are you also doing code reviews? Systems testing? Unit testing is great, but make sure that you don't get too myopic.

Categories