Phpunit: Penyedia Data dieksekusi sebelum setupBeforeClass

Dibuat pada 21 Feb 2013  ·  21Komentar  ·  Sumber: sebastianbergmann/phpunit

Penyedia data dipanggil sebelum setupBeforeClass statis dieksekusi. Kalau dipikir-pikir harus sebaliknya.

Kasus penggunaan:

  • Kami memiliki daftar adaptor. Beberapa adaptor hanya didukung pada beberapa lingkungan (yaitu Linux vs Win),
  • Saya ingin menginisialisasi daftar adaptor yang didukung sekali dan meneruskannya ke semua tes melalui penyedia data,
  • Cara terbersih yang dapat saya bayangkan adalah menginisialisasi properti statis di setupBeforeClass dan meminta penyedia mengembalikan properti itu

Masalahnya adalah bahwa properti tidak diinisialisasi ketika penyedia dipanggil.

Versi ditemukan: 3.7.14

Komentar yang paling membantu

@epdenouden JIT? Apakah Anda menguji dengan JIT untuk PHP, atau ada sesuatu yang saya tidak tahu? Maaf, saya agak bingung; apakah Anda berbicara tentang PHP7.x dan PHP8.x atau PHPUnit7.x dan PHPUnit8.x?!

@MAChitgarha Saya mengerti kebingungan Anda karena PHP8 mendapatkan _compiler_ tepat waktu. Saya menggunakan istilah untuk implementasi penyedia data baru yang didasarkan pada ide yang sama: _loader_ just-in-time alias pemuatan malas. Inisialisasi hanya apa yang Anda butuhkan, saat Anda membutuhkannya.

Ini akan bekerja dengan baik dengan PHP versi 8 JIT yang akan datang karena tidak menggunakan fitur rumit dari bahasa PHP itu sendiri. Semua pekerjaan saya jauh di dalam PHPUnit mengulang hal-hal seperti penguraian konfigurasi, pengujian memuat dan menjalankan, dll.

Jika sepertinya saya tidak melakukan apa-apa, saya melakukannya dengan benar. Kecuali untuk faktur GCP atau AWS yang diturunkan itu. 💸

Semua 21 komentar

Saya tidak yakin bahwa menegakkan beberapa urutan sehingga sumber daya statis dapat diinisialisasi dalam setupBeforeClass benar-benar masuk akal jika Anda menganggap bahwa penyedia data tidak harus statis atau bahkan di kelas pengujian yang sama.

Mengapa tidak malas menginisialisasi adaptor? Maka urutan tidak masalah sama sekali.

Tanpa menjalankan penyedia data, kami tidak tahu berapa banyak pengujian yang dijalankan oleh metode pengujian. Di dunia yang sempurna, kami akan memecahkan B/C dan mengharuskan penyedia data menjadi objek yang mengimplementasikan antarmuka yang diperluas Countable . Dengan begitu kita bisa memisahkan kekhawatiran ini dan memiliki situasi yang jauh lebih bersih.

@whatthejeff Inilah yang akhirnya kami lakukan. Namun inisialisasi dalam konstruktor bisa menjadi sedikit lebih bersih, karena parameter harus dibungkus dalam array ketika dikembalikan dari penyedia.

@sebastienbergmann ok saya mengerti mengapa mereka dipanggil sebelumnya sekarang, bagaimana dengan menyebutkannya di doc ? (Saya dapat membuka PR yang berubah jika Anda baik-baik saja). Saya bahkan tidak yakin memiliki objek akan banyak membantu: jika Anda melihat mantan saya, ada ketergantungan dari satu penyedia ke penyedia lainnya.

Terima kasih atas balasan Anda, menutup masalah.

@vicb , saya akan dengan senang hati menggabungkan PR terkait dokumentasi untuk ini.

Saya mungkin agak terlambat ke tempat kejadian, tetapi apa yang kebetulan saya lakukan ketika saya memiliki dependensi yang perlu saya inisialisasi adalah membuang anotasi @dataProvider dan menggunakan yield sebagai gantinya.

@srosato Saya bodoh (saya tidak menggunakan hasil). Bisakah Anda memberikan contoh singkat tentang bagaimana melakukan ini? Melalui https://Gist.github.com jika contoh di sini tidak sesuai.

Jika @dataProvider memerlukan kode penyiapan dan ukurannya tidak terlalu besar, Anda dapat menetapkannya sebagai string dan eval dalam pengujian. Sebagai contoh:

