Paket ini membantu menjalankan pengujian unit terkait waktu/IO (misalnya, panggilan fungsi tidur, kueri basis data, panggilan API, dll) lebih cepat menggunakan Swoole.
Paket counit memungkinkan menjalankan beberapa tes terkait waktu/IO secara bersamaan dalam satu proses PHP menggunakan Swoole. Counit kompatibel dengan PHPUnit , yang artinya:
Kasus uji counit yang umum terlihat seperti ini:
use Deminy Counit TestCase ; // Here is the only change made for counit, comparing to test cases for PHPUnit.
class SleepTest extends TestCase
{
public function testSleep (): void
{
$ startTime = time ();
sleep ( 3 );
$ endTime = time ();
self :: assertEqualsWithDelta ( 3 , ( $ endTime - $ startTime ), 1 , ' The sleep() function call takes about 3 seconds to finish. ' );
}
}
Dibandingkan dengan PHPUnit , counit dapat membuat kasus pengujian Anda lebih cepat. Berikut perbandingan saat menjalankan test suite yang sama menggunakan PHPUnit dan counit untuk proyek nyata. Dalam rangkaian pengujian, banyak pengujian yang melakukan panggilan ke metode DeminyCounitCounit::sleep() untuk menunggu sesuatu terjadi (misalnya, menunggu data kedaluwarsa).
# Tes | # Pernyataan | Saatnya Menyelesaikan | |
---|---|---|---|
counit (tanpa Swoole), atau PHPUnit | 44 | 1148 | 9 menit 18 detik |
counit (dengan Swoole diaktifkan) | 19 detik |
Paket dapat diinstal menggunakan Composer :
composer require deminy/counit --dev
Atau, di file composer.json Anda, pastikan paket deminy/counit disertakan:
{
"require-dev" : {
"deminy/counit" : " ~0.2.0 "
}
}
Folder ./tests/unit/global dan ./tests/unit/case-by-case berisi beberapa contoh pengujian, yang mencakup pengujian terkait waktu berikut:
Untuk menjalankan pengujian sampel, jalankan container Docker dan instal paket Composer terlebih dahulu:
docker-compose up -d
docker compose exec -ti swoole composer install -n
Ada lima container yang dimulai: container PHP, container Swoole, container Redis, container MySQL, dan server web. Kontainer PHP tidak menginstal ekstensi Swoole, sedangkan kontainer Swoole telah menginstal dan mengaktifkannya.
Seperti disebutkan sebelumnya, kasus pengujian dapat ditulis dengan cara yang sama seperti PHPUnit . Namun, untuk menjalankan pengujian terkait waktu/IO lebih cepat dengan counit , kita perlu melakukan beberapa penyesuaian saat menulis kasus pengujian tersebut; penyesuaian ini dapat dilakukan dalam dua gaya berbeda.
Dalam gaya ini, setiap kasus pengujian dijalankan dalam coroutine terpisah secara otomatis.
Untuk kasus pengujian yang ditulis dengan gaya ini, satu-satunya perubahan yang harus dilakukan pada kasus pengujian yang ada adalah menggunakan kelas DeminyCounitTestCase alih-alih PHPUnitFrameworkTestCase sebagai kelas dasar.
Contoh kasus uji gaya global terlihat seperti ini:
use Deminy Counit TestCase ; // Here is the only change made for counit, comparing to test cases for PHPUnit.
class SleepTest extends TestCase
{
public function testSleep (): void
{
$ startTime = time ();
sleep ( 3 );
$ endTime = time ();
self :: assertEqualsWithDelta ( 3 , ( $ endTime - $ startTime ), 1 , ' The sleep() function call takes about 3 seconds to finish. ' );
}
}
Ketika metode kustomisasi setUpBeforeClass() dan tearDownAfterClass() ditentukan dalam kasus pengujian, pastikan untuk memanggil metode induknya sesuai dengan metode kustomisasi ini.
Gaya ini mengasumsikan tidak ada pernyataan langsung dalam kasus pengujian, atau pernyataan sebelum pemanggilan fungsi sleep() atau operasi IO ramah coroutine. Kasus uji seperti berikut masih berfungsi, namun akan memicu beberapa pesan peringatan saat diuji:
class GlobalTest extends Deminy Counit TestCase
{
public function testAssertionSuppression (): void
{
self :: assertTrue ( true , ' Trigger an immediate assertion. ' );
// ......
}
}
Kita dapat menulis ulang kelas pengujian ini menggunakan gaya "kasus per kasus" (dibahas di bagian selanjutnya) untuk menghilangkan pesan peringatan.
Untuk menemukan lebih banyak tes yang ditulis dengan gaya ini, silakan periksa tes di bawah folder ./tests/unit/global (test suite "global").
Dalam gaya ini, Anda membuat perubahan secara langsung pada kasus uji agar berfungsi secara asinkron.
Untuk kasus uji yang ditulis dengan gaya ini, kita perlu menggunakan kelas DeminyCounitCounit yang sesuai dalam kasus uji di mana kita perlu menunggu eksekusi PHP atau melakukan operasi IO. Biasanya, pemanggilan metode berikut akan digunakan:
Kasus uji tipikal dengan gaya kasus per kasus terlihat seperti ini:
use Deminy Counit Counit ;
use PHPUnit Framework TestCase ;
class SleepTest extends TestCase
{
public function testSleep (): void
{
Counit:: create ( function () { // To create a new coroutine manually to run the test case.
$ startTime = time ();
Counit:: sleep ( 3 ); // Call this method instead of PHP function sleep().
$ endTime = time ();
self :: assertEqualsWithDelta ( 3 , ( $ endTime - $ startTime ), 1 , ' The sleep() function call takes about 3 seconds to finish. ' );
});
}
}
Jika Anda perlu menyembunyikan pesan peringatan "Tes ini tidak melakukan pernyataan apa pun" atau untuk mencocokkan jumlah pernyataan, Anda dapat menyertakan parameter ke-2 saat membuat coroutine baru:
use Deminy Counit Counit ;
use PHPUnit Framework TestCase ;
class SleepTest extends TestCase
{
public function testSleep (): void
{
Counit:: create ( // To create a new coroutine manually to run the test case.
function () {
$ startTime = time ();
Counit:: sleep ( 3 ); // Call this method instead of PHP function sleep().
$ endTime = time ();
self :: assertEqualsWithDelta ( 3 , ( $ endTime - $ startTime ), 1 , ' The sleep() function call takes about 3 seconds to finish. ' );
},
1 // Optional. To suppress warning message "This test did not perform any assertions", and to make the counters match.
);
}
}
Untuk menemukan lebih banyak tes yang ditulis dengan gaya ini, silakan periksa tes di bawah folder ./tests/unit/case-by-case (test suite "case-by-case").
Di sini kita akan menjalankan pengujian di lingkungan yang berbeda, dengan atau tanpa Swoole.
#1
Jalankan rangkaian pengujian menggunakan PHPUnit :
# To run test suite "global":
docker compose exec -ti php ./vendor/bin/phpunit --testsuite global
# or,
docker compose exec -ti swoole ./vendor/bin/phpunit --testsuite global
# To run test suite "case-by-case":
docker compose exec -ti php ./vendor/bin/phpunit --testsuite case-by-case
# or,
docker compose exec -ti swoole ./vendor/bin/phpunit --testsuite case-by-case
#2
Jalankan rangkaian pengujian menggunakan counit (tanpa Swoole):
# To run test suite "global":
docker compose exec -ti php ./counit --testsuite global
# To run test suite "case-by-case":
docker compose exec -ti php ./counit --testsuite case-by-case
#3
Jalankan rangkaian pengujian menggunakan counit (dengan ekstensi Swoole diaktifkan):
# To run test suite "global":
docker compose exec -ti swoole ./counit --testsuite global
# To run test suite "case-by-case":
docker compose exec -ti swoole ./counit --testsuite case-by-case
Dua set perintah pertama membutuhkan waktu yang hampir sama untuk diselesaikan. Kumpulan perintah terakhir menggunakan counit dan berjalan di wadah Swoole (di mana ekstensi Swoole diaktifkan); jadi ini lebih cepat dari yang lain:
Gaya | # Tes | # Pernyataan | Saatnya Selesai | |
---|---|---|---|---|
counit (tanpa Swoole), atau PHPUnit | global | 16 | 24 | 48 detik |
kasus per kasus | 48 detik | |||
counit (dengan Swoole diaktifkan) | global | 7 detik | ||
kasus per kasus | 7 detik |
Karena paket ini memungkinkan menjalankan beberapa pengujian secara bersamaan, kita tidak boleh menggunakan sumber daya yang sama dalam pengujian yang berbeda; jika tidak, kondisi balapan bisa saja terjadi. Misalnya, jika beberapa pengujian menggunakan kunci Redis yang sama, beberapa pengujian terkadang bisa gagal. Dalam hal ini, kita harus menggunakan kunci Redis yang berbeda dalam kasus pengujian yang berbeda. Metode DeminyCounitHelper::getNewKey() dan DeminyCounitHelper::getNewKeys() dapat digunakan untuk menghasilkan kunci pengujian acak dan unik.
Paket ini berfungsi paling baik untuk pengujian yang menggunakan pemanggilan fungsi sleep() ; Menjalankan beberapa pengujian terkait IO dengan lebih cepat juga dapat membantu, dengan batasan yang berlaku. Berikut adalah daftar batasan paket ini:
Ada deminy/counit gambar yang sudah dibuat sebelumnya untuk menjalankan pengujian sampel. Berikut adalah perintah untuk membuat gambar:
docker build -t deminy/counit:php-only -f ./dockerfiles/php/Dockerfile .
docker build -t deminy/counit:swoole-enabled -f ./dockerfiles/swoole/Dockerfile .
Paket ini memungkinkan penggunaan Swoole untuk menjalankan pengujian terkait beberapa waktu/IO tanpa multiprosesing, yang berarti semua pengujian dapat dijalankan dalam satu proses PHP. Untuk memahami cara kerjanya, saya sarankan untuk memeriksa pembicaraan online gratis ini: Pemrograman CSP dalam PHP (dan berikut slidenya).
Dalam ekosistem PHP, terdapat opsi lain untuk menjalankan pengujian unit secara paralel, yang sebagian besar berakhir dengan menggunakan multiprosesor:
lisensi MIT.