Posts: 5
Threads: 2
Joined: Jul 2020
Jul-12-2020, 07:51 PM
(This post was last modified: Jul-12-2020, 07:51 PM by rpk2006.)
I am using VSCode for Python programming.
I have two files:
(1) pyMain
(2) pyTests
With this program I am learning to write unit tests using pyTest.
[pyMain.py]
class Mathematics:
def AddNum(self,num1,num2):
return num1+num2
def SubtractNum(self,num1,num2):
return num1-num2
[pyTests.py]
from pyMain import Mathematics
import pytest
def TestAddition():
assert Mathematics.AddNum(1,5,6) == 11
def TestSubtraction():
assert Mathematics.SubtractNum(1,6,3) == 3
TestAddition()
TestSubtraction() I am not understanding why there is a need to pass value for 'self' in functions AddNum and SubtractNum. In pyTests.py, I am passing '1' to prevent error in the assert statements.
Posts: 1,583
Threads: 3
Joined: Mar 2020
Although they're part of your class, the way you've written the methods, they don't actually access any state of the class or the class instances (just passed in arguments). That really makes them static methods.
As such, you can declare them as such with the staticmethod decorator and then you don't have to pass in self (or the class).
class Mathematics:
@staticmethod
def AddNum(num1,num2):
return num1+num2
@staticmethod
def SubtractNum(num1,num2):
return num1-num2
Posts: 7,315
Threads: 123
Joined: Sep 2016
Jul-12-2020, 09:46 PM
(This post was last modified: Jul-12-2020, 09:46 PM by snippsat.)
(Jul-12-2020, 08:59 PM)bowlofred Wrote: As such, you can declare them as such with the staticmethod decorator and then you don't have to pass in self (or the class). @staticmethod is the way solve this,but i think this class should be used in normal way with a instantiating of a object in test function.
@ rpk2006 take a look this and it can be smart to some reading about classes/OOP in Python.
class Mathematics:
def add_num(self, num1, num2):
'''I am method in class Mathematics and not a function'''
return num1 + num2
def subtract_num(self, num1, num2):
return num1 - num2 Usage test:
>>> obj = Mathematics()
>>> obj.add_num(2, 7)
9
>>> obj.subtract_num(10, 3)
7
>>>
>>> obj.add_num(7, 7) == 14
True So the instantiation of obj can you to when testing this class.
So self do now become obj and can now pass 2 argument that the methods need.
Posts: 5
Threads: 2
Joined: Jul 2020
@ bowlofred, @snippsat:
You mean to say if I don't instantiate, it is considered STATIC ?
Thanks for the answers.
Posts: 1,838
Threads: 2
Joined: Apr 2017
No, they're static because they have no self parameter.
I don't agree that the class should be instantiated - as mentioned above, it holds no state so why would you? I don't think this example calls for a class anyway; just simple functions would do. Why introduce complexity for no reason? If you wanted to namespace the functions, just put them in a "mathematics" module.
Posts: 2,125
Threads: 11
Joined: May 2017
If you write a class, then do it right.
You're able to change the behavior of classes.
For example, you can add a method for add and subtract.
With your provided example:
class MyValue:
def __init__(self, value):
self.value = value
def __add__(self, other):
'''I am method in class Mathematics and not a function'''
return self.value + other.value
def __sub__(self, other):
return self.value - other.value
my_val1 = MyValue(5)
my_val2 = MyValue(4)
print(my_val1 + my_val2) Output: 9
And if you want to have functions, which takes left and right operand and doing something with it, then just use regular functions.
def add(a, b):
return a + b
def sub(a, b):
return a - b
# or use operator add and sub from operator module:
from operator import add, sub
print(add(1,2))
print(add(2,3)) Output: from operator import add, sub
print(add(1,2))
print(add(2,3))
I guess you wanted the class, to stick the methods together.
If you have a regular method, then you have to instantiate the class to access the method.
A staticmethod does not supply the function with a reference to self nor to class.
To use this method, the class must be instantiated.
Finally, the classmethod allows calling methods directly on a class without creating an instance.
class Math:
@classmethod
def add(cls, a, b):
return a + b
@classmethod
def sub(cls, a, b):
return a - b
# calling the method on the class directly
print(Math.sub(1,2)) Output: -1
Posts: 7,315
Threads: 123
Joined: Sep 2016
I agree that class are not needed here and could have been written better as @ DeaD_EyE show.
rpk2006 Wrote:With this program I am learning to write unit tests using pyTest. As this is the goal,here i use your code in first post no change,and write some for it Pytest.
from math_class import Mathematics
import pytest
def test_base_calc():
calc = Mathematics()
assert calc.AddNum(2, 2) == 4
assert calc.SubtractNum(2, 2) == 0
@pytest.mark.parametrize(
'n1, n2, expected', [
(4 , 5, 9),
(11, 98523, 98534),
(98652525, 52368745210, 52467397735),
]
)
def test_addtion(n1, n2, expected):
calc = Mathematics()
assert calc.AddNum(n1, n2) == expected
@pytest.mark.parametrize(
'n1, n2, expected', [
(12 , 6, 6),
(456785, 3692, 453093),
pytest.param(100, 35, 66, marks=pytest.mark.xfail),
]
)
def test_subtaction(n1, n2, expected):
calc = Mathematics()
assert calc.SubtractNum(n1, n2) == expected
|