public function myProvider() {
    return [
        'new Klass("param 1", "param 2")',
        'new Klass("param 1", "param 2")',
    ];
}

/**
 * <strong i="8">@dataProvider</strong> myProvider
 */
public testMyFunction($instance_str) {
    $klass = eval("return {$instance_str};");
    # continue testing $klass ...
}

dua sen saya:

Alih-alih penyedia data yang mengandalkan properti statis (yang kami tahu tidak mungkin), saya menetapkan data/objek yang diperlukan sebagai anggota kelas dari kelas uji dalam metode setUp() .
di tearDown() saya menyetelnya ke nol, atau ketika ada objek kompleks saya menerapkan metode clear() untuk itu.

selama tidak ada terlalu banyak dependensi kelas uji, saya merasa nyaman dengan pendekatan ini.
tetapi ketika ada lebih dari satu atau dua dependensi seperti itu, Anda mungkin perlu terlalu memikirkan keseluruhan desain Anda.

secara khusus, saya menggunakan koneksi DB sebagai properti statis yang diatur dalam setUpBeforeClass() dan mengatur $queryBuilder , yang membuat koneksi disuntikkan, sebagai anggota kelas di setUp() (bukannya mengembalikannya di penyedia data).

Sebuah solusi akan mendefinisikan metode pribadi baru dan mendefinisikan variabel sebanyak yang diperlukan, sebanyak static yang ada di dalamnya. Kemudian, periksa apakah salah satunya diatur, dan jika tidak, atur semuanya dan kembalikan (atau hasilkan). Dengan cara ini, _variabel akan dideklarasikan hanya sekali_, bahkan jika Anda memiliki sepuluh penyedia atau apa pun. Selain itu, Anda dapat menggunakannya di setUpBeforeClass() atau setUp() .

Lihat dalam contoh:

private static function getData()
{
    static $data, $anotherData;

    if (!isset($data)) {
        $data = new TestClass();
        $anotherData = [];
    }

    return [
        $data,
        // Or: clone $data
        $anotherData,
    ];
}

public static function setUpBeforeClass()
{
    list(self::$sampleJson, self::$sampleData) = self::getData(); 
}

public function sampleProvider()
{
    $data = self::getData();

    return [
        $data
    ];
}

@MAChitgarha terima kasih atas komentar Anda kemarin saya mengetahui tentang tiket ini. :)

Saya sedang mengerjakan refactoring logika penyedia data di # 3736 yang akan menyelesaikan beberapa masalah umum:

  • tidak lagi memiliki lonjakan besar dalam aktivitas di awal proses karena semua penyedia data dimuat
  • penyedia data dapat berjalan setelah perlengkapan setUpBeforeClass dan setUp
  • penyedia data non-statis menjadi mungkin
  • generator akan jauh lebih efisien

@epdenouden Senang mendengarnya! ;) Item kedua dalam daftar Anda adalah item yang bagus. Menunggu itu.

Penyedia data non-statis menjadi mungkin

Bukankah saat ini mungkin? Saya selalu menggunakan penyedia data non-statis dalam pengujian saya alih-alih yang statis, dan mereka bekerja seperti yang diharapkan tanpa masalah (menggunakan PHPUnit 7.5.6). Apakah aku salah?

Bukankah saat ini mungkin? Saya selalu menggunakan penyedia data non-statis dalam pengujian saya alih-alih yang statis, dan mereka bekerja seperti yang diharapkan tanpa masalah (menggunakan PHPUnit 7.5.6). Apakah aku salah?

Tidak, Anda benar! Ungkapan saya tidak cukup tepat, terima kasih telah mengemukakan hal ini. Jauh di dalam kode penanganan penyedia data saat ini berbunyi:

private static function getDataFromDataProviderAnnotation($allTheParameters): ?iterable
    // code for locating the data provider
    // [...]
                if ($dataProviderMethod->isStatic()) {
                    $object = null;
                } else {
                    $object = $dataProviderClass->newInstance();
                }

    // code for preparing returned data rows
    // [...]
}

Jadi inilah rahasia kecil yang kotor:

  • Anda dapat menggunakan penyedia data non-statis dan
  • mereka akan dipanggil pada instanceof tapi...
  • itu _bukan contoh yang sama_ yang digunakan untuk perlengkapan dan tes

