অজগর ইউনিট পরীক্ষা থেকে তথ্য আউটপুটিং


115

আমি যদি অজগরটিতে ইউনিট পরীক্ষা লিখছি (ইউনিটেটেস্ট মডিউলটি ব্যবহার করে), ব্যর্থ পরীক্ষা থেকে ডেটা আউটপুট দেওয়া কি সম্ভব, তাই আমি ত্রুটিটির কারণটি হ্রাস করতে সহায়তা করতে এটি পরীক্ষা করতে পারি? আমি একটি কাস্টমাইজড বার্তা তৈরির ক্ষমতার বিষয়ে সচেতন, যা কিছু তথ্য বহন করতে পারে তবে কখনও কখনও আপনি আরও জটিল ডেটা নিয়ে কাজ করতে পারেন, এটি সহজেই স্ট্রিং হিসাবে প্রতিনিধিত্ব করতে পারে না।

উদাহরণস্বরূপ, ধরুন আপনার ক্লাস ফু ছিল এবং টেস্টডেটা নামক একটি তালিকা থেকে ডেটা ব্যবহার করে একটি পদ্ধতি বার পরীক্ষা করছিলেন:

class TestBar(unittest.TestCase):
    def runTest(self):
        for t1, t2 in testdata:
            f = Foo(t1)
            self.assertEqual(f.bar(t2), 2)

যদি পরীক্ষাটি ব্যর্থ হয় তবে আমি কেন এই নির্দিষ্ট ডেটাতে ব্যর্থতার কারণ হয়েছিল তা দেখতে টি 1, টি 2 এবং / বা এফ আউটপুট করতে চাই। আউটপুট দ্বারা, আমি বলতে চাইছি যে পরীক্ষাটি সঞ্চালনের পরে, ভেরিয়েবলগুলি অন্য ভেরিয়েবলগুলির মতো অ্যাক্সেস করা যায়।

উত্তর:


73

কারও পক্ষে খুব দেরীতে উত্তর যা আমার মত, এখানে একটি সহজ এবং দ্রুত উত্তর খুঁজছে।

পাইথন ২.7 msgএ ত্রুটি বার্তায় তথ্য যুক্ত করতে আপনি অতিরিক্ত পরামিতি ব্যবহার করতে পারেন :

self.assertEqual(f.bar(t2), 2, msg='{0}, {1}'.format(t1, t2))

অফিসিয়াল ডক্স এখানে here


1
পাইথন 3 এও কাজ করে।
মিঃডিবিএ

18
ডকগুলি এতে ইঙ্গিত করেছে তবে এটি স্পষ্টভাবে উল্লেখ করার মতো: ডিফল্টরূপে, যদি msgব্যবহৃত হয়, তবে এটি স্বাভাবিক ত্রুটি বার্তাকে প্রতিস্থাপন করবে। করতে msgস্বাভাবিক ত্রুটি বার্তা যোগ করা, এছাড়াও আপনি সেট করতে হবে TestCase.longMessage সত্যতে
Catalin Iacob

1
আমরা কাস্টম ত্রুটি বার্তাটি পাস করতে পারি তা জানতে পেরে ভাল, তবে আমি ত্রুটি নির্বিশেষে কিছু বার্তা প্রিন্ট করতে আগ্রহী ছিলাম।
হ্যারি মোরেনো

5
@ ক্যাটালিনআইকোবের মন্তব্য পাইথন ২.x এর ক্ষেত্রে প্রযোজ্য। পাইথন ৩.x এ, টেস্টকেস.লংমেসেজে ডিফল্ট হয় True
ndmeiri

70

আমরা এর জন্য লগিং মডিউলটি ব্যবহার করি।

উদাহরণ স্বরূপ:

import logging
class SomeTest( unittest.TestCase ):
    def testSomething( self ):
        log= logging.getLogger( "SomeTest.testSomething" )
        log.debug( "this= %r", self.this )
        log.debug( "that= %r", self.that )
        # etc.
        self.assertEquals( 3.14, pi )

if __name__ == "__main__":
    logging.basicConfig( stream=sys.stderr )
    logging.getLogger( "SomeTest.testSomething" ).setLevel( logging.DEBUG )
    unittest.main()

