কীভাবে সঠিকভাবে দাবি করা যায় যে পাইয়েস্টে কোনও ব্যতিক্রম উত্থাপিত হয়?


292

কোড:

# coding=utf-8
import pytest


def whatever():
    return 9/0

def test_whatever():
    try:
        whatever()
    except ZeroDivisionError as exc:
        pytest.fail(exc, pytrace=True)

আউটপুট:

================================ test session starts =================================
platform linux2 -- Python 2.7.3 -- py-1.4.20 -- pytest-2.5.2
plugins: django, cov
collected 1 items 

pytest_test.py F

====================================== FAILURES ======================================
___________________________________ test_whatever ____________________________________

    def test_whatever():
        try:
            whatever()
        except ZeroDivisionError as exc:
>           pytest.fail(exc, pytrace=True)
E           Failed: integer division or modulo by zero

pytest_test.py:12: Failed
============================== 1 failed in 1.16 seconds ==============================

পাইস্টেস্ট প্রিন্টের ট্রেসব্যাক কীভাবে তৈরি করবেন, তাই আমি দেখতে পাব ফাংশনটিতে whateverএকটি ব্যতিক্রম কোথায় উত্থাপিত হয়েছিল?


আমি পুরো ট্রেসব্যাকটি পাই, উবুন্টু 14.04, পাইথন 2.7.6
thefourtheye

@ থেফোর্তেয়ে আউটপুট দিয়ে টুকরো টানুন দয়া করে। আমি পাইথন ২.7.৪ এবং উবুন্টু ১৪.০৪ দিয়ে চেষ্টা করেছি - মূল পোস্টে বর্ণিত একই ফলাফলের সাথে।
গিল বেটস

1
@ গিলবেটস আপনি কি সঠিক উত্তরটি চিহ্নিত করতে পারবেন ??
গঞ্জালো গার্সিয়া

উত্তর:


329

pytest.raises(Exception) আপনার যা প্রয়োজন তা হল

কোড

import pytest

def test_passes():
    with pytest.raises(Exception) as e_info:
        x = 1 / 0

def test_passes_without_info():
    with pytest.raises(Exception):
        x = 1 / 0

def test_fails():
    with pytest.raises(Exception) as e_info:
        x = 1 / 1

def test_fails_without_info():
    with pytest.raises(Exception):
        x = 1 / 1

# Don't do this. Assertions are caught as exceptions.
def test_passes_but_should_not():
    try:
        x = 1 / 1
        assert False
    except Exception:
        assert True

# Even if the appropriate exception is caught, it is bad style,
# because the test result is less informative
# than it would be with pytest.raises(e)
# (it just says pass or fail.)

def test_passes_but_bad_style():
    try:
        x = 1 / 0
        assert False
    except ZeroDivisionError:
        assert True

def test_fails_but_bad_style():
    try:
        x = 1 / 1
        assert False
    except ZeroDivisionError:
        assert True

আউটপুট

============================================================================================= test session starts ==============================================================================================
platform linux2 -- Python 2.7.6 -- py-1.4.26 -- pytest-2.6.4
collected 7 items 

test.py ..FF..F

=================================================================================================== FAILURES ===================================================================================================
__________________________________________________________________________________________________ test_fails __________________________________________________________________________________________________

    def test_fails():
        with pytest.raises(Exception) as e_info:
>           x = 1 / 1
E           Failed: DID NOT RAISE

test.py:13: Failed
___________________________________________________________________________________________ test_fails_without_info ____________________________________________________________________________________________

    def test_fails_without_info():
        with pytest.raises(Exception):
>           x = 1 / 1
E           Failed: DID NOT RAISE

test.py:17: Failed
___________________________________________________________________________________________ test_fails_but_bad_style ___________________________________________________________________________________________

    def test_fails_but_bad_style():
        try:
            x = 1 / 1
>           assert False
E           assert False

test.py:43: AssertionError
====================================================================================== 3 failed, 4 passed in 0.02 seconds ======================================================================================

