PHP Academy · Pelajaran

Ujian Integrasi dan Fungsian

Uji cara komponen berfungsi bersama dalam keadaan sebenar.

Pelajaran 3 daripada 413 langkah

Ujian Integrasi dan Fungsian ialah pelajaran PHP Academy percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran PHP Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus PHP Academy merangkumi sejumlah 4 pelajaran.

Melangkaui Unit

Ujian unit membuktikan sesuatu kelas berfungsi secara berasingan dengan semua kebergantungannya diolokkan. Namun, objek olokan boleh mengelirukan — pangkalan data sebenar, penghala rangka kerja atau lapisan HTTP berkelakuan berbeza. Ujian integrasi mengesahkan dua atau lebih komponen sebenar yang disepadukan bersama; ujian fungsi menguji aplikasi dari hujung ke hujung melalui titik masuk awamnya (permintaan HTTP, perintah konsol). Dalam pelajaran ini, kedua-duanya diterangkan kedudukannya dan ditulis.

Piramid Ujian

Set ujian yang sihat berbentuk seperti piramid:

  • Banyak ujian unit — pantas, terasing, dijalankan sentiasa.
  • Lebih sedikit ujian integrasi — pangkalan data, baris gilir dan cache sebenar, tetapi lebih perlahan.
  • Sedikit ujian fungsi/ujung ke hujung — keseluruhan tindanan, paling perlahan dan paling rapuh.

Menterbalikkan susunan ini (menjadikannya 'kon ais krim' yang kebanyakannya terdiri daripada ujian ujung ke hujung) menghasilkan set ujian yang perlahan dan tidak stabil. Utamakan liputan pada lapisan bawah apabila boleh.

Integrasi: Repositori terhadap Pangkalan Data Sebenar

Ujian integrasi untuk repositori menggunakan sambungan pangkalan data sebenar — bukan olokan — untuk mengesan pepijat SQL, skema dan pemetaan. Gunakan pangkalan data ujian khusus (atau SQLite dalam memori yang cukup sepadan dengan dialek anda) dan PDO sebenar.

<?php
use PHPUnit\Framework\TestCase;

final class UserRepositoryTest extends TestCase
{
    private \PDO $pdo;

    protected function setUp(): void
    {
        $this->pdo = new \PDO('sqlite::memory:');
        $this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
        $this->pdo->exec('CREATE TABLE users (id INTEGER PRIMARY KEY, email TEXT)');
    }

    public function test_persists_and_finds_a_user(): void
    {
        $repo = new UserRepository($this->pdo);
        $id = $repo->create('ada@example.com');
        self::assertSame('ada@example.com', $repo->find($id)->email);
    }
}

Pengasingan: Pengembalian Transaksi

Ujian integrasi tidak boleh membocorkan keadaan kepada satu sama lain. Corak terpantas ialah membungkus setiap ujian dalam transaksi dan mengembalikannya dalam tearDown() — pangkalan data kembali kepada keadaan bersih tanpa perlu diisi semula. (Pemotongan ialah pilihan sandaran apabila kod yang diuji mengesahkan transaksi atau menggunakan DDL.)

<?php
protected function setUp(): void
{
    $this->pdo = TestDb::connection();
    $this->pdo->beginTransaction();
}

protected function tearDown(): void
{
    $this->pdo->rollBack();   // undo everything this test did
}

Data Ujian dan Kilang

Ujian memerlukan data. Elakkan longgokan SQL gergasi yang rapuh; utamakan kilang kecil yang hanya membina baris yang diperlukan oleh sesuatu ujian, dengan nilai lalai yang munasabah dan boleh digantikan bagi setiap kes. Ini menjadikan tujuan setiap ujian jelas dan tahan terhadap pertumbuhan skema.

<?php
final class UserFactory
{
    public static function create(\PDO $pdo, array $overrides = []): int
    {
        $data = array_merge(['email' => 'user'.uniqid().'@test.dev'], $overrides);
        $stmt = $pdo->prepare('INSERT INTO users (email) VALUES (:email)');
        $stmt->execute($data);
        return (int) $pdo->lastInsertId();
    }
}

Fungsi: Mengakses Aplikasi Seperti Klien

Ujian fungsi memacu kernel atau penghala aplikasi sebenar dengan permintaan simulasi dan membuat penegasan terhadap respons — kod status, pengepala dan isi. WebTestCase Symfony serta pembantu ujian HTTP Laravel melakukan perkara ini tanpa memulakan pelayan web sebenar. Berikut ialah bentuk Symfony.

<?php
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

final class HealthControllerTest extends WebTestCase
{
    public function test_health_endpoint_returns_ok(): void
    {
        $client = static::createClient();
        $client->request('GET', '/health');

        self::assertResponseIsSuccessful();        // 2xx
        self::assertJson($client->getResponse()->getContent());
    }
}

Membuat Penegasan pada Respons

Ujian fungsi membuat penegasan terhadap tingkah laku yang boleh diperhatikan pada sempadan: status, bentuk JSON dan kesan sampingan dalam pangkalan data. Di bawah, POST mencipta sumber; kita menyemak kedua-dua respons HTTP dan bahawa rekod itu benar-benar disimpan — membuktikan seluruh tindanan bekerjasama.

