Penggunaan fungsi PARRALE pada PHP

PHPUnit telah mengisyaratkan paralelisme sejak tahun 2007, tetapi sementara ini, pengujian kami terus berjalan perlahan-lahan. Waktu uang, kanan? ParaTest adalah alat yang berada di atas PHPUnit dan memungkinkan Anda menjalankan pengujian secara paralel tanpa menggunakan ekstensi. Ini adalah kandidat ideal untuk uji fungsional (yaitu Selenium) dan proses lain yang berjalan lama.

Table of Contents

  • ParaTest di Layanan Anda
  • Memasang ParaTest
  • Antarmuka Baris Perintah ParaTest
  • Tes Paralel Pertama Anda
  • Masalah di tangan
  • Mereka yang Datang Sebelumnya
  • Halo, Paraunit
  • ParaTest At Bat
  • Bagaimana ParaTest Menangani Pengujian Paralel
  • Contoh ParaTest
  • Pengujian Fungsional Dengan Selenium
  • Penanganan Kondisi Balap
  • ParaTest dan saus Labs
  • Masa depan ParaTest
  • Bacaan tambahan dan sumber daya
  • Fungsi PHP untuk apa?
  • PHP juga mampu lintas platform apa artinya?
  • Bagaimana cara kerja pemrograman PHP?
  • Mengapa menggunakan PHP?


ParaTest di Layanan Anda

ParaTest adalah alat baris perintah yang kuat untuk menjalankan tes PHPUnit secara paralel. Terinspirasi oleh orang-orang baik di Sauce Labs, awalnya dikembangkan untuk menjadi solusi yang lebih lengkap untuk meningkatkan kecepatan tes fungsional.

Sejak awal - dan terima kasih kepada beberapa kontributor brilian (termasuk Giorgio Sironi, pengelola ekstensi PHPUnit Selenium) - ParaTest telah menjadi alat yang berharga untuk mempercepat tes fungsional, serta tes integrasi yang melibatkan database, layanan web, dan sistem file .

ParaTest juga mendapat kehormatan dibundel dengan kerangka pengujian Saus Labe, dan telah digunakan di hampir 7000 proyek, pada saat penulisan ini.

Memasang ParaTest

Saat ini, satu-satunya cara resmi untuk menginstal ParaTest adalah melalui Komposer. Bagi Anda yang baru mengenal Composer, kami memiliki artikel bagus tentang hal ini. Untuk mengambil versi pengembangan terbaru, sertakan hal-hal berikut dalam file composer.json Anda:

"require": {
    "brianium/paratest": "dev-master"
}

Atau, untuk versi stabil terbaru:

"require": {
    "brianium/paratest": "0.4.4"
}

Selanjutnya, menjalankan instalasi komposer dari baris perintah. Biner ParaTest akan dibuat dalam direktori vendor/bin.

Antarmuka Baris Perintah ParaTest

ParaTest menyertakan antarmuka baris perintah yang seharusnya tidak asing bagi sebagian besar pengguna PHPUnit - dengan beberapa bonus tambahan untuk pengujian paralel.

Penggunaan fungsi PARRALE pada PHP

Tes Paralel Pertama Anda

Menggunakan ParaTest sama seperti sederhana seperti PHPUnit. Untuk dengan cepat menunjukkan hal ini dalam tindakan, membuat direktori, paratest-sampel, dengan struktur sebagai berikut:

Mari kita Instal ParaTest sebagaimana disebutkan di atas. Dengan asumsi bahwa Anda memiliki sebuah Bash shell dan biner komposer global diinstal, Anda dapat melakukannya dalam satu baris dari direktori paratest-contoh:

echo '{"require": { "brianium/paratest": "0.4.4" }}' > composer.json && composer install

Untuk masing-masing file di direktori, buat kelas kasus uji dengan nama yang sama, seperti:

class SlowOneTest extends PHPUnit_Framework_TestCase
{
    public function test_long_running_condition()
    {
        sleep(5);
        $this->assertTrue(true);
    }
}

Perhatikan penggunaan sleep(5) untuk mensimulasikan tes yang akan mengambil lima detik untuk dijalankan. Jadi kita harus memiliki lima kasus uji yang mengambil setiap lima detik untuk menjalankan. Menggunakan vanili PHPUnit, tes ini akan menjalankan serial dan mengambil dua puluh-lima detik, total. ParaTest akan menjalankan tes ini secara bersamaan dalam lima proses yang terpisah dan hanya harus mengambil lima detik, bukan dua puluh lima!