এটি আমাদের নির্দিষ্ট পরীক্ষাগুলির জন্য ডিবাগিং চালু করতে সহায়তা করে যা আমরা জানি যে ব্যর্থ হচ্ছে এবং যার জন্য আমরা অতিরিক্ত ডিবাগিং তথ্য চাই।

আমার পছন্দের পদ্ধতিটি তবে, ডিবাগিংয়ে প্রচুর সময় ব্যয় করা নয়, বরং সমস্যাটি প্রকাশের জন্য আরও সূক্ষ্ম পরীক্ষা দেওয়ার জন্য ব্যয় করা।


আমি যদি টেস্টসোমথিংয়ের অভ্যন্তরে কোনও পদ্ধতিকে ফোও বলি এবং এটি কিছু লগ করে। লগরে ফু-তে পাস না করে আমি কীভাবে এর জন্য আউটপুট দেখতে পারি?
simao

@ সিমাও: কী foo? একটি পৃথক ফাংশন? একটি পদ্ধতি ফাংশন SomeTest? প্রথম ক্ষেত্রে, কোনও ফাংশনের নিজস্ব লগার থাকতে পারে। দ্বিতীয় ক্ষেত্রে, অন্য পদ্ধতি ফাংশনটির নিজস্ব লগার থাকতে পারে। loggingপ্যাকেজ কীভাবে কাজ করে তা সম্পর্কে আপনি কি জানেন ? একাধিক লগার নিয়ম।
এসলট

8
আপনি নির্দিষ্টভাবে সঠিকভাবে লগিং সেটআপ করছি। আমি ধরে নিচ্ছি এটি কাজ করছে তবে আমি কোথায় আউটপুটটি দেখতে পাচ্ছি? এটি কনসোলে আউটপুট দিচ্ছে না। আমি কোনও ফাইলে লগিং করে এটি কনফিগার করার চেষ্টা করেছি, তবে এটি কোনও ফলও দেয় না।
মিকি ই

"তবে আমার পছন্দের পদ্ধতিটি ডিবাগিংয়ের জন্য প্রচুর সময় ব্যয় করা নয়, বরং সমস্যাটি প্রকাশের জন্য আরও সূক্ষ্ম পরীক্ষা করার জন্য ব্যয় করা উচিত" " -- ভাল বলেছ!
শেঠ

34

আপনি সাধারণ মুদ্রণ বিবৃতি, বা stdout লেখার অন্য কোনও উপায় ব্যবহার করতে পারেন। আপনি নিজের পরীক্ষাগুলির যে কোনও জায়গায় পাইথন ডিবাগারটিও ডেকে আনতে পারেন।

আপনি যদি নিজের পরীক্ষা চালানোর জন্য নাক ব্যবহার করেন (যা আমি প্রস্তাব দিই) তবে এটি প্রতিটি পরীক্ষার জন্য স্টাডআউট সংগ্রহ করবে এবং পরীক্ষাটি ব্যর্থ হলে কেবল তা আপনাকে দেখায়, সুতরাং পরীক্ষাগুলি পাস করার পরে আপনাকে বিশৃঙ্খল আউটপুট নিয়ে বেঁচে থাকতে হবে না।

আসক্তিতে উল্লিখিত ভেরিয়েবলগুলি স্বয়ংক্রিয়ভাবে প্রদর্শন করতে বা ব্যর্থ পরীক্ষায় ডিবাগারটি আহ্বান করতে নাকেরও সুইচ রয়েছে। উদাহরণস্বরূপ -s( --nocapture) স্টডআউট ক্যাপচার প্রতিরোধ করে।


দুর্ভাগ্যক্রমে, নাক লগিং ফ্রেমওয়ার্কটি ব্যবহার করে stdout / err এ লিখিত লগ সংগ্রহ করার মতো মনে হচ্ছে না। আমি printএবং log.debug()পরবর্তী প্রতিটি অন্যান্য, এবং স্পষ্টভাবে চালু DEBUGথেকে root- এ লগিং setUp()পদ্ধতি, কিন্তু শুধুমাত্র printআউটপুট শো আপ করুন।
হরিদসভ

7
nosetests -sstdout এর বিষয়বস্তুগুলি দেখায় যে কোনও ত্রুটি আছে কিনা বা নেই - এমন কিছু যা আমি দরকারী বলে মনে করি।
হ্যারিগ্রাফল

