# Testing Patterns **Analysis Date:** 2026-04-21 ## Test Framework **Runner:** - PHPUnit exists in the project only as part of the ThinkPHP framework (`thinkphp/phpunit.xml`) - No project-level test runner configured **Assertion Library:** - PHPUnit's built-in assertions (only in framework's own tests) **No Project Tests Exist.** After thorough exploration of the entire codebase: - `application/**/*.test.php` -- None found - `application/**/*.spec.php` -- None found - `tests/` directory -- Does not exist at project root - `phpunit.xml` -- Only exists at `thinkphp/phpunit.xml` (framework's own test suite) - `.idea/phpunit.xml` -- IDE config pointing to `thinkphp/phpunit.xml` (for framework testing only) **Framework PHPUnit Config (`thinkphp/phpunit.xml`):** ```xml ./tests/thinkphp/ ./ tests vendor ``` This config is for testing the ThinkPHP framework itself, NOT the application code in `application/`. **ThinkPHP Framework Tests (not application code):** - `thinkphp/tests/` contains ~50 test files testing framework internals - Covers: Cache, Config, Controller, DB, Debug, Exception, Hook, Lang, Loader, Log, Model, Paginate, Request, Response, Route, Session, Template, URL, Validate, View - Example: `thinkphp/tests/thinkphp/library/think/validateTest.php` **Vendor Tests (not application code):** - `vendor/overtrue/socialite/tests/` -- OAuth provider tests - `vendor/easywechat-composer/easywechat-composer/tests/` -- Composer plugin tests - `vendor/pimple/pimple/.github/workflows/tests.yml` -- CI config - `vendor/phpoffice/phpspreadsheet/` -- No test files included in dist ## Test File Organization **Current State:** No test files exist for application code. **Recommended Structure (if tests were to be added):** ``` tests/ ├── bootstrap.php ├── admin/ │ ├── controller/ │ │ └── UserTest.php │ ├── library/ │ │ └── AuthTest.php │ └── validate/ │ └── UserTest.php ├── common/ │ ├── controller/ │ ├── library/ │ │ ├── AuthTest.php │ │ └── UploadTest.php │ └── model/ │ └── UserTest.php ├── api/ │ └── controller/ │ └── UserTest.php ├── extend/ │ └── fast/ │ └── RandomTest.php ├── fixtures/ │ └── database/ └── TestCase.php ``` ## Mocking **No mocking framework in use.** **Dependencies that would need mocking for testing:** - `think\Db` -- Database operations (query, startTrans, commit, rollback, name, table) - `think\Config` -- Configuration access (`Config::get()`, `Config::set()`) - `think\Request` -- HTTP request (`$this->request->post()`, `$this->request->isAjax()`) - `think\Session` -- Session management - `think\Cookie` -- Cookie operations - `think\Hook` -- Event/hook system - `think\Lang` -- Language/translation - `think\Loader` -- Class autoloading - `think\View` -- Template rendering - `fast\Tree` -- Tree data structure - `\app\common\library\Auth` -- Authentication singleton - `\app\admin\library\Auth` -- Admin authentication singleton - `GuzzleHttp\Client` -- HTTP client (used in `application/index/controller/Index.php`) **Mocking Challenge:** The codebase relies heavily on ThinkPHP's singleton pattern (`Auth::instance()`) and static methods (`Db::name()`, `Config::get()`), making unit testing difficult without significant refactoring or a dedicated mocking framework like Mockery. ## Fixtures and Factories **Current State:** No test fixtures or factories exist. **Database fixtures would be needed for:** - User records (admin users, regular users) - Auth groups and rules - Categories and attachments - Config entries ## Coverage **Current Coverage: 0%** -- No test coverage for any application code. **Untested Modules (by priority):** **High Priority (core business logic):** | Module | File | Functionality | |--------|------|---------------| | Common Auth | `application/common/library/Auth.php` | User registration, login, token management, password encryption, email/mobile verification | | Admin Auth | `application/admin/library/Auth.php` | Admin authentication, permission checking, breadcrumb generation | | Backend Trait | `application/admin/library/traits/Backend.php` | CRUD operations: index, add, edit, del, multi, import, recyclebin, destroy, restore | | Backend Controller | `application/common/controller/Backend.php` | `buildparams()` query building, `selectpage()` dropdown, data limit enforcement | | Upload | `application/common/library/Upload.php` | File upload, validation, chunked upload, image processing | | Token | `application/common/library/Token.php` | Token CRUD (MySQL/Redis drivers) | | Security | `application/common/library/Security.php` | XSS cleaning, input sanitization | **Medium Priority (data operations):** | Module | File | Functionality | |--------|------|---------------| | User Model (common) | `application/common/model/User.php` | Money/score change logging, level calculation, avatar generation | | User Model (admin) | `application/admin/model/User.php` | Password hashing on change, money/score audit logging | | MoneyLog | `application/common/model/MoneyLog.php` | Financial transaction logging | | ScoreLog | `application/common/model/ScoreLog.php` | Score transaction logging | | User Controller | `application/admin/controller/user/User.php` | User management with avatar processing | | Command Controller | `application/admin/controller/Command.php` | Online command generation and execution | | Validators | `application/admin/validate/*.php` | Data validation rules for all entities | **Low Priority (utilities):** | Module | File | |--------|------| | Global Helpers | `application/common.php` (20+ functions) | | Admin Helpers | `application/admin/common.php` | | Random | `extend/fast/Random.php` | | Date | `extend/fast/Date.php` | | Tree | `extend/fast/Tree.php` | | Rsa | `extend/fast/Rsa.php` | | Form | `extend/fast/Form.php` | | Http | `extend/fast/Http.php` | ## Code Quality Tools **Static Analysis:** - No PHPStan, Psalm, or PHPMD configured at project level - PhpStorm `.idea/` directory contains transferred (inactive) configurations for PHPCS, PHPStan, and MessDetector - No `.php-cs-fixer.php`, `phpcs.xml`, `phpmd.xml`, or `phpstan.neon` files **Linting:** - No ESLint, Prettier, or stylelint for frontend code - `package.json` exists with Grunt build tasks only (minification, no linting) **CI/CD:** - No `.github/` directory (no GitHub Actions) - No `.gitlab-ci.yml` - No `Jenkinsfile` - No `.travis.yml` - No CI pipeline of any kind **Build Tools:** - Grunt for CSS/JS minification (`public/assets/js/*.min.js`, `public/assets/css/*.min.css`) - `application/admin/command/Min.php` for asset minification - `application/admin/command/Crud.php` for code generation - `application/admin/command/Api.php` for API documentation generation - `application/admin/command/Menu.php` for menu generation - `application/admin/command/Install.php` for installation **Composer Scripts:** None defined in `composer.json` ## Test Types **Unit Tests:** Not used. No unit test files exist for any application code. **Integration Tests:** Not used. No integration tests exist. **E2E Tests:** Not used. No end-to-end testing framework (Selenium, Cypress, etc.) configured. **Feature Tests:** Not used. ## Why No Tests 1. **FastAdmin Nature** -- This is a rapid development admin scaffold. FastAdmin projects prioritize speed over test coverage by design. 2. **No `require-dev`** -- `composer.json` has no testing-related dev dependencies (no PHPUnit, Mockery, etc.) 3. **No `scripts.test`** -- `composer.json` defines no test scripts 4. **No CI/CD** -- No continuous integration pipeline to enforce test execution 5. **Tight Coupling** -- Heavy reliance on ThinkPHP singletons and static methods makes unit testing difficult without significant refactoring 6. **Framework Philosophy** -- ThinkPHP 5.x ecosystem does not emphasize testing as a first-class concern ## Adding Tests: Recommended Setup **Step 1: Add dev dependencies to `composer.json`:** ```json "require-dev": { "phpunit/phpunit": "^9.6", "mockery/mockery": "^1.6" } ``` **Step 2: Create `phpunit.xml` at project root:** ```xml ./tests/ ``` **Step 3: Create `tests/bootstrap.php`:** ```php request` populated by framework routing 5. **Session/Cookie** -- Many operations depend on session/cookie state 6. **Config Dependency** -- Heavy use of `Config::get()` makes isolation testing difficult 7. **View Rendering** -- Some tests would need to verify HTML output from templates --- *Testing analysis: 2026-04-21*