Sekarang bahwa kita memiliki pemahaman tentang apa ParaTest, mari kita menggali sedikit lebih dalam masalah yang terkait dengan menjalankan tes PHPUnit secara paralel.


Masalah di tangan

Pengujian dapat menjadi proses yang lambat, terutama ketika kita mulai berbicara tentang memukul database atau mengotomatisasi browser. Untuk menguji lebih cepat dan efisien, kita harus dapat menjalankan pengujian secara bersamaan (pada saat yang sama), bukan secara serial (satu demi satu).

Metode umum untuk mencapai ini bukan ide baru: menjalankan kelompok uji yang berbeda dalam beberapa proses PHPUnit. Ini dapat dengan mudah diselesaikan menggunakan fungsi PHP asli proc_open. Berikut ini akan menjadi contoh dari tindakan ini:

/**
 * $runningTests - currently open processes
 * $loadedTests - an array of test paths
 * $maxProcs - the total number of processes we want running
 */
while(sizeof($runningTests) || sizeof($loadedTests)) {
    while(sizeof($loadedTests) && sizeof($runningTests) < $maxProcs)
        $runningTests[] = proc_open("phpunit " . array_shift($loadedTests), $descriptorspec, $pipes);
    //log results and remove any processes that have finished ....
}

Karena PHP kekurangan benang asli, ini adalah metode yang khas untuk mencapai beberapa tingkat concurrency. Tantangan khusus dalam alat-alat pengujian yang menggunakan metode ini dapat direbus ke tiga masalah utama:

  • Bagaimana kami memuat tes?
  • Bagaimana kita agregat dan laporan hasil dari proses PHPUnit yang berbeda?
  • Bagaimana kami dapat menyediakan konsistensi dengan alat asli (mis. PHPUnit)?

Mari kita lihat beberapa teknik yang telah digunakan di masa lalu, dan kemudian meninjau ParaTest dan bagaimana itu berbeda dari yang lain.


Mereka yang Datang Sebelumnya

Seperti disebutkan sebelumnya, gagasan menjalankan PHPUnit dalam beberapa proses bukanlah yang baru. Prosedur khas yang digunakan adalah sesuatu di sepanjang baris berikut:

  • Grep untuk metode pengujian atau memuat direktori file yang berisi test suite.
  • Buka proses untuk setiap metode atau rangkaian uji.
  • Keluaran Parse dari pipa STDOUT.

Mari kita lihat alat yang menggunakan metode ini.

Halo, Paraunit

Paraunit adalah pelari paralel asli yang dipaketkan dengan saus Labs' sosis alat, dan ini berfungsi sebagai titik awal untuk ParaTest. Mari kita lihat bagaimana menangani tiga masalah utama yang disebutkan di atas.

Tes Memuat

Paraunit dirancang untuk memudahkan pengujian fungsional. Ini mengeksekusi setiap metode pengujian daripada seluruh rangkaian uji dalam proses PHPUnit miliknya sendiri. Mengingat jalur ke koleksi tes, Paraunit mencari metode pengujian individual, melalui pencocokan pola terhadap isi file.

preg_match_all("/function (test[^\(]+)\(/", $fileContents, $matches);

Metode uji yang diambil kemudian dapat dijalankan seperti ini:

proc_open("phpunit --filter=$testName $testFile", $descriptorspec, $pipes);

Dalam tes di mana setiap metode menyiapkan dan meruntuhkan browser, ini dapat membuat hal-hal sedikit lebih cepat, jika masing-masing metode tersebut dijalankan dalam proses terpisah. Namun, ada beberapa masalah dengan metode ini.

Sementara metode yang dimulai dengan kata, 'test,' adalah konvensi yang kuat di antara pengguna PHPUnit, anotasi adalah opsi lain. Metode pemuatan yang digunakan oleh Paraunit akan melewati pengujian yang sah ini:

/**
 * @test
 */
public function twoTodosCheckedShowsCorrectClearButtonText()
{
    $this->todos->addTodos(array('one', 'two'));
    $this->todos->getToggleAll()->click();
    $this->assertEquals('Clear 2 completed items', $this->todos->getClearButton()->text());
}