নাক ডক্সে স্বয়ংক্রিয়ভাবে ভেরিয়েবলগুলি দেখাতে আমি স্যুইচগুলি খুঁজে পাচ্ছি না। আপনি কি তাদের বর্ণনা করার মতো কিছুতে আমাকে নির্দেশ করতে পারেন?
এবিএম

নাক বা ইউনিটেস্ট থেকে স্বয়ংক্রিয়ভাবে ভেরিয়েবলগুলি দেখানোর কোনও উপায় আমি জানি না। আমি আমার পরীক্ষাগুলিতে যা দেখতে চাই তা মুদ্রণ করি।
নেড ব্যাচেল্ডার

16

আমি মনে করি না এটি আপনার জন্য ঠিক যা খুঁজছেন, ভেরিয়েবল মানগুলি প্রদর্শন করার কোনও উপায় নেই যা ব্যর্থ হয় না, তবে এটি আপনাকে পছন্দ মতো ফলাফলগুলি আউটপুট দেওয়ার আরও কাছে যেতে সহায়তা করতে পারে।

ফলাফল বিশ্লেষণ এবং প্রক্রিয়াজাতকরণের জন্য আপনি টেস্টরুনার.আরুন () দ্বারা ফেরত টেস্টরসাল্ট অবজেক্টটি ব্যবহার করতে পারেন । বিশেষত টেস্টআরসাল্ট.অরফারেন্স এবং টেস্টেরসাল্ট.ফেইলচারস

পরীক্ষার ফলাফলগুলি সম্পর্কে:

http://docs.python.org/library/unittest.html#id3

এবং আপনাকে সঠিক দিকে নির্দেশ করার জন্য কয়েকটি কোড:

>>> import random
>>> import unittest
>>>
>>> class TestSequenceFunctions(unittest.TestCase):
...     def setUp(self):
...         self.seq = range(5)
...     def testshuffle(self):
...         # make sure the shuffled sequence does not lose any elements
...         random.shuffle(self.seq)
...         self.seq.sort()
...         self.assertEqual(self.seq, range(10))
...     def testchoice(self):
...         element = random.choice(self.seq)
...         error_test = 1/0
...         self.assert_(element in self.seq)
...     def testsample(self):
...         self.assertRaises(ValueError, random.sample, self.seq, 20)
...         for element in random.sample(self.seq, 5):
...             self.assert_(element in self.seq)
...
>>> suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
>>> testResult = unittest.TextTestRunner(verbosity=2).run(suite)
testchoice (__main__.TestSequenceFunctions) ... ERROR
testsample (__main__.TestSequenceFunctions) ... ok
testshuffle (__main__.TestSequenceFunctions) ... FAIL

======================================================================
ERROR: testchoice (__main__.TestSequenceFunctions)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "<stdin>", line 11, in testchoice
ZeroDivisionError: integer division or modulo by zero

