Replies: 2 comments 23 replies
-
Create a own package that fakes the import names Also reach out to the vendor about test automation Some venors provide extra license specifically for development or ci |
Beta Was this translation helpful? Give feedback.
-
Here is a more complete example. This also accounts for some of the suggestions from @RonnyPfannschmidt and @webknjaz in the other answer. Vendor packageFor demonstration purposes, here is a vendor package named
# arithmetic/__init__.py
from .divide import divide
from .multiply import multiply
__all__ = ["divide", "multiply"] # arithmetic/divide.py
def divide(a: float, b: float) -> float:
"""Divide two numbers."""
z = a / b
return z My packageI have a
# src/calculator/__init__.py
from .arithmetic_api import ArithmeticAPI
from .calculator import Calculator
__all__ = ["ArithmeticAPI", "Calculator"] # src/calculator/arithmetic_api.py
class ArithmeticAPI:
"""Wrapper API for the vendor arithmetic package."""
def __init__(self, arithmetic) -> None:
"""Initialize with the vendor's arithmetic package."""
self._arithmetic = arithmetic
def divide(self, x: float, y: float) -> float:
"""Divide two numbers using the vendor arithmetic package."""
z = self._arithmetic.divide(x, y)
return z # src/calculator/calculator.py
from .arithmetic_api import ArithmeticAPI
class Calculator:
"""Calculator model for arithmetic operations."""
def __init__(self, api: ArithmeticAPI | None = None) -> None:
self.api = api
@staticmethod
def add(x: float, y: float) -> float:
"""Add two numbers."""
z = x + y
return z
def divide(self, x: float, y: float) -> float:
"""Divide two numbers. Uses vendor arithmetic package if available."""
if self.api:
print("Using the vendor arithmetic package via ArithmeticAPI")
z = self.api.divide(x, y)
else:
z = x / y
return z UsageThis example uses the from calculator import Calculator
calc = Calculator()
z = calc.add(3, 1.5) This example divides two numbers without using the vendor package. from calculator import Calculator
calc = Calculator()
z = calc.divide(10, 3) This divides two numbers using the vendor's # Add the arithmetic package to path before running
# export PYTHONPATH="/Users/homer/Desktop/vendor/arithmetic/src:$PYTHONPATH"
import arithmetic # this is the vendor's arithmetic package
from calculator import ArithmeticAPI
from calculator import Calculator
api = ArithmeticAPI(arithmetic)
calc = Calculator(api)
z = calc.divide(10, 3) TestingTesting the addition function is straightforward as it doesn't rely on the vendor package. from calculator import Calculator
def test_addition():
"""Test add function."""
calc = Calculator()
z = calc.add(5, 12.1)
assert z == 17.1 Testing the division function involves two tests. One test for testing without the vendor package. Another test that mocks the wrapper API as if the from calculator import Calculator
from calculator import ArithmeticAPI
from unittest.mock import Mock
def test_division():
"""Test divide function."""
calc = Calculator()
z = calc.divide(9, 3)
assert z == 3
def test_division_vendor():
"""Test divide function using vendor arithmetic package via ArithmeticAPI."""
api = Mock(spec_set=ArithmeticAPI, divide=lambda x, y: 5.5)
calc = Calculator(api)
z = calc.divide(9, 3)
assert z == 5.5 SummaryHopefully this is a better example. I know it may not give all the details needed to provide a complete answer but I think it closely resembles the actual code I'm working with. @RonnyPfannschmidt and @webknjaz Let me know if you have more suggestions and thanks for the help. |
Beta Was this translation helpful? Give feedback.
-
I am using a Python package that is provided by a vendor that makes laboratory equipment. The vendor package provides an interface to control an instrument in the lab. Due to licensing, the vendor package is only on the computer that the instrument is connected to.
I made another Python package that relies on the vender package for some functionality. However, the computer where the vendor package resides is not always accessible which hampers the development of my own package. So the only time I can develop my package is when I have access to the lab computer.
I tried to monkeypatch functions from the vendor package. But it doesn't work because pytest complains that the vendor package can't be found. Below is some code to demonstrate the problem.
Is there a way I can use monkeypatch or some other feature of pytest to run tests for my package when the vendor package is not available? I basically want to mock the vendor package so that I can develop my own package when I don't have access to the computer where the vendor package resides.
Beta Was this translation helpful? Give feedback.
All reactions