Anda memberi saya sesuatu untuk dipikirkan dan divalidasi mengenai refactoring penyedia data! Saya perlu menambahkan tes tambahan untuk memastikan instance objek adalah yang diharapkan, bukan hanya tipe atau klon yang sama. ️ dan pada saya ketika Anda berada di Amsterdam.

@epdenouden Tapi saya tidak mendapatkan kegagalan! Di PHPUnit 7.5.13, pernyataan tidak menghasilkan kesalahan apa pun. Bagaimana Anda mendapatkan kesalahan ini? Ketidakcocokan mundur, maksudmu?

Ini ada di cabang penyedia data pemuatan malas yang sedang saya kerjakan yang didasarkan pada 8.2. Saya akan memeriksa 7.5.x berikutnya, terima kasih atas perhatiannya.

Jika ini berhasil, saya harus kembali ke beberapa masalah lama lainnya yang meminta secara eksplisit untuk menerapkan metode penyedia non-statis dan melihat kasus penggunaan yang tepat lagi.

Bagaimanapun: komentar Anda telah menginspirasi tes yang sangat berguna :)

Dan @MAChitgarha ya itu akan menjadi BC-break

@epdenouden saya akan menunggu untuk itu. Untuk beberapa alasan, dalam proyek saya, saya menggunakan PHPUnit 7.5.13; tapi saya akan memperbaruinya ke 8.2.* segera. Dan kabar baiknya, jika BC-break bisa diperbaiki. Saya tidak tahu struktur PHPUnit itu sendiri, jadi saya tidak tahu apa yang Anda ubah, tapi saya rasa mungkin untuk memperbaikinya. Namun, itu semua terserah Anda! :)

Dan kabar baiknya, jika BC-break bisa diperbaiki. Saya tidak tahu struktur PHPUnit itu sendiri, jadi saya tidak tahu apa yang Anda ubah, tapi saya rasa mungkin untuk memperbaikinya. Namun, itu semua terserah Anda! :)

Memperkenalkan jeda kompatibilitas mundur tanpa alasan yang sangat bagus bukanlah sesuatu yang diizinkan oleh

Jadi ya, beri tahu kami apa yang ingin Anda lihat sebagai pengguna akhir/pengembang pengujian. Ingatlah bahwa proyek seperti ini tidak memiliki banyak pengembang sukarelawan.

Fakta menyenangkan: pengujian di atas memang bekerja pada kedua versi 7.x dan 8.x dan gagal pada prototipe JIT.

Kode yang saya kerjakan jauh lebih mirip dengan aliran kode asli. Jadi itu mungkin hasil dari bug, beberapa logika masih perlu saya refactor lebih lanjut, sesuatu tingkat rendah tentang objek dan refleksi dalam PHP saya perlu mencari atau mungkin hanya beberapa pengujian naif di pihak saya. 🔬

@epdenouden JIT? Apakah Anda menguji dengan JIT untuk PHP, atau ada sesuatu yang saya tidak tahu? Maaf, saya agak bingung; apakah Anda berbicara tentang PHP7.x dan PHP8.x atau PHPUnit7.x dan PHPUnit8.x?!

@epdenouden JIT? Apakah Anda menguji dengan JIT untuk PHP, atau ada sesuatu yang saya tidak tahu? Maaf, saya agak bingung; apakah Anda berbicara tentang PHP7.x dan PHP8.x atau PHPUnit7.x dan PHPUnit8.x?!

@MAChitgarha Saya mengerti kebingungan Anda karena PHP8 mendapatkan _compiler_ tepat waktu. Saya menggunakan istilah untuk implementasi penyedia data baru yang didasarkan pada ide yang sama: _loader_ just-in-time alias pemuatan malas. Inisialisasi hanya apa yang Anda butuhkan, saat Anda membutuhkannya.

Ini akan bekerja dengan baik dengan PHP versi 8 JIT yang akan datang karena tidak menggunakan fitur rumit dari bahasa PHP itu sendiri. Semua pekerjaan saya jauh di dalam PHPUnit mengulang hal-hal seperti penguraian konfigurasi, pengujian memuat dan menjalankan, dll.

Jika sepertinya saya tidak melakukan apa-apa, saya melakukannya dengan benar. Kecuali untuk faktur GCP atau AWS yang diturunkan itu. 💸

Apakah halaman ini membantu?
0 / 5 - 0 peringkat