Reputation: 4010
How do I parameterize a test function using data that I obtain from other custom classes? In the documentation, I only see examples of parameterizing on static data given as a global list of tuples.
In my case, I am testing a function I wrote that finds a image within another image. It looks like so:
def search_for_image_in_image(screenshot_path, detectable_path):
"""
Uses template matching algorithm to detect an image within an image
:param screenshot_path: Path to the screenshot to search
:param detectable_path: Path to the detectable to search for
:return: tuple containing:
(bool) - Whether or not the detectable was found within the screenshot, using
the given epsilon
(float) - Maximum value the algorithm found
(list) - x and y position in the screenshot where the maximum value is located.
Or in other words, where the algorithm thinks the top left of the detectable
is most likely to be (if it is there at all)
So, I set up some sample data to test with:
tests\
sample data\
images_to_search_for\
moe.png
larry.png
curly.png
images_to_search
screenshot_01.png
screenshot_02.png
expected_results.csv
I manually created the csv file like so:
screenshot_name,moe,larry,curly
screenshot_01,True,False,True
screenshot_02,False,False,False
I can create classes or functions to load this sample data, but I don't understand how I am to pass it to my test method.
Here is the skeleton of my test code:
import pytest
from image_detection import search_for_image_in_image
class DataLoader(object):
def __init__(self):
# Load all the data up
pass
def get_screenshot_paths(self):
"""
:return: (list of string) paths to all the images to search
"""
pass
def get_detectable_paths(self):
"""
:return: (list of string) paths to all the images to search for
"""
pass
def is_expected_to_be_found(self, screenshot_name, detectable_name):
"""
:param screenshot_name:
:param detectable_name:
:return: Whether or not the detectable is expected to be found in the screenshot
"""
pass
@pytest.mark.parametrize("screenshot_path,detectable_path,expected_result", ???? )
def test_image_searching(screenshot_path, detectable_path, expected_result):
actual_result, _, _ = search_for_image_in_image(screenshot_path, detectable_path)
What do I put where I have "????" Or do I go about it some other way?
Upvotes: 0
Views: 208
Reputation: 50819
You need to create a function to handle the data
def data_provider():
data_loader = DataLoader()
yield pytest.param(data_loader.get_screenshot_paths(), data_loader.get_detectable_paths(), data_loader.is_expected_to_be_found('name_a', 'name_b'))
@pytest.mark.parametrize('screenshot_path, detectable_path, expected_result', data_provider())
def test_image_searching(self, screenshot_path, detectable_path, expected_result):
actual_result, _, _ = search_for_image_in_image(screenshot_path, detectable_path)
Upvotes: 0
Reputation: 403
I got your point. What I understand from your question is you want to parametrize the test methods from the return value of other functions, that you are unable to see in the pytest docs.
For that, You have to use pytest hook function(pytest_generate_tests) to parametrize the tests methods.
import pytest
def pytest_generate_tests(metafunc):
"""
This method will call before the execution of all the tests methods.
"""
# your logic here, to obtain the value(list data type) from any other custom classes.
# for e.g:-
data_loader = DataLoader()
images_path = data_loader.get_screenshot_paths()
images_path_1 = data_loader.get_detectable_paths()
metafunc.parametrize("first_path","seconds_path", images_path, images_path_1)
# now, whenever this method will called by test methods, it will automatically parametrize with the above values.
def test_1(first_path, second_path):
"""
Your tests method here
"""
I hope you find your answer. Refer(https://docs.pytest.org/en/latest/parametrize.html)
Upvotes: 1