So I have some code which uses gphoto2 to capture some images and stuff, I figured the best way to test this would be to wrap the gphoto2 code in something like an if TESTING: then return fake data, else do the gphoto2 stuff.
Does anyone know how I would achieve this, I've tried googling some things but I've not had any luck with specifically detecting if unit tests are being run or not.
I'd assume it would be something like if unittest: but maybe there is a better way to do this altogether?
EDIT:
So based on the comments and answers so far, I tried out the unittest.mock package, it didn't work as I'd hoped, let me explain.
If I have method A which calls the capture image method (method B), then saves the image and a few other bits. I've managed to mock method B so that it returns either the image or None, which works fine when I call method B specifically, but when I try to call method A, it doesn't use the mock of method B, it uses the actual method B.
How do I make method A use the mock method B?
The mock package exists for this very reason.
It's a standalone, pip-installable package for Python 2; it has been incorporated into the standard library for Python versions >= 3.3 (as unittest.mock).
Just use a mocking library from within your test code. This way you'd mask the external APIs (hardware calls in your case) and return predictable values.
I would recommend flexmock https://pypi.python.org/pypi/flexmock it's super easy.
In the beginning of your test code, you'll write something like:
flexmock(SomeObject).should_receive('some_method').and_return('some', 'values')
Related
I am new to Python Test Framework. Is there any concept in Python Testing, similar to AssemblyInitialize
concept in c#. I need to run two methods, before every test method runs. I'm aware of setup and teardown methods. I'm looking specifically something similar to AssemblyInitialize in c#.
Thank you.
I googled over the internet to look for anything similar to AssemblyInitialize in C#. Nothing popped up.
Because a python module is loaded only once, you can simply do like this, although it's an undocumented method.
# test_xxx.py
def init_test()
# Do whatever you want.
pass
init_test()
A documented method is to use fixture() like this.
import pytest
#pytest.fixture(scope='session', autouse=True)
def init_test():
# Do whatever you want.
pass
For a specific program I'm working in, we need to evaluate some code, then run a unittest, and then depending on whether or not the test failed, do A or B.
But the usual self.assertEqual(...) seems to display the results (fail, errors, success) instead of saving them somewhere, so I can't access that result.
I have been checking the modules of unittest for days but I can't figure out where does the magic happen or if there is somewhere a variable I can call to know the result of the test without having to read the screen (making the program read and try to find the words "error" or "failed" doesn't sound like a good solution).
After some days of researching, I sent an email to help#python.org and got the perfect solution for my issue.
The answer I got was:
I suspect that the reason that you're having trouble getting unittest
to do that is that that's not the sort of thing that unittest was
written to do. A hint that that's the case seems to me to be that over
at the documentation:
https://docs.python.org/3/library/unittest.html
there's a section on the command-line interface but nothing much about
using the module as an imported module.
A bit of Googling yields this recipe:
http://code.activestate.com/recipes/578866-python-unittest-obtain-the-results-of-all-the-test/
Which looks as though it might be useful to you but I can't vouch for
it and it seems to involve replacing one of the library's files.
(Replacing one of the library's files is perfectly reasonable in my
opinion. The point of Python's being open-source is that you can hack
it for yourself.)
But if I were doing what you're describing, I'd probably write my own
testing code. You could steal what you found useful from unittest
(kind of the inverse of changing the library in place). Or you might
find that your needs are sufficiently simple that a simple file of
testing code was sufficient.
If none of that points to a solution, let us know what you get and
I'll try to think some more.
Regards, Matt
After changing my result.py module from unittest, I'm able to access the value of the test (True, False, or Error).
Thank you very much, Matt.
P.S. I edited my question so it was more clear and didn't have unnecessary code.
You can use pdb to debug this issue, in the test simply add these two lines to halt execution and begin debugging.
import pdb
pdb.settrace()
Now for good testing practice you want deterministic test results, a test that fails only sometimes is not a good test. I recommend mocking the random function and using data sets that capture the errors you find.
How can python program know if it is being tested? For example:
def foo():
if foo_being_tested:
pseudorandom()
else:
random()
When in test, program should use pseudorandom sequence to be able to compare with C code version of the program and in regular execution random from numpy should be used.
You can't, not without inspecting the call stack.
Generally speaking, you should not do this at all; by altering your code when tested you are not correctly testing your code.
Instead, you'd use mocking to replace any parts your code uses (anything used by the code under test but not part of it). For your specific example, you'd mock out random(); on Python 3.3 and up you can use unittest.mock, available as mock on PyPI for other Python versions, or you can just manually swap out module_under_test.random for the duration of the test.
You could also set an environment variable in your unittests to make it explicit you are running a test, but ideally that should be avoided.
I'm writing a Python wrapper for an authenticated RESTful API. I'm writing up my test suite right now (Also first time test-writer here) but have a few questions:
1.a) How can I make a call, but not have to hardcode credentials into the tests since I'll be throwing it on Github?
1.b) I kind of know about mocking, but have no idea how to go about it. Would this allow me to not have to call the actual service? What would be the best way to go about this?
2) What do I test for - Just ensure that my methods are passing certains items in the dictionary?
3) Any best practices I should be following here?
Hey TJ if you can show me an example of one function that you are writing (code under test, not the test code) then I can give you an example test.
Generally though:
1.a You would mock the call to the external api, you are not trying to test whether their authentication mechanism, or your internet connection is working. You are just trying to test that you are calling their api with the correct signature.
1.b Mocking in Python is relatively straight forward. I generally use the mocking library written by Michael Foord. pip install mock will get you started. Then you can do things like
import unittest
from mock import call, patch
from my_module import wrapper_func
class ExternalApiTest(unittest.TestCase):
#patch('my_module.api_func')
def test_external_api_call(self, mocked_api_func):
response = wrapper_func('user', 'pass')
self.assertTrue(mocked_api_func.called)
self.assertEqual(
mocked_api_func.call_args_list,
[call('user', 'pass')]
)
self.assertEqual(mocked_api_func.return_value, response)
In this example we are replacing the api_func inside my_module with a mock object. The mock object records what has been done to it. It's important to remember where to patch. You don't patch the location you imported the object from. You patch it in the location that you will be using it.
You test that your code is doing the correct thing with a given input. Testing pure functions (pure in the functional programming sense) is pretty simple. You assert that given a input a, this function returns output b. It gets a bit trickier when your functions have lots of side effects.
If you are finding it too hard or complicated to test a certain functiob/method it can mean that it's a badly written piece of code. Try breaking it up into testable chunks and rather than passing objects into functions try to pass primitives where possible.
I'm currently writing a set of unit tests for a Python microblogging library, and following advice received here have begun to use mock objects to return data as if from the service (identi.ca in this case).
However, surely by mocking httplib2 - the module I am using to request data - I am tying the unit tests to a specific implementation of my library, and removing the ability for them to function after refactoring (which is obviously one primary benefit of unit testing in the firt place).
Is there a best of both worlds scenario? The only one I can think of is to set up a microblogging server to use only for testing, but this would clearly be a large amount of work.
You are right that if you refactor your library to use something other than httplib2, then your unit tests will break. That isn't such a horrible dependency, since when that time comes it will be a simple matter to change your tests to mock out the new library.
If you want to avoid that, then write a very minimal wrapper around httplib2, and your tests can mock that. Then if you ever shift away from httplib2, you only have to change your wrapper. But notice the number of lines you have to change is the same either way, all that changes is whether they are in "test code" or "non-test code".
Not sure what your problem is. The mock class is part of the tests, conceptually at least. It is ok for the tests to depend on particular behaviour of the mock objects that they inject into the code being tested. Of course the injection itself should be shared across unit tests, so that it is easy to change the mockup implementation.