-1

I'm writing integration tests using plain unittest in Python (import unittest) and are creating stubs for some external services. Now I want to run the same tests with a real implementation; but also keep the stubs. That way I can run the tests with and without the stubs and compare behaviour.

I'm running my tests both from SetupTools and through PyCharm. Is there some generic way for me to set/inject/bootstrap a parameter which tells my code wether to use the stub or the real implementation? Command line preferrable. Any pointers appreciated. :)

Anders S
  • 438
  • 4
  • 15
  • 1
    unittests shouldn't use the real implemetation. if they did they would be integration tests. make separete tests that use the real implementation. – Ionut Hulub May 27 '15 at 08:49
  • I'm just using the unittest library, but you are correct they are integration tests. Regardless: I would like to be able to exercise both the real implementation as well as the stub. This comparison has given me a lot of value earlier when something external changes. – Anders S May 27 '15 at 09:41
  • Say you're testing an unit called `foo`. This unit uses the real implementation of `bar`. Bar has a typo and throws an error. Your unit test for `foo` will fail, even though the `foo` unit doesn't have any error. This is why it's undesireable to use real implementations in unit tests, and I think you should rethink the approach. – Ionut Hulub May 27 '15 at 09:43
  • Like I said: They are integration tests. I have unit tests as well. And I would like to run both, not just one of them. But I need some way to manage which is active at that specific point in time. – Anders S May 27 '15 at 09:53

1 Answers1

0

It sounds like you are looking for a mocking framework. Mocking frameworks allow you to create a 'stub' for the method from within your test. This is good because you don't want to be inserting any test specific code into your actual code.

One of the more popular mocking frameworks for python 2.* is python-mock (in fact it comes with python 3) So you can write the code as:

from mock import MagicMock

test_foo_mocked():
    bar = MagicMock()
    bar.return_value = 'fake_val'
    assertEqual(bar(), 'fake_val')

test_foo_real():
    assertEqual(bar(), 'real_val')

Side Note:
I would really recommend that you think of these as completely unrelated tests. There are many benefits to keeping your integration tests separate from your unit tests. Thinking of them as two different ways of running the 'same test' may encourage you to write bad tests. Unit tests should be able to test things that would be difficult or impossible to test through integration tests and vice versa.

chrisst
  • 1,696
  • 5
  • 19
  • 32
  • Thanks for the pointers, but I try to stay away from Mocking as much as I can. I do have stubs though, that really doesn't need a framework in Python. While I can see that you could end up with some ugly tests by treating them as one, you'd also have to update several tests when something changes. So you could end up in a situation where the real-impl test is updated, while the stub-test is running against something that doesn't occur in the real impl. – Anders S Jul 02 '15 at 07:51