นี่เป็นการใช้งาน conftest.py ที่ถูกต้องหรือไม่?
ใช่แล้ว. conftest.py
การแข่งขันจะมีการใช้งานที่มีศักยภาพและร่วมกันของ การแข่งขันที่คุณจะกำหนดจะถูกแชร์ในการทดสอบทั้งหมดในชุดทดสอบของคุณ อย่างไรก็ตามการนิยามฟิกซ์เจอร์ในรูทconftest.py
อาจไร้ประโยชน์และมันจะทำให้การทดสอบช้าลงหากฟิกซ์เจอร์เหล่านั้นไม่ได้ถูกใช้ในการทดสอบทั้งหมด
มันมีประโยชน์อื่น ๆ ?
ใช่แล้ว.
การแข่งขัน : กำหนดการแข่งขันสำหรับข้อมูลคงที่ที่ใช้โดยการทดสอบ ข้อมูลนี้สามารถเข้าถึงได้โดยการทดสอบทั้งหมดในชุดยกเว้นที่ระบุไว้เป็นอย่างอื่น นี่อาจเป็นข้อมูลเช่นเดียวกับผู้ช่วยเหลือของโมดูลซึ่งจะถูกส่งผ่านไปยังการทดสอบทั้งหมด
การโหลดปลั๊กอินภายนอก : conftest.py
ใช้เพื่อนำเข้าปลั๊กอินหรือโมดูลภายนอก โดยการกำหนดตัวแปรโกลบอลต่อไปนี้ pytest จะโหลดโมดูลและทำให้พร้อมใช้งานสำหรับการทดสอบ ปลั๊กอินโดยทั่วไปคือไฟล์ที่กำหนดไว้ในโครงการของคุณหรือโมดูลอื่น ๆ ซึ่งอาจจำเป็นในการทดสอบของคุณ นอกจากนี้คุณยังสามารถโหลดชุดของปลั๊กอินที่กำหนดไว้ล่วงหน้าตามที่อธิบายไว้ที่นี่
pytest_plugins = "someapp.someplugin"
Hooks : คุณสามารถระบุ hooks เช่นวิธีการตั้งค่าและการฉีกขาดและอีกมากมายเพื่อปรับปรุงการทดสอบของคุณ สำหรับชุดของตะขอใช้ได้อ่านที่นี่ ตัวอย่าง:
def pytest_runtest_setup(item):
""" called before ``pytest_runtest_call(item). """
#do some stuff`
ทดสอบเส้นทางหลัก : นี่เป็นคุณลักษณะที่ซ่อนอยู่เล็กน้อย โดยการกำหนดconftest.py
ในเส้นทางรากของคุณคุณจะต้องตระหนักถึงโมดูลใบสมัครของคุณโดยไม่ได้ระบุpytest
PYTHONPATH
ในพื้นหลัง py.test จะปรับเปลี่ยนของคุณsys.path
ด้วยการรวมเอา submodules ทั้งหมดที่พบจากเส้นทางของรูท
ฉันสามารถมีไฟล์ conftest.py มากกว่าหนึ่งไฟล์ได้หรือไม่
ใช่คุณสามารถทำได้และขอแนะนำอย่างยิ่งหากโครงสร้างการทดสอบของคุณค่อนข้างซับซ้อน conftest.py
ไฟล์มีขอบเขตไดเรกทอรี ดังนั้นการสร้างการแข่งขันและผู้ช่วยเป้าหมายจึงเป็นวิธีปฏิบัติที่ดี
เมื่อไหร่ที่ฉันจะทำเช่นนั้น? ตัวอย่างจะได้รับการชื่นชม
หลายกรณีสามารถใส่ได้:
การสร้างชุดเครื่องมือหรือขอสำหรับกลุ่มการทดสอบที่เฉพาะเจาะจง
ราก / mod / conftest.py
def pytest_runtest_setup(item):
print("I am mod")
#do some stuff
test root/mod2/test.py will NOT produce "I am mod"
กำลังโหลดชุดการแข่งขันสำหรับการทดสอบบางอย่าง แต่ไม่ใช่สำหรับการทดสอบอื่น ๆ
ราก / mod / conftest.py
@pytest.fixture()
def fixture():
return "some stuff"
ราก / mod2 / conftest.py
@pytest.fixture()
def fixture():
return "some other stuff"
ราก / mod2 / test.py
def test(fixture):
print(fixture)
จะพิมพ์ "สิ่งอื่น ๆ "
การแทนที่ hooks ที่สืบทอดมาจากรูconftest.py
ท
ราก / mod / conftest.py
def pytest_runtest_setup(item):
print("I am mod")
#do some stuff
ราก / conftest.py
def pytest_runtest_setup(item):
print("I am root")
#do some stuff
เมื่อทำการทดสอบภายในroot/mod
จะมีการพิมพ์เฉพาะ "I am mod"
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับที่นี่conftest.py
แก้ไข:
จะทำอย่างไรถ้าฉันต้องการฟังก์ชั่นตัวช่วยธรรมดาแบบเก่าที่จะเรียกจากการทดสอบจำนวนมากในโมดูลที่แตกต่างกัน - พวกเขาจะสามารถใช้งานได้หรือไม่หากฉันวางไว้ใน conftest.py หรือฉันควรวางไว้ในโมดูล helpers.py แล้วนำเข้าและใช้ในโมดูลทดสอบของฉัน
คุณสามารถใช้conftest.py
เพื่อกำหนดผู้ช่วยของคุณ อย่างไรก็ตามคุณควรปฏิบัติตามแนวทางปฏิบัติทั่วไป pytest
ผู้ช่วยสามารถนำมาใช้กับการติดตั้งอย่างน้อยใน ตัวอย่างเช่นในการทดสอบของฉันฉันมีผู้ช่วยจำลองซึ่งฉันฉีดเข้าไปในการทดสอบของฉันด้วยวิธีนี้
ราก / ผู้ช่วย / Redis / redis.py
@pytest.fixture
def mock_redis():
return MockRedis()
ราก / ทดสอบ / สิ่ง / conftest.py
pytest_plugin="helper.redis.redis"
ราก / ทดสอบ / สิ่ง / test.py
def test(mock_redis):
print(mock_redis.get('stuff'))
นี่จะเป็นโมดูลทดสอบที่คุณสามารถนำเข้าได้อย่างอิสระในการทดสอบของคุณ โปรดทราบว่าคุณอาจตั้งชื่อredis.py
ราวกับconftest.py
ว่าโมดูลของคุณredis
มีการทดสอบเพิ่มเติม อย่างไรก็ตามการฝึกฝนนั้นไม่ได้เกิดขึ้นเพราะความกำกวม
หากคุณต้องการใช้conftest.py
คุณสามารถใส่ผู้ช่วยนั้นลงในรูทconftest.py
แล้วฉีดเข้าไปเมื่อจำเป็น
ราก / ทดสอบ / conftest.py
@pytest.fixture
def mock_redis():
return MockRedis()
ราก / ทดสอบ / สิ่ง / test.py
def test(mock_redis):
print(mock_redis.get(stuff))
อีกอย่างที่คุณสามารถทำได้คือเขียนปลั๊กอินที่ติดตั้งได้ ในกรณีนี้ผู้ช่วยของคุณสามารถเขียนได้ทุกที่ แต่ต้องกำหนดจุดเริ่มต้นที่จะติดตั้งในกรอบการทดสอบของคุณและกรอบอื่น ๆ ดูนี่สิ
หากคุณไม่ต้องการใช้การแข่งขันแน่นอนคุณสามารถกำหนดผู้ช่วยที่เรียบง่ายและใช้การนำเข้าเก่าแบบธรรมดาทุกที่ที่ต้องการ
ราก / ทดสอบ / ผู้ช่วย / redis.py
class MockRedis():
# stuff
ราก / ทดสอบ / สิ่ง / test.py
from helper.redis import MockRedis
def test():
print(MockRedis().get(stuff))
อย่างไรก็ตามที่นี่คุณอาจมีปัญหากับเส้นทางเนื่องจากโมดูลไม่ได้อยู่ในโฟลเดอร์ย่อยของการทดสอบ คุณควรจะสามารถเอาชนะสิ่งนี้ (ไม่ผ่านการทดสอบ) โดยการเพิ่ม__init__.py
ผู้ช่วยของคุณ
ราก / ทดสอบ / ผู้ช่วย / __ init__.py
from .redis import MockRedis
PYTHONPATH
หรือเพียงแค่การเพิ่มโมดูลผู้ช่วยของคุณ
It seems great. However, I feel the documentation could be better.