Pertanyaan Memastikan py.test termasuk direktori aplikasi di sys.path


Saya memiliki struktur direktori proyek sebagai berikut (yang menurut saya cukup standar):

my_project
    setup.py
    mypkg
        __init__.py
        foo.py
    tests
        functional
            test_f1.py
        unit
            test_u1.py

Saya menggunakan py.test untuk kerangka pengujian saya, dan saya berharap dapat menjalankannya py.test tests ketika di my_project direktori untuk menjalankan tes saya. Ini memang berhasil, sampai saya mencoba mengimpor kode aplikasi saya menggunakan (misalnya) import mypkg dalam sebuah tes. Pada saat itu, saya mendapatkan kesalahan "Tidak ada modul bernama mypkg". Saat melakukan penyelidikan, tampaknya itu py.test menjalankan pengujian dengan direktori file tes di sys.path, tapi tidak direktori itu py.test lari dari.

Untuk mengatasi ini, saya telah menambahkan conftest.py file ke saya tests direktori, yang berisi kode berikut:

import sys, os

# Make sure that the application source directory (this directory's parent) is
# on sys.path.

here = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, here)

Ini tampaknya berfungsi, tetapi apakah ini cara yang baik untuk memastikan bahwa tes melihat kode aplikasi? Apakah ada cara yang lebih baik untuk mencapai ini, atau apakah saya melakukan sesuatu yang salah dalam bagaimana saya menyusun proyek saya?

Saya telah melihat beberapa proyek lain yang digunakan py.test (sebagai contoh, pip) tetapi saya tidak dapat melihat kode yang melakukan hal seperti ini, namun tetap berjalan py.test tests sepertinya bekerja di sana. Saya tidak tahu mengapa, tapi saya khawatir mereka mungkin mencapai hasil yang sama dengan cara yang lebih sederhana.

Saya telah melihat di py.test dokumentasi, tetapi saya tidak dapat melihat penjelasan tentang masalah ini atau apa pendekatan yang disarankan untuk mengatasinya.


32
2018-01-07 12:27


asal


Jawaban:


Seperti yang Anda katakan pada diri Anda py.test pada dasarnya menganggap Anda telah menyiapkan PYTHONPATH dengan benar. Ada beberapa cara untuk mencapai ini:

  • Berikan proyek Anda setup.py dan gunakan pip install -e . dalam virtualenv untuk proyek ini. Ini mungkin metode standar.

  • Sebagai variasi pada ini jika Anda memiliki virtualenv tetapi tidak setup.py menggunakan fasilitas venv Anda untuk menambahkan direktori proyek di sys.path, mis. pew add . jika Anda menggunakan pew, atau add2virtualenv . jika Anda menggunakan virtualenv dan ekstensi virtualenvwrapper.

  • Jika Anda selalu menyukai direktori kerja saat ini di sys.path, Anda dapat selalu mengekspor PYTHONPATH='' di shell Anda. Yaitu memastikan string kosong pada sys.path yang akan ditafsirkan oleh python sebagai direcotry kerja saat ini. Ini berpotensi bahaya keamanan.

  • Peretasan favorit saya sendiri, penyalahgunaan bagaimana py.test memuat file conftest: kosongkan conftest.py di direktori tingkat teratas proyek.

Alasan py.test untuk berperilaku dengan cara ini adalah dengan mempermudah menjalankan tes dalam sebuah tes / direktori checkout dengan paket yang diinstal. Jika tanpa syarat akan menambahkan direktori proyek ke PYTHONPATH maka ini tidak akan mungkin lagi.


31
2018-01-07 13:32



Jawabannya sebenarnya jauh lebih mudah, seperti yang terlihat sini.

Yang perlu Anda lakukan hanyalah menambahkan __init__.py ke direktori pengujian Anda dan masing-masing sub direktori, seperti halnya;

tests/__init__.py
tests/functional/__init__.py
tests/unit/__init__.py

7
2017-12-22 09:53



Cara mudah untuk melakukannya adalah, di direktori perubahan terminal / cmd ke tempat direktori induk berada, (mis. Dalam kasus ini cd C:/.../my_project).

Lalu lari: python -m pytest --cov=mypkg tests

Tidak perlu dipusingkan dengan PYTHONPATH. Dengan berlari bersama python -m, secara otomatis menggunakan jalur itu sebagai PYTHONPATH.


0
2017-08-07 12:05