Selain tidak mendukung anotasi uji, warisan juga terbatas. Kami mungkin memperdebatkan manfaat melakukan sesuatu seperti ini, tetapi mari kita pertimbangkan pengaturan berikut:

abstract class TodoTest extends PHPUnit_Extensions_Selenium2TestCase
{
    protected $browser = null;

    public function setUp()
    {
       //configure browser
    }

    public function testTypingIntoFieldAndHittingEnterAddsTodo()
    {
        //selenium magic
    }
}

/**
 * ChromeTodoTest.php
 * No test methods to read!
 */
class ChromeTodoTest extends TodoTest
{
    protected $browser = 'chrome';
}

/**
 * FirefoxTodoTest.php
 * No test methods to read!
 */
class FirefoxTodoTest extends TodoTest
{
    protected $browser = 'firefox';
}

Metode yang mewarisi tidak dalam file, sehingga mereka tidak akan dimuat.

Menampilkan hasil

Paraunit mengumpulkan hasil dari setiap proses dengan menguraikan output yang dihasilkan oleh setiap proses. Metode ini memungkinkan Paraunit untuk menangkap keseluruhan lengkap kode pendek dan umpan balik yang disajikan oleh PHPUnit.

Kelemahan untuk mengumpulkan hasil dengan cara ini adalah bahwa itu cukup berat dan mudah rusak. Ada banyak hasil yang berbeda untuk diperhitungkan, dan banyak ekspresi reguler di tempat kerja untuk menampilkan hasil yang berarti dengan cara ini.

Konsistensi dengan PHPUnit

Karena file grepping, Paraunit cukup terbatas dalam fitur-fitur PHPUnit yang dapat mendukungnya. Ini adalah alat yang sangat baik untuk menjalankan struktur sederhana dari tes fungsional, tetapi, di samping beberapa kesulitan yang sudah disebutkan, itu tidak memiliki dukungan untuk beberapa fitur PHPUnit yang berguna. Beberapa contoh tersebut termasuk test suite, menentukan konfigurasi dan file bootstrap, mencatat hasil, dan menjalankan kelompok uji tertentu.

Banyak alat yang ada mengikuti pola ini. Grep direktori file uji dan jalankan seluruh file dalam proses baru atau setiap metode - tidak pernah keduanya.


ParaTest At Bat

Tujuan dari ParaTest adalah untuk mendukung pengujian paralel untuk berbagai skenario. Awalnya dibuat untuk mengisi celah di Paraunit, itu telah menjadi alat baris perintah yang kuat untuk menjalankan kedua test suite dan metode uji secara paralel. Hal ini menjadikan ParaTest sebagai kandidat ideal untuk uji jangka panjang dengan berbagai bentuk dan ukuran.

Bagaimana ParaTest Menangani Pengujian Paralel

ParaTest menyimpang dari norma yang ditetapkan untuk mendukung lebih banyak PHPUnit, dan bertindak sebagai kandidat yang benar-benar layak untuk pengujian paralel.

Tes Memuat

ParaTest beban tes dalam cara yang sama dengan PHPUnit. Beban semua tes dalam direktori tertentu yang diakhiri dengan akhiran *Test.php, atau akan memuat tes berdasarkan file konfigurasi PHPUnit XML standar. Pemuatan dilakukan, melalui refleksi, sehingga mudah untuk mendukung metode test, pewarisan, test suite, dan metode pengujian individual. Refleksi membuat penambahan dukungan untuk anotasi lainnya menjadi cepat.

Karena refleksi memungkinkan ParaTest untuk mengambil kelas dan metode, ia dapat menjalankan kedua rangkaian pengujian dan metode uji secara paralel, menjadikannya alat yang lebih serbaguna.

ParaTest memang memberlakukan beberapa kendala, tetapi yang sudah ada di komunitas PHP. Tes harus mengikuti standar PSR-0, dan akhiran file default * Test.php tidak dapat dikonfigurasi, seperti di PHPUnit. Ada cabang saat ini yang sedang berlangsung untuk mendukung konfigurasi sufiks yang sama yang diizinkan dalam PHPUnit.

Menampilkan Hasil

ParaTest juga menyimpang dari jalur parsing pipa STDOUT. Alih-alih mem-parsing aliran keluaran, ParaTest mencatat hasil dari setiap proses PHPUnit dalam format JUnit dan mengumpulkan hasil dari log ini. Jauh lebih mudah untuk membaca hasil tes dari format yang mapan daripada aliran keluaran.