<?php
public function test_creating_a_user_persists_it(): void
{
    $client = static::createClient();
    $client->request('POST', '/users', server: [
        'CONTENT_TYPE' => 'application/json',
    ], content: json_encode(['email' => 'ada@example.com']));

    self::assertResponseStatusCodeSame(201);

    $repo = static::getContainer()->get(UserRepository::class);
    self::assertNotNull($repo->findByEmail('ada@example.com'));
}

Memalsukan Hujung Secara Terpilih

Malah ujian fungsi tidak seharusnya memanggil penyedia pembayaran sebenar atau menghantar e-mel sebenar. Gantikan hanya perkhidmatan luaran yang paling luar — tukarkannya dalam bekas ujian kepada pelaksanaan olokan atau dalam memori — sambil mengekalkan kod, penghalaan dan pangkalan data sendiri sebagai komponen sebenar. Ini mengekalkan kesetiaan ujung ke hujung tanpa panggilan rangkaian yang tidak stabil.

<?php
public function test_checkout_charges_via_gateway(): void
{
    $client = static::createClient();
    // Replace the real gateway binding with an in-memory fake:
    static::getContainer()->set(PaymentGateway::class, new FakePaymentGateway());

    $client->request('POST', '/checkout', content: json_encode(['cart' => 1]));
    self::assertResponseIsSuccessful();
}

Set Ujian Berasingan, Kelajuan Berasingan

Pisahkan phpunit.xml anda kepada beberapa set ujian supaya set ujian unit yang pantas dijalankan setiap kali disimpan, manakala set ujian integrasi atau fungsi yang perlahan dijalankan apabila diperlukan atau dalam CI. Kumpulkan mengikut direktori dan pilih dengan --testsuite.

<phpunit>
  <testsuites>
    <testsuite name="unit">
      <directory>tests/Unit</directory>
    </testsuite>
    <testsuite name="integration">
      <directory>tests/Integration</directory>
    </testsuite>
    <testsuite name="functional">
      <directory>tests/Functional</directory>
    </testsuite>
  </testsuites>
</phpunit>

Konsistensi Mengatasi Liputan

Cara terpantas untuk menghilangkan kepercayaan terhadap sesuatu set ujian ialah ketidakstabilan. Jadikan ujian integrasi atau fungsi konsisten:

  • Bekukan masa (suntik jam) dan bukannya memanggil time().
  • Tetapkan benih rawak; elakkan penegasan yang bergantung pada susunan untuk pertanyaan yang tidak diisih.
  • Tetapkan semula keadaan pangkalan data pada setiap ujian (pengembalian transaksi atau pemotongan).
  • Jangan sekali-kali bergantung pada susunan pelaksanaan ujian.

Padankan Pangkalan Data Ujian dengan Produksi

SQLite dalam memori memang pantas, tetapi perbezaan dialek (kepekaan huruf besar-kecil, fungsi JSON, penguatkuasaan kunci asing dan jenis data) boleh menyembunyikan pepijat yang hanya muncul pada enjin sebenar. Bagi kod yang menggunakan SQL khusus enjin, jalankan ujian integrasi terhadap enjin yang sama seperti produksi — lazimnya dalam bekas Docker sementara dalam CI — dan bukannya pengganti mudah yang lebih selesa.

<?php
// Read connection from environment so CI points at a real Postgres/MySQL container
$dsn = getenv('TEST_DATABASE_URL') ?: 'sqlite::memory:';
$pdo = new \PDO($dsn);
$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
// In CI, TEST_DATABASE_URL targets the same engine as production.

Semakan Pantas

Bagaimanakah ujian fungsi harus mengendalikan penyedia pembayaran pihak ketiga?

Ringkasan

Anda telah belajar menguji komponen bersama:

  • Ujian integrasi menggunakan pangkalan data atau perkhidmatan sebenar untuk mengesan perkara yang disembunyikan oleh olokan; asingkannya dengan pengembalian transaksi.
  • Ujian fungsi memacu kernel sebenar melalui permintaan simulasi dan membuat penegasan terhadap respons serta kesan sampingan.
  • Kilang membina data minimum; hanya palsukan sempadan luaran yang paling luar.
  • Asingkan set ujian mengikut kelajuan dan pastikan ujian yang lebih perlahan kekal konsisten.

Seterusnya: mengukur kualiti ujian dengan ujian mutasi.

Percuma untuk bermula

Pelajari PHP dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
49
Pelajaran
195

Soalan Lazim

Adakah pelajaran “Ujian Integrasi dan Fungsian” percuma?

Ya — teks penuh “Ujian Integrasi dan Fungsian” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus PHP Academy, tingkat taraf kepada CoddyKit PRO. Kursus PHP Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Ujian Integrasi dan Fungsian”?

Uji cara komponen berfungsi bersama dalam keadaan sebenar. Anda berlatih PHP Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan PHP Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran PHP Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “Ujian Integrasi dan Fungsian” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran PHP Academy ini?

Ya. Setiap pelajaran PHP Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Aliran Kerja Pembangunan Dipacu Ujian
  2. Penciptaan Mock dan Stub dengan Mockery
  3. Ujian Integrasi dan Fungsian
  4. Ujian Mutasi dengan Infection
← Kembali ke PHP Academy