Home > other >  How to check that an integer is passed to Pytest
How to check that an integer is passed to Pytest

Time:09-19

I have a simple code to check prod.py:

def add(x, y):
    return x ** y

add(4.1, 4)

This is the test code test_prod.py:

from prod import add
import pytest


@pytest.mark.parametrize("a, b, expected", [(4, 4, 256), (2, 3, 8)])
def test_prod(a, b, expected):
    assert add(a, b) == expected

@pytest.mark.parametrize("expected_exception, one, two", [(TypeError, 4, 'a'),])
def test_check(expected_exception, one, two):
    with pytest.raises(expected_exception):
        add(one, two)

Everything works well. But how do I check that the integer comes from prod.py ? In this code, prod.py returns a number with the float() data type. I need the test to fail. The test should end with success if prod.py will return int() .

I check the test like this: python3 -m pytest /home/user/test/test_prod.py -v

This doesn't work either because it doesn't check the real data type coming from prod.py::

from prod import add
import pytest


@pytest.mark.parametrize("a, b, expected", [(4, 4, 256), (2, 3, 8)])
def test_prod(a, b, expected):
    assert add(a, b) == expected
    if type(expected) is not int:
        assert False

@pytest.mark.parametrize("expected_exception, one, two", [(TypeError, 4, 'a'),])
def test_check(expected_exception, one, two):
    with pytest.raises(expected_exception):
        add(one, two)


This code should NOT pass the test:

def add(x, y):
    return x ** y

add(4.1, 4)

This code should pass the test:

def add(x, y):
    return int(x ** y)


print(add(4, 4.1))

CodePudding user response:

Just take the type of the outcome and test it versus the integer class.

The assert on float I put in the code should be removed for your purpose, but I put it in to show that it passes with the right type.

def add(x, y):
    return x ** y

result  = add(4.1, 4)

assert type(result) is float
assert type(result) is int

CodePudding user response:

You might want to add a raise TypeError to add if the input is non-integer:

def add(x, y):
    
    if type(x) is not int or type(y) is not int:
        raise TypeError("Add expects integer input")
        
    return x ** y

result  = add(4.1, 4)

You can use a decorator to do this on a function provided by a third party (modified from https://www.geeksforgeeks.org/decorators-in-python/)

# Defining the original function
def add(x, y):
    
    #if type(x) is not int or type(y) is not int:
    #    raise TypeError("Add expects integer input")
        
    return x ** y

# defining a decorator
def type_checking_decorator(func):
 
    # inner1 is a Wrapper function in
    # which the argument is called
     
    # inner function can access the outer local
    # functions like in this case "func"
    def inner1(x,y):
        if type(x) is not int or type(y) is not int:
            raise TypeError("Add expects integer input")
         
        # calling the actual function now
        # inside the wrapper function.
        func(x,y) 
        
    return inner1

 
# passing 'function_to_be_used' inside the
# decorator to control its behaviour
function_to_be_used = type_checking_decorator(add)
 
 
# calling the function
function_to_be_used(4, 4)
try:
    function_to_be_used(4.1, 4)
except TypeError as e:
    print(e)

CodePudding user response:

As pointed out by wim it is difficult to solve the exact question you have. Evaluating other peoples code is however a challenge addressed by nbgrader.

Building such a solution for yourself is hard and potentially dangerous because you are executing code from strangers on your own server.

nbgrader

  • Related