<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
  <testsuite name="AnotherUnitTestInSubLevelTest" file="/home/brian/Projects/parallel-phpunit/test/fixtures/tests/level1/AnotherUnitTestInSubLevelTest.php" tests="3" assertions="3" failures="0" errors="0" time="0.005295">
    <testcase name="testTruth" class="AnotherUnitTestInSubLevelTest" file="/home/brian/Projects/parallel-phpunit/test/fixtures/tests/level1/AnotherUnitTestInSubLevelTest.php" line="7" assertions="1" time="0.001739"/>
    <testcase name="testFalsehood" class="AnotherUnitTestInSubLevelTest" file="/home/brian/Projects/parallel-phpunit/test/fixtures/tests/level1/AnotherUnitTestInSubLevelTest.php" line="15" assertions="1" time="0.000477"/>
    <testcase name="testArrayLength" class="AnotherUnitTestInSubLevelTest" file="/home/brian/Projects/parallel-phpunit/test/fixtures/tests/level1/AnotherUnitTestInSubLevelTest.php" line="23" assertions="1" time="0.003079"/>
  </testsuite>
</testsuites>

Mengurai log JUnit memang memiliki beberapa kelemahan kecil. Tes yang dilewati dan diabaikan tidak dilaporkan dalam umpan balik langsung, tetapi mereka akan tercermin dalam nilai total yang ditampilkan setelah uji coba.

Konsistensi dengan PHPUnit

Refleksi memungkinkan ParaTest mendukung lebih banyak konvensi PHPUnit. The ParaTest konsol mendukung lebih banyak fitur PHPUnit di luar kotak daripada alat serupa lainnya, seperti kemampuan untuk menjalankan grup, konfigurasi pasokan dan file bootstrap, dan hasil log dalam format JUnit.


Contoh ParaTest

ParaTest dapat digunakan untuk mendapatkan kecepatan dalam beberapa skenario pengujian.

Pengujian Fungsional Dengan Selenium

ParaTest unggul di pengujian fungsional. Mendukung saklar -f di dalam konsol untuk mengaktifkan mode fungsional. Mode fungsional menginstruksikan ParaTest untuk menjalankan setiap metode pengujian dalam proses terpisah, bukan default, yang menjalankan setiap rangkaian uji dalam proses terpisah.

Seringkali setiap metode uji fungsi melakukan banyak pekerjaan, seperti membuka browser, menjelajahi halaman, dan kemudian menutup browser.

Contoh proyek, paratest-selenium, menunjukkan pengujian aplikasi todo Backbone.js dengan Selenium dan ParaTest. Setiap metode uji membuka browser dan menguji fitur tertentu:

public function setUp()
{
    $this->setBrowserUrl('https://backbonejs.org/examples/todos/');
    $this->todos = new Todos($this->prepareSession());
}

public function testTypingIntoFieldAndHittingEnterAddsTodo()
{
    $this->todos->addTodo("parallelize phpunit tests\n");
    $this->assertEquals(1, sizeof($this->todos->getItems()));
}

public function testClickingTodoCheckboxMarksTodoDone()
{
    $this->todos->addTodo("make sure you can complete todos");
    $items = $this->todos->getItems();
    $item = array_shift($items);
    $this->todos->getItemCheckbox($item)->click();
    $this->assertEquals('done', $item->attribute('class'));
}

//....more tests

Test case ini bisa mengambil detik panas jika dijalankan secara serial, melalui vanilla PHPUnit. Mengapa tidak menjalankan beberapa metode sekaligus?

Penanganan Kondisi Balap

Seperti halnya pengujian paralel, kita harus memperhatikan skenario yang akan menghadirkan kondisi balapan - seperti beberapa proses yang mencoba mengakses basis data. Cabang dev-master ParaTest menyediakan fitur tes token yang sangat berguna, yang ditulis oleh kolaborator Dimitris Baltas (dbaltas on Github), yang membuat database pengujian integrasi menjadi jauh lebih mudah.

Dimitris telah menyertakan contoh bermanfaat yang menunjukkan fitur ini di Github. Dalam kata-kata Dimitris sendiri:

TEST_TOKEN mencoba untuk menangani masalah sumber daya umum dengan cara yang sangat sederhana: mengkloning sumber daya untuk memastikan bahwa tidak ada proses konkuren akan mengakses sumber daya yang sama.

Variabel lingkungan TEST_TOKEN disediakan untuk pengujian yang akan dikonsumsi, dan didaur ulang ketika proses telah selesai. Ini dapat digunakan untuk mengubah tes Anda secara kondisional, seperti:

public function setUp()
{
    parent::setUp();
    $this->_filename = sprintf('out%s.txt', getenv('TEST_TOKEN'));
}

ParaTest dan saus Labs

Saus Labs adalah Excalibur pengujian fungsional. Saus Labs menyediakan layanan yang memungkinkan Anda untuk dengan mudah menguji aplikasi Anda dalam berbagai browser dan platform. Jika Anda belum memeriksa mereka sebelumnya, saya sangat menyarankan Anda untuk melakukannya.

Menguji dengan Saus bisa menjadi tutorial tersendiri, tetapi para penyihir itu telah melakukan pekerjaan yang hebat dalam menyediakan tutorial untuk menggunakan PHP dan ParaTest untuk menulis tes fungsional menggunakan layanan mereka.


Masa depan ParaTest

ParaTest adalah alat yang hebat untuk mengisi beberapa kesenjangan PHPUnit, namun, pada akhirnya, itu adalah hanya plug di bendungan. Skenario yang jauh lebih baik akan dukungan asli di PHPUnit!

Sementara itu, ParaTest akan terus meningkatkan dukungan untuk lebih dari PHPUnit's asli perilaku. Itu akan terus menawarkan fitur yang berguna untuk pengujian paralel - terutama di alam fungsional dan integrasi.

ParaTest memiliki banyak hal-hal besar dalam karya-karya untuk meningkatkan transparansi antara PHPUnit dan itu sendiri, terutama di opsi-opsi konfigurasi apa yang didukung.

Versi stabil terbaru dari ParaTest (v0.4.4) yang nyaman mendukung Mac, Linux, dan Windows, tetapi ada beberapa permintaan tarik berharga dan fitur di dev-master yang pasti melayani keramaian Mac dan Linux. Jadi yang akan menarik percakapan yang bergerak maju.

Bacaan tambahan dan sumber daya

Ada beberapa artikel dan sumber daya di web yang menampilkan ParaTest. Memberi mereka membaca, jika Anda tertarik:

  • ParaTest pada Github
  • Paralel PHPUnit oleh kontributor ParaTest dan PHPUnit Selenium ekstensi maintainer Giorgio Sironi
  • Berkontribusi Paratest. Artikel yang sangat baik pada Giorgio's eksperimental WrapperRunner untuk ParaTest
  • Giorgio's kode sumber WrapperRunner
  • tripsta/paratest-sampel. Contoh fitur TEST_TOKEN oleh pencipta Danau Dimitris Baltas
  • brianium/paratest-selenium. Contoh penggunaan ParaTest untuk menulis tes fungsional

Fungsi PHP untuk apa?

Fungsi PHP dalam Pengembangan Website Agar halaman website lebih dinamis dan bisa menyesuaikan tampilan konten berdasarkan situasi, dibutuhkan integrasi dengan server dan database. Inilah fungsi PHP dalam pengembangan website, yaitu sebagai penghubung antara halaman statis dengan server dan database.

PHP juga mampu lintas platform apa artinya?

PHP adalah bahasa lintas platform; yang berarti dapat pada aplikasi di sejumlah sistem operasi yang berbeda seperti windows, Linux, Mac OS dll.

Bagaimana cara kerja pemrograman PHP?

Konsep kerja PHP diawali dengan permintaan suatu halaman web (file.php) oleh browser atau klien. Kemudian berdasarkan alamat di Internet (URL), browser mendapatkan alamat dari web server, yang akan mengidentifikasi halaman yang diminta, dan menyampaikan segala informasi yang dibutuhkan oleh web server.

Mengapa menggunakan PHP?

Fungsi PHP Dapat digunakan untuk membuat website dinamis. Banyak digunakan oleh programmer karena dapat menyimpan data dalam database. Dapat digunakan untuk membuat halaman yang fleksibel dan dapat diubah berdasarkan kemauan user untuk berbagai pengaturan yang diinginkan.