কোনও ফাংশন প্রত্যাশিত ব্যতিক্রম না ছুঁড়লে কেবলমাত্র কীভাবে এমন এককটি লিখতে পারে যা ব্যর্থ হয়?
কোনও ফাংশন প্রত্যাশিত ব্যতিক্রম না ছুঁড়লে কেবলমাত্র কীভাবে এমন এককটি লিখতে পারে যা ব্যর্থ হয়?
উত্তর:
ইউনিটেটেস্ট মডিউল থেকে TestCase.assertRaises
(বা TestCase.failUnlessRaises
) ব্যবহার করুন , উদাহরণস্বরূপ:
import mymod
class MyTestCase(unittest.TestCase):
def test1(self):
self.assertRaises(SomeCoolException, mymod.myfunc)
myfunc
করার জন্য সেগুলি অ্যাসেটরাইজস কলটিতে যুক্তি হিসাবে যুক্ত করা দরকার to ড্যারিল স্পিজিটরের উত্তর দেখুন।
self.assertRaises(TypeError, mymod.myfunc)
। আপনি এখানে অন্তর্নির্মিত ব্যতিক্রমগুলির একটি সম্পূর্ণ তালিকা পেতে পারেন: ডকস.পিথথন.আর
self.assertRaises(SomeCoolException, Constructor, arg1)
পাইথন ২.7 যেহেতু আপনি ফেলে দেওয়া প্রকৃত ব্যতিক্রমী অবজেক্টটির প্রাপ্যতা পেতে প্রসঙ্গ পরিচালক ব্যবহার করতে পারেন:
import unittest
def broken_function():
raise Exception('This is broken')
class MyTestCase(unittest.TestCase):
def test(self):
with self.assertRaises(Exception) as context:
broken_function()
self.assertTrue('This is broken' in context.exception)
if __name__ == '__main__':
unittest.main()
http://docs.python.org/dev/library/unittest.html#unittest.TestCase.assertRaises
ইন পাইথন 3.5 , আপনি মোড়ানো আছে context.exception
মধ্যে str
, অন্যথায় আপনি একটি পাবেনTypeError
self.assertTrue('This is broken' in str(context.exception))
context.exception
বার্তা দেয় না; এটা এক প্রকার
import unittest2
আপনার ব্যবহার করা দরকার str()
, যেমন self.assertTrue('This is broken' in str(context.exception))
।
আমার আগের উত্তরের কোডটি এখানে সরল করা যেতে পারে:
def test_afunction_throws_exception(self):
self.assertRaises(ExpectedException, afunction)
এবং যদি কার্যকারিতাটি আর্গুমেন্ট নেয়, কেবল তাদের এন্টারট্রেস রাইজেস করুন:
def test_afunction_throws_exception(self):
self.assertRaises(ExpectedException, afunction, arg1, arg2)
2.7.15
। তাহলে afunction
এ self.assertRaises(ExpectedException, afunction, arg1, arg2)
বর্গ সূচনাকারী হয়, তাহলে আপনি পাস করতে হবে self
প্রথম আর্গুমেন্ট যেমন, যেমন self.assertRaises(ExpectedException, Class, self, arg1, arg2)
পাইথন ফাংশন একটি ব্যতিক্রম ছুঁড়ে ফেলেছে তা আপনি কীভাবে পরীক্ষা করবেন?
কোনও ফাংশন প্রত্যাশিত ব্যতিক্রম না ছুঁড়লে কেবলমাত্র কীভাবে একটি পরীক্ষা লিখবে?
self.assertRaises
প্রসঙ্গ পরিচালক হিসাবে পদ্ধতিটি ব্যবহার করুন :
def test_1_cannot_add_int_and_str(self):
with self.assertRaises(TypeError):
1 + '1'
পাইথন শেলটিতে সর্বোত্তম অনুশীলনের পদ্ধতির প্রদর্শন করা মোটামুটি সহজ।
unittest
গ্রন্থাগার
পাইথন ২.7 বা 3 তে:
import unittest
পাইথন ২.6-এ, আপনি ইউনিটএস্ট 2unittest
নামে পরিচিত 2.7 এর লাইব্রেরির একটি ব্যাকপোর্ট ইনস্টল করতে পারেন এবং কেবল এটির নাম হিসাবে unittest
:
import unittest2 as unittest
পাইথনের টাইপ-সুরক্ষার জন্য নিম্নলিখিত পরীক্ষাটি এখন আপনার পাইথন শেলটিতে আটকান:
class MyTestCase(unittest.TestCase):
def test_1_cannot_add_int_and_str(self):
with self.assertRaises(TypeError):
1 + '1'
def test_2_cannot_add_int_and_str(self):
import operator
self.assertRaises(TypeError, operator.add, 1, '1')
পরীক্ষার এক ব্যবহার assertRaises
প্রসঙ্গ পরিচালক হিসাবে করে, যা নিশ্চিত করে যে ত্রুটিটি সঠিকভাবে ধরা হয়েছে এবং রেকর্ড করার সময় পরিষ্কার হয়েছে।
আমরা প্রসঙ্গ পরিচালক ছাড়া এটি লিখতেও পারি, পরীক্ষা দুটি দেখুন। প্রথম যুক্তিটি হ'ল আপনি যে ত্রুটিটি উত্থাপনের প্রত্যাশা করছেন সেটি, দ্বিতীয় যুক্তি, আপনি যে ফাংশনটি পরীক্ষা করছেন এবং বাকি আরগস এবং কীওয়ার্ড আরগগুলি সেই ফাংশনে পাঠানো হবে।
আমি মনে করি এটি কেবল প্রসঙ্গ ব্যবস্থাপককে ব্যবহার করার জন্য আরও সহজ, পঠনযোগ্য এবং রক্ষণাবেক্ষণযোগ্য।
পরীক্ষা চালাতে:
unittest.main(exit=False)
পাইথন ২.6 এ আপনার সম্ভবত নিম্নলিখিতগুলির প্রয়োজন হবে :
unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))
এবং আপনার টার্মিনালটি নিম্নলিখিত আউটপুট করা উচিত:
..
----------------------------------------------------------------------
Ran 2 tests in 0.007s
OK
<unittest2.runner.TextTestResult run=2 errors=0 failures=0>
এবং আমরা দেখতে পাচ্ছি যে আমরা প্রত্যাশা মতো একটি যুক্ত করার চেষ্টা করেছি 1
এবং এর '1'
ফলে একটি TypeError
।
আরও ভার্বোজ আউটপুট জন্য, এই চেষ্টা করুন:
unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))
আপনার কোডটি এই প্যাটার্নটি অনুসরণ করবে (এটি এককতম মডিউল শৈলীর পরীক্ষা):
def test_afunction_throws_exception(self):
try:
afunction()
except ExpectedException:
pass
except Exception:
self.fail('unexpected exception raised')
else:
self.fail('ExpectedException not raised')
পাইথন <2.7 এ এই নির্মাণটি প্রত্যাশিত ব্যতিক্রমগুলিতে সুনির্দিষ্ট মানগুলি পরীক্ষা করার জন্য দরকারী। ইউনিটেটেস্ট ফাংশনটি assertRaises
কেবলমাত্র তার ব্যতিক্রম উত্থাপিত হয়েছিল কিনা তা পরীক্ষা করে।
assertRaises
পরিবর্তে একটি ত্রুটি পাবেন।
থেকে: http://www.lengrand.fr/2011/12/pythonunittest-assertraises-raises-error/
প্রথমত, এখানে dum_function.py ফাইলের সম্পর্কিত (এখনও ডাম: পি) ফাংশনটি দিচ্ছি:
def square_value(a):
"""
Returns the square value of a.
"""
try:
out = a*a
except TypeError:
raise TypeError("Input should be a string:")
return out
এখানে পরীক্ষাটি করা হবে (কেবলমাত্র এই পরীক্ষাটি সন্নিবেশ করা হয়েছে):
import dum_function as df # import function module
import unittest
class Test(unittest.TestCase):
"""
The class inherits from unittest
"""
def setUp(self):
"""
This method is called before each test
"""
self.false_int = "A"
def tearDown(self):
"""
This method is called after each test
"""
pass
#---
## TESTS
def test_square_value(self):
# assertRaises(excClass, callableObj) prototype
self.assertRaises(TypeError, df.square_value(self.false_int))
if __name__ == "__main__":
unittest.main()
আমরা এখন আমাদের ফাংশন পরীক্ষা করতে প্রস্তুত! পরীক্ষা চালানোর চেষ্টা করার পরে যা ঘটে তা এখানে:
======================================================================
ERROR: test_square_value (__main__.Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "test_dum_function.py", line 22, in test_square_value
self.assertRaises(TypeError, df.square_value(self.false_int))
File "/home/jlengrand/Desktop/function.py", line 8, in square_value
raise TypeError("Input should be a string:")
TypeError: Input should be a string:
----------------------------------------------------------------------
Ran 1 test in 0.000s
FAILED (errors=1)
TypeError হল অ্যাক্টুল্লে উত্থাপিত, এবং একটি পরীক্ষায় ব্যর্থতা উত্পন্ন করে। সমস্যাটি হ'ল এটি হ'ল আমাদের ঠিক আচরণ: এস।
এই ত্রুটিটি এড়াতে, পরীক্ষা কলটিতে ল্যাম্বদা ব্যবহার করে কেবল ফাংশনটি চালান:
self.assertRaises(TypeError, lambda: df.square_value(self.false_int))
চূড়ান্ত আউটপুট:
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK
পারফেক্ট!
... এবং আমার জন্যও নিখুঁত !!
থানস্ক অনেক মিঃ জুলিয়েন লেনগ্র্যান্ড-ল্যামবার্ট
এই পরীক্ষার দাবী আসলে একটি মিথ্যা ধনাত্মক ফেরত দেয় । এটি ঘটে কারণ 'অ্যাসেটরাইজেস' এর ভিতরে থাকা ল্যাম্বদা হ'ল একক যা পরীক্ষিত ক্রিয়াকলাপটি নয়, তবে টাইপ ত্রুটি উত্থাপন করে।
self.assertRaises(TypeError, df.square_value(self.false_int))
পদ্ধতিটিতে কল করে ফলাফলটি দেয়। আপনি যা চান তা হ'ল পদ্ধতি এবং কোনও যুক্তি পাস করা এবং একককে এটি কল করতে দিন:self.assertRaises(TypeError, df.square_value, self.false_int)
contextmanager
ব্যতিক্রমটি উত্থাপিত হয়েছে কিনা তা পরীক্ষা করতে আপনি নিজের তৈরি করতে পারেন।
import contextlib
@contextlib.contextmanager
def raises(exception):
try:
yield
except exception as e:
assert True
else:
assert False
এবং তারপরে আপনি এটির raises
মতো ব্যবহার করতে পারেন :
with raises(Exception):
print "Hola" # Calls assert False
with raises(Exception):
raise Exception # Calls assert True
আপনি যদি ব্যবহার করে থাকেন তবে pytest
এই জিনিসটি ইতিমধ্যে কার্যকর করা হয়েছে। আপনি করতে পারেন pytest.raises(Exception)
:
উদাহরণ:
def test_div_zero():
with pytest.raises(ZeroDivisionError):
1/0
এবং ফলাফল:
pigueiras@pigueiras$ py.test
================= test session starts =================
platform linux2 -- Python 2.6.6 -- py-1.4.20 -- pytest-2.5.2 -- /usr/bin/python
collected 1 items
tests/test_div_zero.py:6: test_div_zero PASSED
unittest
মডিউলটির প্রয়োজন নেই এমন উত্তর পোস্ট করার জন্য ধন্যবাদ !
আমি ডক্টেস্ট ব্যবহার করি প্রায় সর্বত্র [1] কারণ আমি একই সাথে আমার ফাংশনগুলি নথিভুক্ত ও পরীক্ষা করি তা পছন্দ করি।
এই কোডটি একবার দেখুন:
def throw_up(something, gowrong=False):
"""
>>> throw_up('Fish n Chips')
Traceback (most recent call last):
...
Exception: Fish n Chips
>>> throw_up('Fish n Chips', gowrong=True)
'I feel fine!'
"""
if gowrong:
return "I feel fine!"
raise Exception(something)
if __name__ == '__main__':
import doctest
doctest.testmod()
যদি আপনি এই উদাহরণটি একটি মডিউলে রাখেন এবং কমান্ড লাইন থেকে চালান তবে উভয় পরীক্ষার কেসগুলি মূল্যায়ন করে পরীক্ষা করা হয়।
[1] পাইথন ডকুমেন্টেশন: ২৩.২ ডক্টেস্ট - টেস্ট ইন্টারেক্টিভ পাইথনের উদাহরণ
আমি সবেমাত্র আবিষ্কার করেছি যে মক গ্রন্থাগারটি একটি assertRaisesWithMessage () পদ্ধতি সরবরাহ করে (তার ইউনিটেস্টে est টেস্টকেস সাবক্লাসে), যা কেবল প্রত্যাশিত ব্যতিক্রম উত্থাপিত নয় তা পরীক্ষা করে দেখবে, তবে এটি প্রত্যাশিত বার্তার সাথেও উত্থাপিত হয়েছে:
from testcase import TestCase
import mymod
class MyTestCase(TestCase):
def test1(self):
self.assertRaisesWithMessage(SomeCoolException,
'expected message',
mymod.myfunc)
এখানে অনেক উত্তর আছে। কোডটি দেখায় যে আমরা কীভাবে একটি ব্যতিক্রম তৈরি করতে পারি, কীভাবে আমরা আমাদের পদ্ধতিগুলিতে সেই ব্যতিক্রমটি ব্যবহার করতে পারি এবং শেষ পর্যন্ত কীভাবে আপনি ইউনিট পরীক্ষায় যাচাই করতে পারেন, সঠিক ব্যতিক্রমগুলি উত্থাপিত হচ্ছে।
import unittest
class DeviceException(Exception):
def __init__(self, msg, code):
self.msg = msg
self.code = code
def __str__(self):
return repr("Error {}: {}".format(self.code, self.msg))
class MyDevice(object):
def __init__(self):
self.name = 'DefaultName'
def setParameter(self, param, value):
if isinstance(value, str):
setattr(self, param , value)
else:
raise DeviceException('Incorrect type of argument passed. Name expects a string', 100001)
def getParameter(self, param):
return getattr(self, param)
class TestMyDevice(unittest.TestCase):
def setUp(self):
self.dev1 = MyDevice()
def tearDown(self):
del self.dev1
def test_name(self):
""" Test for valid input for name parameter """
self.dev1.setParameter('name', 'MyDevice')
name = self.dev1.getParameter('name')
self.assertEqual(name, 'MyDevice')
def test_invalid_name(self):
""" Test to check if error is raised if invalid type of input is provided """
self.assertRaises(DeviceException, self.dev1.setParameter, 'name', 1234)
def test_exception_message(self):
""" Test to check if correct exception message and code is raised when incorrect value is passed """
with self.assertRaises(DeviceException) as cm:
self.dev1.setParameter('name', 1234)
self.assertEqual(cm.exception.msg, 'Incorrect type of argument passed. Name expects a string', 'mismatch in expected error message')
self.assertEqual(cm.exception.code, 100001, 'mismatch in expected error code')
if __name__ == '__main__':
unittest.main()
আপনি ইউনিটতম মডিউল থেকে assertRaises ব্যবহার করতে পারেন
import unittest
class TestClass():
def raises_exception(self):
raise Exception("test")
class MyTestCase(unittest.TestCase):
def test_if_method_raises_correct_exception(self):
test_class = TestClass()
# note that you dont use () when passing the method to assertRaises
self.assertRaises(Exception, test_class.raises_exception)
যদিও সমস্ত উত্তর পুরোপুরি ঠিক আছে, আমি পরীক্ষার একটি উপায় খুঁজছিলাম যদি কোনও ফাংশন ইউনিট টেস্টিং ফ্রেমওয়ার্কের উপর নির্ভর না করে এবং পরীক্ষার ক্লাস না লিখে ব্যতিক্রম করে তোলে।
আমি নিম্নলিখিত লেখা শেষ:
def assert_error(e, x):
try:
e(x)
except:
return
raise AssertionError()
def failing_function(x):
raise ValueError()
def dummy_function(x):
return x
if __name__=="__main__":
assert_error(failing_function, 0)
assert_error(dummy_function, 0)
এবং এটি ডান লাইনে ব্যর্থ:
Traceback (most recent call last):
File "assert_error.py", line 16, in <module>
assert_error(dummy_function, 0)
File "assert_error.py", line 6, in assert_error
raise AssertionError()
AssertionError