======================================================================
FAIL: testshuffle (__main__.TestSequenceFunctions)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "<stdin>", line 8, in testshuffle
AssertionError: [0, 1, 2, 3, 4] != [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

----------------------------------------------------------------------
Ran 3 tests in 0.031s

FAILED (failures=1, errors=1)
>>>
>>> testResult.errors
[(<__main__.TestSequenceFunctions testMethod=testchoice>, 'Traceback (most recent call last):\n  File "<stdin>"
, line 11, in testchoice\nZeroDivisionError: integer division or modulo by zero\n')]
>>>
>>> testResult.failures
[(<__main__.TestSequenceFunctions testMethod=testshuffle>, 'Traceback (most recent call last):\n  File "<stdin>
", line 8, in testshuffle\nAssertionError: [0, 1, 2, 3, 4] != [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n')]
>>>

5

অন্য বিকল্প - একটি ডিবাগার শুরু করুন যেখানে পরীক্ষা ব্যর্থ হয়।

টেস্টোব দিয়ে আপনার পরীক্ষা চালানোর চেষ্টা করুন (এটি কোনও পরিবর্তন ছাড়াই আপনার ইউনিটেট স্যুটটি চালাবে), এবং কোনও পরীক্ষা ব্যর্থ হলে আপনি '--debug' কমান্ড লাইন সুইচটি ডিবাগার খোলার জন্য ব্যবহার করতে পারেন।

উইন্ডোতে এখানে একটি টার্মিনাল সেশন রয়েছে:

C:\work> testoob tests.py --debug
F
Debugging for failure in test: test_foo (tests.MyTests.test_foo)
> c:\python25\lib\unittest.py(334)failUnlessEqual()
-> (msg or '%r != %r' % (first, second))
(Pdb) up
> c:\work\tests.py(6)test_foo()
-> self.assertEqual(x, y)
(Pdb) l
  1     from unittest import TestCase
  2     class MyTests(TestCase):
  3       def test_foo(self):
  4         x = 1
  5         y = 2
  6  ->     self.assertEqual(x, y)
[EOF]
(Pdb)

2
নাক ( nose.readthedocs.org/en/latest/index.html ) হল আরেকটি কাঠামো যা 'ডিবাগার সেশন শুরু করুন' বিকল্প সরবরাহ করে। আমি এটি '-sx --pdb --pdb-failures' দিয়ে চালিত করি, যা আউটপুট খায় না, প্রথম ব্যর্থতার পরে থামে এবং ব্যতিক্রম এবং পরীক্ষার ব্যর্থতায় পিডিবিতে যায়। আমি অলস এবং একটি লুপ পরীক্ষা না করেই এটি সমৃদ্ধ ত্রুটি বার্তাগুলির জন্য আমার প্রয়োজনীয়তা সরিয়ে ফেলেছে।
jwhitlock

5

আমি যে পদ্ধতিটি ব্যবহার করি তা সত্যিই সহজ। আমি কেবল এটি একটি সতর্কতা হিসাবে লগ করছি যাতে এটি প্রকৃতপক্ষে প্রদর্শিত হবে।

import logging

class TestBar(unittest.TestCase):
    def runTest(self):

       #this line is important
       logging.basicConfig()
       log = logging.getLogger("LOG")

       for t1, t2 in testdata:
         f = Foo(t1)
         self.assertEqual(f.bar(t2), 2)
         log.warning(t1)

এই পরীক্ষা সফল হলে এই কাজ করবে? আমার ক্ষেত্রে সতর্কতা কেবল যদি পরীক্ষা ব্যর্থ হয় তবে তা দেখানো হচ্ছে
শ্রেয়া মারিয়া

@ShreyaMaria হ্যা এটা হবে
Orane

5

আমি মনে করি আমি এটি অতিরিক্ত বিবেচনা করা হয়েছে। আমি যে উপায়টি নিয়ে কাজটি করেছি তার মধ্যে একটি উপায় হ'ল কেবল একটি বৈশ্বিক পরিবর্তনশীল, যা ডায়াগনস্টিক ডেটা সংগ্রহ করে।

এরকম কিছু:

log1 = dict()
class TestBar(unittest.TestCase):
    def runTest(self):
        for t1, t2 in testdata:
            f = Foo(t1) 
            if f.bar(t2) != 2: 
                log1("TestBar.runTest") = (f, t1, t2)
                self.fail("f.bar(t2) != 2")

উত্তরের জন্য ধন্যবাদ। পাইথনে ইউনিট পরীক্ষা থেকে কীভাবে তথ্য রেকর্ড করা যায় তার জন্য তারা আমাকে কিছু বিকল্প ধারণা দিয়েছেন।


2

লগিং ব্যবহার করুন:

import unittest
import logging
import inspect
import os

logging_level = logging.INFO

try:
    log_file = os.environ["LOG_FILE"]
except KeyError:
    log_file = None

def logger(stack=None):
    if not hasattr(logger, "initialized"):
        logging.basicConfig(filename=log_file, level=logging_level)
        logger.initialized = True
    if not stack:
        stack = inspect.stack()
    name = stack[1][3]
    try:
        name = stack[1][0].f_locals["self"].__class__.__name__ + "." + name
    except KeyError:
        pass
    return logging.getLogger(name)

def todo(msg):
    logger(inspect.stack()).warning("TODO: {}".format(msg))

def get_pi():
    logger().info("sorry, I know only three digits")
    return 3.14

class Test(unittest.TestCase):

    def testName(self):
        todo("use a better get_pi")
        pi = get_pi()
        logger().info("pi = {}".format(pi))
        todo("check more digits in pi")
        self.assertAlmostEqual(pi, 3.14)
        logger().debug("end of this test")
        pass

ব্যবহার:

# LOG_FILE=/tmp/log python3 -m unittest LoggerDemo
.
----------------------------------------------------------------------
Ran 1 test in 0.047s

OK
# cat /tmp/log
WARNING:Test.testName:TODO: use a better get_pi
INFO:get_pi:sorry, I know only three digits
INFO:Test.testName:pi = 3.14
WARNING:Test.testName:TODO: check more digits in pi

আপনি যদি সেট না করে থাকেন তবে LOG_FILEলগইন হবে stderr


2

আপনি loggingএটির জন্য মডিউল ব্যবহার করতে পারেন ।

সুতরাং ইউনিট পরীক্ষার কোডে, ব্যবহার করুন:

import logging as log

def test_foo(self):
    log.debug("Some debug message.")
    log.info("Some info message.")
    log.warning("Some warning message.")
    log.error("Some error message.")

ডিফল্টরূপে সতর্কতা এবং ত্রুটিগুলি আউটপুট করা হয় /dev/stderr, সুতরাং এগুলি কনসোলে দৃশ্যমান হওয়া উচিত।

লগগুলি (যেমন বিন্যাসকরণ) কাস্টমাইজ করতে, নিম্নলিখিত নমুনাটি ব্যবহার করে দেখুন:

# Set-up logger
if args.verbose or args.debug:
    logging.basicConfig( stream=sys.stdout )
    root = logging.getLogger()
    root.setLevel(logging.INFO if args.verbose else logging.DEBUG)
    ch = logging.StreamHandler(sys.stdout)
    ch.setLevel(logging.INFO if args.verbose else logging.DEBUG)
    ch.setFormatter(logging.Formatter('%(asctime)s %(levelname)s: %(name)s: %(message)s'))
    root.addHandler(ch)
else:
    logging.basicConfig(stream=sys.stderr)

2

এই ক্ষেত্রে আমি যা করি তা হ'ল log.debug()আমার আবেদনে কিছু বার্তা রয়েছে। যেহেতু ডিফল্ট লগিং স্তর হ'ল WARNING, এই জাতীয় বার্তাগুলি সাধারণ সম্পাদনে প্রদর্শিত হয় না।

তারপরে, ইউনিটেস্টে আমি লগিংয়ের স্তরটিতে পরিবর্তন করি DEBUG, যাতে এ জাতীয় বার্তা চালানোর সময় প্রদর্শিত হয় shown

import logging

log.debug("Some messages to be shown just when debugging or unittesting")

ইউনিটসেটে:

# Set log level
loglevel = logging.DEBUG
logging.basicConfig(level=loglevel)



একটি সম্পূর্ণ উদাহরণ দেখুন:

এটি daikiri.py, একটি মৌলিক শ্রেণি যা একটি দাইকিরির নাম এবং দাম সহ প্রয়োগ করে। একটি পদ্ধতি রয়েছে make_discount()যা প্রদত্ত ছাড় প্রয়োগের পরে সেই নির্দিষ্ট দাইকিরির দাম ফিরিয়ে দেয়:

import logging

log = logging.getLogger(__name__)

class Daikiri(object):
    def __init__(self, name, price):
        self.name = name
        self.price = price

    def make_discount(self, percentage):
        log.debug("Deducting discount...")  # I want to see this message
        return self.price * percentage

তারপরে, আমি একটি ইউনিট তৈরি করি test_daikiri.pyযা এর ব্যবহার পরীক্ষা করে:

import unittest
import logging
from .daikiri import Daikiri


class TestDaikiri(unittest.TestCase):
    def setUp(self):
        # Changing log level to DEBUG
        loglevel = logging.DEBUG
        logging.basicConfig(level=loglevel)

        self.mydaikiri = Daikiri("cuban", 25)

    def test_drop_price(self):
        new_price = self.mydaikiri.make_discount(0)
        self.assertEqual(new_price, 0)

if __name__ == "__main__":
    unittest.main()

সুতরাং আমি যখন এটি সম্পাদন করি তখন আমি log.debugবার্তাগুলি পাই :

$ python -m test_daikiri
DEBUG:daikiri:Deducting discount...
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

1

ইন্সপেক্ট.ট্রেস আপনাকে ব্যতিক্রম ছড়িয়ে দেওয়ার পরে স্থানীয় ভেরিয়েবলগুলি পেতে দেয়। তারপরে পোস্ট মর্টেমের সময় পরীক্ষার জন্য সেই স্থানীয় ভেরিয়েবলগুলি সংরক্ষণ করার জন্য আপনি নীচের মতো ডেকরেটারের সাথে ইউনিট পরীক্ষাগুলি মোড়াতে পারেন।

import random
import unittest
import inspect


def store_result(f):
    """
    Store the results of a test
    On success, store the return value.
    On failure, store the local variables where the exception was thrown.
    """
    def wrapped(self):
        if 'results' not in self.__dict__:
            self.results = {}
        # If a test throws an exception, store local variables in results:
        try:
            result = f(self)
        except Exception as e:
            self.results[f.__name__] = {'success':False, 'locals':inspect.trace()[-1][0].f_locals}
            raise e
        self.results[f.__name__] = {'success':True, 'result':result}
        return result
    return wrapped

def suite_results(suite):
    """
    Get all the results from a test suite
    """
    ans = {}
    for test in suite:
        if 'results' in test.__dict__:
            ans.update(test.results)
    return ans

# Example:
class TestSequenceFunctions(unittest.TestCase):

    def setUp(self):
        self.seq = range(10)

    @store_result
    def test_shuffle(self):
        # make sure the shuffled sequence does not lose any elements
        random.shuffle(self.seq)
        self.seq.sort()
        self.assertEqual(self.seq, range(10))
        # should raise an exception for an immutable sequence
        self.assertRaises(TypeError, random.shuffle, (1,2,3))
        return {1:2}

    @store_result
    def test_choice(self):
        element = random.choice(self.seq)
        self.assertTrue(element in self.seq)
        return {7:2}

    @store_result
    def test_sample(self):
        x = 799
        with self.assertRaises(ValueError):
            random.sample(self.seq, 20)
        for element in random.sample(self.seq, 5):
            self.assertTrue(element in self.seq)
        return {1:99999}


suite = unittest.TestLoader().loadTestsFromTestCase(TestSequenceFunctions)
unittest.TextTestRunner(verbosity=2).run(suite)

from pprint import pprint
pprint(suite_results(suite))

শেষ লাইনটি পরীক্ষার সাফল্যের সাথে ফিরে আসা মানগুলি এবং স্থানীয় ভেরিয়েবলগুলি প্রিন্ট করবে যেখানে এই ক্ষেত্রে এক্স, ব্যর্থ হলে:

{'test_choice': {'result': {7: 2}, 'success': True},
 'test_sample': {'locals': {'self': <__main__.TestSequenceFunctions testMethod=test_sample>,
                            'x': 799},
                 'success': False},
 'test_shuffle': {'result': {1: 2}, 'success': True}}

আপনি কি জানেন :-)


0

দৃ failure় ব্যর্থতা থেকে উত্পন্ন ব্যতিক্রম ধরা সম্পর্কে কীভাবে? আপনার ক্যাচ ব্লকে আপনি যেখানেই চেয়েছিলেন ডাটা আউটপুট করতে পারবেন। তারপরে আপনার কাজ শেষ হয়ে গেলে আপনি ব্যতিক্রমটি আবার ছুঁড়ে ফেলতে পারেন। পরীক্ষা রানার সম্ভবত পার্থক্যটি জানত না।

দাবি অস্বীকার: আমি পাইথনের ইউনিট পরীক্ষার কাঠামোর সাহায্যে এটি চেষ্টা করি নি তবে অন্যান্য ইউনিট পরীক্ষার কাঠামোর সাথেও করেছি।



-1

@ এফ সি এর উত্তর প্রসারিত করা, এটি আমার পক্ষে বেশ কার্যকর:

class MyTest(unittest.TestCase):
    def messenger(self, message):
        try:
            self.assertEqual(1, 2, msg=message)
        except AssertionError as e:      
            print "\nMESSENGER OUTPUT: %s" % str(e),
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.