2

Consider the function foo provided by package X in Python. I want to test the different functionalities of X.foo, and then use X.foo in my code. To make sure that I am using X.foo as it was tested, I am thinking of encapsulating it inside a function, and then call that function instead. However, I am not sure if this is overkill, and that I should just call X.foo directly.

For example, to test X.foo, it is placed inside a function called main, which in turn is in a file called example.py:

# example.py
import X

def main(arg1,arg2,arg3):
    X.foo(arg1,arg2,arg3,...) # X.foo may have other arguments other than arg1,arg2, and arg3

Next, to unit-test X.foo, a new file called test_example.py is created in the same directory as example.py containing different functions that test the different functionalities of X.foo:

# test_example.py
from example import main

def test_foo1():
    main(...)
    # some assertions here

def test_foo2():
    main(...)
    # some assertions here

def test_foo3():
    main(...)
    # some assertions here

I would then run each of test_foo1,test_foo2, and test_foo3 to make sure that X.foo runs as expected. However, to use X.foo in my code, I am not sure whether to call X.foo directly, or to call main as I did in the tests above. That is, in another file, I could write either

import X
X.foo(...)

or

from example import main
main(...)

I feel that the latter option is "safer" because I am restricting my usage of X.foo to how it was tested and nothing more.

8
  • 4
    It is quite atypical to unit test library functions. Can you explain why you want to do so? May 9, 2022 at 15:45
  • @VincentSavard To make sure that they work as expected based on what I read from the documentation.
    – mhdadk
    May 9, 2022 at 15:46
  • 2
    Sorry, I still don't follow. Typically, you test your own code (that uses the library as an implementation details) and see that it behaves as expected. Testing the library directly seems counterproductive, as even if it does behave as it should, you have not tested whether your own code uses it correctly. You might even mock the actual library out depending on its nature, and its behaviour would only be tested through integration or end-to-end testing. May 9, 2022 at 15:51
  • 3
    @VincentSavard: I honor your idealism, but there are several real-world several cases where testing 3rd party library functions makes perfectly sense - specificially when the documentation is ambigous, incomplete, badly written or plain wrong.
    – Doc Brown
    May 9, 2022 at 18:28
  • 1
    @mhdadk can you give the actual example instead of all the foos and ... and main and example? ita really unclear what you are asking, or rather what you are doing testing wise that makes this problem seem difficult
    – Ewan
    May 9, 2022 at 19:10

2 Answers 2

2

Encapsulating library functions makes most sense when your "own" interface main offers simplified access to the library, or at least provides a more precise or more readable name (assuming in the real code, the functions are not just called main and X.foo). This can specifically be helpful in a situations where

  • the documentation of the lib has low quality, or

  • certain ways of using the library work, and others show up bugs (but you can live with that bugs because you found some workarounds) , or

  • the function(s) you are going to call are significantly more complex than what you require

This is nothing one can judge just by nonsensical names like main or foo. So let's make a better example: say this is a graphics drawing library, and X.foo is a universal drawing function (it's real name might be gfx.Draw), with tons of overloads and parameters to draw points, lines, curves, rectangles and others shapes. Now all you need is a line drawing function. So you decide to write a function DrawLine which calls gfx.Draw with the parameters for drawing a line between two endpoints.

To make sure your encapsulation is working correctly, you decide to write some simple tests for DrawLine which show it works as described in the documentation. Now it should be clear that your real code should also call DrawLine, which will be less error prone and more expressive than just calling gfx.Draw.

The situation will become different when you just write a function named MyDraw with the exact same parameters as gfx.Draw. It should be obvious that calling MyDraw will not bring much benefit in this situation, tests or not.

So in short - one does not use a capsule around library functions because of having written tests, one uses a capsule to simplify access (and write tests for making sure this works as intended). Note this can be also true when one does not write unit tests at all (but somewhere along the process one has to test the capsule, either manually or automatic, or as part of some integration test).

1

Foo is a dependency. If you want to test it, import it and call the methods on it that are being used as part of your test suite. For example, if you are using Foo.X write some tests around the X method. These are probably redundant if the maintainers are following best practices. But I could see them being useful for upgrade scenarios to see if there is breakage or un-expected results when major/minor upgrading since basically those tests are isolating Foo.X functionality and could serve as an early warning indicator for detecting functional and/or breaking changes.

The majority of tests would revolve around your actual implementation where your code is referencing Foo and using method X. Depending on the what the dependency does, Foo may be abstracted away via dependency injection. In your implementation, there might be some integration tests instead of unit tests since unit tests are not dealing with the real Foo.X if the Foo dependency is being abstracted. It depends on what the dependency does if unit or integration tests will provide Foo coverage. There should be enough unit/integration tests to cover Foo sufficiently in your test suite that you would not need to test Foo.X separately. But, if your worried about the quality of Foo.X, having the extra testing layer would help in that regard.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.