নোট করুন যে e_infoব্যতিক্রম বস্তুটি সংরক্ষণ করে যাতে আপনি এটি থেকে বিশদটি বের করতে পারেন। উদাহরণস্বরূপ, আপনি যদি ব্যতিক্রম কল স্ট্যাক বা ভিতরে অন্য কোনও নেস্টেড ব্যতিক্রম পরীক্ষা করতে চান।


34
এটি ভাল হবে যদি আপনি অনুসন্ধানের কোনও উদাহরণ অন্তর্ভুক্ত করতে পারেন e_info। নির্দিষ্ট অন্যান্য ভাষার সাথে আরও পরিচিত বিকাশকারীদের পক্ষে, এটি স্পষ্ট নয় যে এটির e_infoপরিধিটি withব্লকের বাইরেও প্রসারিত ।
সিজেএস

151

আপনি কি এরকম কিছু বোঝাতে চাইছেন:

def test_raises():
    with pytest.raises(Exception) as execinfo:   
        raise Exception('some info')
    # these asserts are identical; you can use either one   
    assert execinfo.value.args[0] == 'some info'
    assert str(execinfo.value) == 'some info'

16
excinfo.value.messageআমার জন্য কাজ করে না, ব্যবহার করতে হয়েছিল str(excinfo.value), একটি নতুন উত্তর যুক্ত করেছে
d_j

5
@ ডি_জে, assert excinfo.value.args[0] == 'some info'বার্তাটি অ্যাক্সেস করার সরাসরি উপায়
ম্যাক্সচলেপজিগ

assert excinfo.match(r"^some info$")পাশাপাশি কাজ করে
রবিন নিমেথ

14
সংস্করণ হিসাবে 3.1আপনি কীওয়ার্ড আর্গুমেন্টটি matchএই ব্যতিক্রমটি কোনও পাঠ্যের সাথে বা রেজেক্সের সাথে মেলে তা প্রমাণ করতে ব্যবহার করতে পারেন : with raises(ValueError, match='must be 0 or None'): raise ValueError("value must be 0 or None")বাwith raises(ValueError, match=r'must be \d+$'): raise ValueError("value must be 42")
ইলিয়া রুসিন

58

পাইস্টে এই ধরণের কেসগুলি হ্যান্ডেল করার দুটি উপায় রয়েছে:

  • pytest.raisesফাংশন ব্যবহার করে

  • pytest.mark.xfailসাজসজ্জার ব্যবহার করে

এর ব্যবহার pytest.raises:

def whatever():
    return 9/0
def test_whatever():
    with pytest.raises(ZeroDivisionError):
        whatever()

এর ব্যবহার pytest.mark.xfail:

@pytest.mark.xfail(raises=ZeroDivisionError)
def test_whatever():
    whatever()

এর আউটপুট pytest.raises:

============================= test session starts ============================
platform linux2 -- Python 2.7.10, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 -- 
/usr/local/python_2.7_10/bin/python
cachedir: .cache
rootdir: /home/user, inifile:
collected 1 item

test_fun.py::test_whatever PASSED


======================== 1 passed in 0.01 seconds =============================

pytest.xfailচিহ্নিতকারী আউটপুট :

============================= test session starts ============================
platform linux2 -- Python 2.7.10, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 -- 
/usr/local/python_2.7_10/bin/python
cachedir: .cache
rootdir: /home/user, inifile:
collected 1 item

test_fun.py::test_whatever xfail

======================== 1 xfailed in 0.03 seconds=============================

ডকুমেন্টেশন যেমন বলে:

ব্যবহার pytest.raises, সম্ভবত ক্ষেত্রে যেখানে আপনি ব্যতিক্রম আপনার নিজের কোড ইচ্ছাকৃতভাবে উত্থাপন করা হয় পরীক্ষা জন্য ভালো হতে ব্যবহার যেহেতু @pytest.mark.xfailএকটি চেক ফাংশন সম্ভবত ভাল নির্ভরতা মধ্যে অনির্ধারিত বাগ দলিল ভালো কিছু (যেখানে পরীক্ষা বর্ণনা কি ঘটতে "উচিত") অথবা বাগ জন্য ।


