12
Pengujian dan CI
Badaso menguji dirinya lewat PHPUnit feature test yang memanggil endpoint API v1 sungguhan, ditambah tiga workflow GitHub Actions untuk PHPUnit, PHPStan, dan ESLint. Seluruh pengujian dijalankan dari sebuah proyek Laravel baru yang memasang badaso/core dari branch yang sedang diuji, sehingga test tidak memakai proses aplikasi host.
Helper CallHelperTest
Semua feature test berdiri di atas satu kelas helper, Uasoft\Badaso\Helpers\CallHelperTest. Helper ini menyimpan token admin di cache file dengan kunci TOKEN_ADMIN_AUTHORIZE, lalu membungkusnya menjadi header Authorization lewat withAuthorizeBearer. src/Helpers/CallHelperTest.php:13-311 dan src/Helpers/CallHelperTest.php:109-1122
Prefix endpoint tidak di-hardcode. getUrlApiV1Prefix membaca config('badaso.api_route_prefix', 'badaso-api') lalu menambahkan '/v1', dan nilai konfigurasi itu sendiri berasal dari VITE_API_ROUTE_PREFIX dengan default badaso-api. src/Helpers/CallHelperTest.php:50-553 dan src/Config/badaso.php:354
| Fungsi | Peran | Rujukan |
|---|---|---|
handleUserAdminAuthorize | Membuat/mengubah user admin, login ke /auth/login, menyimpan token, lalu memverifikasi assertSame terhadap isi cache | src/Helpers/CallHelperTest.php:78-995 |
getUserAdminRole | Membuat User dan UserRole dengan role_id ADMINISTRATOR_ROLE_ID = 1 bila belum ada | src/Helpers/CallHelperTest.php:57-766 |
getDataCreateOrUpdateUserAdmin | Menyusun data user dari env('BADASO_USER_NAME', 'badaso.test') dan Hash::make | src/Helpers/CallHelperTest.php:33-487 |
withAuthorizeBearer | Menempelkan Bearer <token> ke TestCase | src/Helpers/CallHelperTest.php:109-1122 |
setCache / getCache / clearCache | Menyimpan dan mengambil ID antar test lewat cache file | src/Helpers/CallHelperTest.php:114-1278 |
handleDeleteUserAdmin | Menghapus user admin setelah rangkaian test selesai | src/Helpers/CallHelperTest.php:102-1079 |
Siklus satu kelas feature test
Setiap kelas feature test mengikuti pola yang sama: testStartInit menyiapkan token, test berikutnya bekerja dengan Bearer, dan testFinish membersihkan cache serta user admin. Urutan metode penting karena ID yang dibuat di satu test dibaca oleh test berikutnya melalui cache file.
sequenceDiagram
participant T as "BadasoApiRoleTest"
participant H as "CallHelperTest"
participant C as "Cache store file"
participant A as "API v1"
T->>H: handleUserAdminAuthorize(this)
H->>A: POST /auth/login
A-->>H: data.accessToken
H->>C: set TOKEN_ADMIN_AUTHORIZE
H-->>T: assertSame(token, cache)
T->>H: withAuthorizeBearer(this)
H->>C: get TOKEN_ADMIN_AUTHORIZE
T->>A: POST /roles/add + Bearer
A-->>T: data.id
T->>C: setCache ROLE_LAST_CREATE_ID
T->>A: PUT /roles/edit + Bearer
T->>H: clearCache() + handleDeleteUserAdmin()
%% fig: Siklus hidup satu kelas feature test
%% desc: testStartInit menyimpan token admin ke cache, test berikutnya memakai Bearer, lalu testFinish membersihkan cache dan user admin.Angka nyata yang dipakai BadasoApiRoleTest: testDeleteMultipleRole membuat $maximal_count = 10 role tambahan, lalu mengirim ids hasil join(',', $ids) ke /roles/delete-multiple dan memastikan Role::whereIn('id', $ids) berjumlah nol. tests/Feature/BadasoApiRoleTest.php:117-14210
BadasoApiCrudManagementTest memperbesar persiapan itu. testStartInit tidak hanya login, tetapi juga memanggil createTestTables(10) dan createTestEmptyValueTables(10) dengan prefix test_table_ dan test_empty_table_, serta $MAXIMAL_CREATE_ENTITY = 3. tests/Feature/BadasoApiCrudManagementTest.php:19-3011 dan tests/Feature/BadasoApiCrudManagementTest.php:486-49612
Rangkaian test per kelas
| Kelas | test yang dijalankan | Rujukan |
|---|---|---|
BadasoApiRoleTest | testStartInit, testAddRole, testReadRole, testEditRole, testBrowseRole, testDeleteRole, testDeleteMultipleRole, testFinish | tests/Feature/BadasoApiRoleTest.php:1413, tests/Feature/BadasoApiRoleTest.php:2014, tests/Feature/BadasoApiRoleTest.php:144-14915 |
BadasoApiCrudManagementTest | 26 test, dari testStartInit sampai testUploadImageFile, termasuk testRollbackMigration | tests/Feature/BadasoApiCrudManagementTest.php:2443-245116 |
BadasoApiConfigurationTest | testMaintenanceWithoutKey, testMaintenanceWithKeyTrue, testMaintenanceWithKeyFalse | tests/Feature/BadasoApiConfigurationTest.php:15-7617 |
BadasoApiConfigurationTest berbeda karena tidak memakai token. Ketiga test cukup mengubah config(['badaso.badaso_maintenance' => ...]) lalu memanggil POST /maintenance tanpa header otorisasi dan memeriksa data.maintenance. tests/Feature/BadasoApiConfigurationTest.php:15-3418 dan tests/Feature/BadasoApiConfigurationTest.php:36-5519
Berkas phpunit.xml yang dihasilkan badaso-test:setup
badaso-test:setup tidak menjalankan test. Perintah ini menulis phpunit.xml ke base_path('phpunit.xml') lewat file_put_contents. tests diambil dari dua direktori: ./tests/Feature milik proyek dan ./vendor/badaso/core/tests/Feature milik paket. src/Commands/BadasoTestSetup.php:9-2220 dan src/Commands/BadasoTestSetup.php:39-5421
Berkas itu juga mengunci env pengujian: APP_ENV=testing, BCRYPT_ROUNDS=4, CACHE_DRIVER=array, MAIL_MAILER=array, QUEUE_CONNECTION=sync, dan SESSION_DRIVER=array. Blok DB_CONNECTION dan DB_DATABASE sengaja dikomentari sehingga koneksi mengikuti .env proyek. src/Commands/BadasoTestSetup.php:77-8922
Laporan coverage mencakup direktori src tertentu saja, misalnya ./vendor/badaso/core/src/Controllers, ./vendor/badaso/core/src/Helpers, dan ./vendor/badaso/core/src/Models. src/Commands/BadasoTestSetup.php:56-7623
⚠️
CACHE_DRIVER=arraypadaphpunit.xmlbertabrakan dengan pemakaianCache::store('file')diCallHelperTest. Helper selalu menunjuk storefilesecara eksplisit, jadi ID antartesttetap tersimpan, tetapi nilai yang ditulis di luar store itu tidak akan terlihat oleh helper. src/Helpers/CallHelperTest.php:1824 dan src/Commands/BadasoTestSetup.php:8025
Workflow PHPUnit
Workflow PHP Unit berjalan pada push ke master dan pada pull request bertipe synchronize, opened, edited, reopened. .github/workflows/phpunit.yml:1-1226
Matriksnya berisi php: [8.0, 8.1] dan laravel: ["9.*", "10.*"], dengan fail-fast: false. Satu entri include menambahkan php: 8.1, laravel: 9.*, coverage: xdebug untuk jalur coverage. Nama job dibentuk dari PHP ${{ matrix.php }} / Laravel ${{ matrix.laravel }}. .github/workflows/phpunit.yml:38-5327
Selain itu workflow menyediakan service container postgres (image postgres, POSTGRES_DB: laravel, health check pg_isready) dan langkah ankane/setup-mysql@v1 dengan mysql-version: 8.0 serta database: laravel. Jadi satu job menguji dua mesin basis data sekaligus. .github/workflows/phpunit.yml:20-3628 dan .github/workflows/phpunit.yml:59-6329
graph TD
A["checkout"] --> B["Mysql setup"]
B --> C["Select PHP version"]
C --> D["composer create-project laravel"]
D --> E["composer require badaso/core:dev-GITHUB_HEAD_REF"]
E --> F["badaso:setup --force"]
F --> G["badaso-test:setup"]
G --> H["db:wipe + migrate"]
H --> I["db:seed BadasoSeeder"]
I --> J["php artisan test (mysql)"]
J --> K["switch .env ke sqlite"]
K --> L["ulangi setup + migrate + seed"]
L --> M["php artisan test (sqlite)"]
M --> N["switch .env ke pgsql"]
N --> O["ulangi setup + migrate + seed"]
O --> P["php artisan test (pgsql)"]
P --> Q["phpunit --coverage-text + clover"]
Q --> R["codecov upload"]
style A fill:#f59e0b,color:#000
style B fill:#336791,color:#fff
style H fill:#336791,color:#fff
style J fill:#2d7d46,color:#fff
style M fill:#2d7d46,color:#fff
style P fill:#2d7d46,color:#fff
style Q fill:#8b5cf6,color:#fff
style R fill:#8b5cf6,color:#fff
%% fig: Tahap workflow PHP Unit
%% desc: Satu job menyiapkan Laravel, memasang badaso/core dari branch yang diuji, lalu mengulang setup dan migrate untuk MySQL, SQLite, dan PostgreSQL sebelum mengunggah coverage.Langkah pemasangan memakai composer require badaso/core:dev-${GITHUB_HEAD_REF} -W, sehingga test memakai kode dari branch pengirim pull request, bukan rilis. .github/workflows/phpunit.yml:84-8830
Tiga putaran basis data
| Putaran | Perubahan .env | Perintah test | Rujukan |
|---|---|---|---|
| MySQL | tidak ada, memakai setup-mysql | php artisan test | .github/workflows/phpunit.yml:90-10131 |
| SQLite | DB_CONNECTION=sqlite, DB_DATABASE=database/database.sqlite | php artisan test setelah touch database/database.sqlite | .github/workflows/phpunit.yml:103-12132 |
| PostgreSQL | DB_CONNECTION=pgsql, DB_PORT=5432, DB_USERNAME=postgres, DB_PASSWORD=postgres, DB_HOST=localhost | php artisan test | .github/workflows/phpunit.yml:123-14433 |
Setiap putaran mengulang urutan yang sama: php artisan badaso:setup --force, php artisan badaso-test:setup, php artisan db:wipe, php artisan migrate, lalu php artisan db:seed --class="Database\Seeders\Badaso\BadasoSeeder". .github/workflows/phpunit.yml:91-9734
⚠️
php artisan db:wipeberjalan tiga kali dalam satujob, sekali per putaran basis data. Perintah ini menghapus seluruh tabel pada koneksi yang aktif, jadi.envwajib sudah diganti sebelumdb:wipedijalankan, seperti urutansed -iyang mendahului langkah setup SQLite dan PostgreSQL. .github/workflows/phpunit.yml:103-11735
Coverage hanya dijalankan ketika matrix.coverage == 'xdebug', memakai ./vendor/bin/phpunit --coverage-text --coverage-clover='reports/coverage/coverage.xml', lalu diunggah codecov/codecov-action@v2 dengan file: laravel/reports/coverage/coverage.xml dan secrets.CODECOV_TOKEN. .github/workflows/phpunit.yml:146-15736
Workflow PHPStan
Workflow PHP Stan memakai matriks jauh lebih kecil: php: [8.0] dan laravel: ["9.*"] dengan laravel-require: 9.0. Langkahnya sama sampai composer require badaso/core:dev-${GITHUB_HEAD_REF}, lalu hanya php artisan badaso:setup --force tanpa migrate atau seed. .github/workflows/phpstan.yml:19-5837
Analisis dijalankan dari proyek Laravel dengan konfigurasi milik paket:
cd laravel && ./vendor/bin/phpstan analyse -c vendor/badaso/core/phpstan.neon.dist
.github/workflows/phpstan.yml:60-6338
phpstan.neon.dist memakai level: 1, menganalisis src dan tests, serta menyertakan ./phpstan-baseline.neon. phpstan/phpstan sendiri ada di require, bukan require-dev. phpstan.neon.dist:1-839 dan composer.json:3640
Baseline itu mengurangi derau dengan dua cara. excludePaths mengeluarkan src/Config/sanctum.php, sedangkan ignoreErrors memuat pola seperti #Call to an undefined static method ...#, #Call to static method ... on an unknown class ...#, #Access to an undefined property Uasoft\Badaso\Models\MenuItem::\$...#, dan #Instantiated class Database\Seeders\Badaso\Exception not found.#. phpstan-baseline.neon:1-1841
⚠️ Daftar
ignoreErrorsadalah daftar pengecualian yang disengaja. Menambah pola baru berarti menyembunyikan kelas kesalahan tertentu darilevel: 1, jadi pola sebaiknya ditambah hanya setelah penyebabnya dipahami, dan pola lama dihapus ketika masalahnya sudah diperbaiki. phpstan-baseline.neon:5-1842
Workflow ESLint
Workflow Eslint dipicu push ke master, pull request (termasuk ready_for_review dan unlocked), pull_request_review bertipe submitted, check_suite bertipe completed, dan status. Nama job-nya automerge. .github/workflows/eslint.yml:1-2743
Langkahnya: checkout ref: ${{ github.head_ref }}, pasang Node.js 14.x, npm install, npm run lint, npm run format, lalu stefanzweifel/git-auto-commit-action@v4 dengan file_pattern: src/resources/badaso/*.js dan commit_message: Apply lint + prettier changes. .github/workflows/eslint.yml:28-4644
Kedua skrip itu menunjuk direktori aset frontend. lint menjalankan eslint --ext .js,.vue --ignore-path .gitignore --fix ./src/resources/badaso, sedangkan format menjalankan prettier ./src/resources/badaso --write. package.json:105-11045
⚠️ Workflow ESLint tidak hanya memeriksa, tetapi juga menulis ulang berkas dan membuat
commitkembali kebranch. Karena itupull requestdariforkakan gagal pada langkah auto-commit, dan perubahan hasil--fixbisa muncul sebagaicommittambahan dibranchpengirim. .github/workflows/eslint.yml:36-4646
Hubungan dengan halaman lain
test feature memanggil endpoint yang sama dengan yang dipakai aplikasi, sehingga daftar endpoint auth dan role dijelaskan di Autentikasi dan Otorisasi serta Manajemen User, Role, dan Permission. Perintah badaso:setup dan badaso-test:setup yang dijalankan workflow berasal dari alur pemasangan di Instalasi dan Setup. Berkas src yang dianalisis PHPStan adalah kode yang dijelaskan di Arsitektur Sistem, sedangkan berkas JavaScript yang dirapikan ESLint berada di Frontend Admin Panel.