การทดสอบกรณีทดสอบหน่วยเดียวที่มีการติดตั้ง / สถานการณ์จำนวนมากใน Pytest

ฉันมีคลาสที่แสดงถึงสถานะที่ซับซ้อน สถานะนั้นสามารถเปลี่ยนแปลงได้ และฉันก็มีอีกตัวอย่างหนึ่งของคลาสนั้นที่แสดงถึงสถานะ "จริง" ฉันเขียนฟังก์ชันที่ใช้ตรรกะที่แตกต่างกันและค้นหาวิธีทำให้สถานะปัจจุบันเป็นสถานะจริงหากต่างกัน

ฉันต้องการทดสอบฟังก์ชันนั้นโดยใช้ pytest มีหลายสถานการณ์ที่เป็นไปได้ แต่ตรรกะการทดสอบค่อนข้างง่ายและสรุปไปที่ (โค้ด pseudo python):

def test_diffing(current_state, prescribed_state):
    properties_to_add = []
    properties_to_delete = []
    properties_to_modify = []
    properties_to_add, properties_to_delete, properties_to_modify = diff_logic(current_state, prescribed_state)

    assert properties_to_add == 1
    assert properties_to_delete == 0
    assert properties_to_modify == 3

ตัวเลขทางด้านขวามือของการยืนยันจะขึ้นอยู่กับว่า current_state คืออะไร ฉันมีสถานการณ์ current_state มากมาย

วิธีที่ดีที่สุดในการเขียนการทดสอบหน่วยเดียวข้างต้นคืออะไร โดยมีฟิกซ์เจอร์หลายคู่ที่ current_state ถูกส่งไปพร้อมกับค่าที่คาดหวังของการยืนยัน

ฉันได้ดูการกำหนดค่าพารามิเตอร์ของ pytest แล้ว แต่ปัญหาของแนวทางนี้คือมันใช้ตัวตกแต่งและมันก็น่าเกลียด* เร็วมาก โดยเฉพาะอย่างยิ่งเมื่อมีการโต้แย้งจำนวนมากและกรณีทดสอบจำนวนมาก ดูเหมือนว่านี่ไม่ใช่สิ่งที่ฉันควรใช้อุปกรณ์ติดตั้ง

อะไรคือวิธีที่ดีที่สุดในการบรรลุสิ่งที่ฉันพยายามทำอย่างหมดจด?

*ฉันกำลังบอกว่ามันดูน่าเกลียดเนื่องจากการโต้แย้งกับมัณฑนากร 15 หรือ 20 ชุดนั้นทำให้เกิดความสับสนอย่างมาก และต้องใช้ตรรกะอย่างมากในตัวมัณฑนากรเอง


person darksky    schedule 11.07.2017    source แหล่งที่มา
comment
หากความเข้าใจของฉันถูกต้อง ฟิกซ์เจอร์จะมีความเหมือนกันระหว่างการทดสอบมากกว่า ไม่ใช่สำหรับอินพุตที่แตกต่างกัน ในกรณีของคุณ คุณน่าจะดีกว่าเขียนการทดสอบหน่วย 15-20 หน่วยหากคุณกำลังทดสอบสถานการณ์ที่ไม่ซ้ำกัน 15-20 รายการ   -  person Avantol13    schedule 11.07.2017
comment
นั่นสมเหตุสมผลแล้ว อะไรคือวิธีที่ดีที่สุดในการหลีกเลี่ยงการทำซ้ำตรรกะเดียวกันทุกประการ 15-20 ครั้ง ข้อแตกต่างเพียงอย่างเดียวคือวัตถุ current_state พร้อมกับความคาดหวัง   -  person darksky    schedule 11.07.2017


คำตอบ (1)


ฉันคิดว่าคุณสามารถใช้ อุปกรณ์ติดตั้งแบบพารามิเตอร์ เพื่อให้ได้สิ่งที่คุณ ต้องการ.

แล้วสิ่งที่ชอบ:

@pytest.fixture(params=[
    {
        'current_state': 'foo',
        'expected': {
            'properties_to_add': 1,
            'properties_to_delete': 2,
            'properties_to_modify': 3,
        },
    },
    ... as many scenarios as you'd like ...
])
def bundle(request):
    return request.param

@pytest.fixture
def current_state(bundle):
    return bundle['current_state']

@pytest.fixture
def expected(bundle):
    return bundle['expected']

ฉันใช้โครงสร้างฟิกซ์เจอร์ "บันเดิล" เพื่อเชื่อมโยงอินพุตและเอาต์พุตเข้าด้วยกัน การทดสอบดูสะอาดตามาก:

def test_diffing(current_state, expected):
    prescribed_state = ...  # I assume this is a constant, you can inject "prescribed_state" in the fixture in the same way as "current_state" and "expected"
    properties_to_add, properties_to_delete, properties_to_modify = diff_logic(current_state, prescribed_state)
    assert expected == {
        'properties_to_add': properties_to_add,
        'properties_to_delete': properties_to_delete,
        'properties_to_modify': properties_to_modify,
    }

จากนั้นหากโครงสร้างข้อมูล "params" (สำหรับฟิกซ์เจอร์ "บันเดิล") มีขนาดใหญ่มาก คุณสามารถกำหนดไว้ที่อื่นและจัดรูปแบบโค้ดเพื่อให้อ่านง่าย โหลดจากไฟล์ข้อมูล ฯลฯ

person Frank T    schedule 11.07.2017