xfailএখানে সমস্যার সমাধান নয়, এটি কেবল পরীক্ষায় ব্যর্থ হতে দেয়। এখানে আমরা একটি নির্দিষ্ট ব্যতিক্রম উত্থাপিত হয়েছে কিনা তা পরীক্ষা করতে চাই।
Ctrl-C

44

আপনি চেষ্টা করতে পারেন

def test_exception():
    with pytest.raises(Exception) as excinfo:   
        function_that_raises_exception()   
    assert str(excinfo.value) == 'some info' 

পাইস্টেস্ট 5.0.0 এর স্ট্রিং হিসাবে ব্যতিক্রম বার্তা / মান পেতে, ব্যবহার str(excinfo.value)করা প্রয়োজন। এটি পাইস্টেস্ট ৪.x এও কাজ করে পাইস্টেস্ট ৪.x str(excinfo)এও কাজ করে তবে পাইস্টেস্ট ৫.০.০ এ কাজ করে না
মাকেন

এই আমি খুঁজছিলাম ছিল। আপনাকে ধন্যবাদ
ইস্টিন বিদায়

15

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

  • ব্যতিক্রম প্রকার (কঠোর পরীক্ষা)
  • ত্রুটি বার্তা (নিয়মিত এক্সপ্রেশন ব্যবহার করে কঠোর বা আলগা চেক)

ডকুমেন্টেশন থেকে দুটি উদাহরণ:

with pytest.raises(ValueError, match='must be 0 or None'):
    raise ValueError('value must be 0 or None')
with pytest.raises(ValueError, match=r'must be \d+$'):
    raise ValueError('value must be 42')

আমি এই পদ্ধতিটি বেশ কয়েকটি প্রকল্পে ব্যবহার করছি এবং এটি খুব পছন্দ করে।


6

সঠিক উপায়টি ব্যবহার করা হচ্ছে pytest.raisesতবে আমি এখানে মন্তব্যগুলিতে আকর্ষণীয় বিকল্প উপায় পেয়েছি এবং এই প্রশ্নের ভবিষ্যতের পাঠকদের জন্য এটি সংরক্ষণ করতে চাই:

try:
    thing_that_rasises_typeerror()
    assert False
except TypeError:
    assert True


2

আরও ভাল অনুশীলনটি এমন এক ক্লাস ব্যবহার করবে যা উত্তরাধিকার সূত্রে উত্তরাধিকার সূত্রে উত্তম হয় est টেস্টকেস এবং স্ব.অ্যাসেটরাইজগুলি চালায়।

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

import unittest


def whatever():
    return 9/0


class TestWhatEver(unittest.TestCase):

    def test_whatever():
        with self.assertRaises(ZeroDivisionError):
            whatever()

তারপরে আপনি এটি চালিয়ে চালিত করবেন:

pytest -vs test_path

4
এর চেয়ে ভাল অনুশীলন কি? আমি পাইস্টেস্ট সিনট্যাক্সের পরিবর্তে ইউনিটেস্ট সিনট্যাক্স ব্যবহার করে "উন্নত অনুশীলন" করব না।
জিন-

2
এটি 'ভাল' নাও হতে পারে তবে এটি একটি দরকারী বিকল্প। কারণ একটি উত্তরের মানদণ্ডটি ইউটিলিটি, তাই আমি উজ্জীবিত হচ্ছি।
রেব কেবিন

দেখে মনে pytestহচ্ছে এর চেয়ে বেশি জনপ্রিয় nosex, তবে আমি পাইটস্ট ব্যবহার করি।
গ্যাং

0

আপনি কি "পাইট্রেস = ট্রু" মুছে ফেলার চেষ্টা করেছেন?

pytest.fail(exc, pytrace=True) # before
pytest.fail(exc) # after

আপনি কি '- ফুলট্রেস' দিয়ে চালানোর চেষ্টা করেছেন?

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.