11 KiB
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 foundapplication/**/*.spec.php-- None foundtests/directory -- Does not exist at project rootphpunit.xml-- Only exists atthinkphp/phpunit.xml(framework's own test suite).idea/phpunit.xml-- IDE config pointing tothinkphp/phpunit.xml(for framework testing only)
Framework PHPUnit Config (thinkphp/phpunit.xml):
<phpunit backupGlobals="false"
backupStaticAttributes="false"
bootstrap="tests/mock.php"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
processIsolation="false"
stopOnFailure="false"
syntaxCheck="false">
<testsuites>
<testsuite name="ThinkPHP Test Suite">
<directory>./tests/thinkphp/</directory>
</testsuite>
</testsuites>
<listeners>
<listener class="JohnKary\PHPUnit\Listener\SpeedTrapListener" />
</listeners>
<filter>
<whitelist>
<directory suffix=".php">./</directory>
<exclude>
<directory suffix=".php">tests</directory>
<directory suffix=".php">vendor</directory>
</exclude>
</whitelist>
</filter>
</phpunit>
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 testsvendor/easywechat-composer/easywechat-composer/tests/-- Composer plugin testsvendor/pimple/pimple/.github/workflows/tests.yml-- CI configvendor/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 managementthink\Cookie-- Cookie operationsthink\Hook-- Event/hook systemthink\Lang-- Language/translationthink\Loader-- Class autoloadingthink\View-- Template renderingfast\Tree-- Tree data structure\app\common\library\Auth-- Authentication singleton\app\admin\library\Auth-- Admin authentication singletonGuzzleHttp\Client-- HTTP client (used inapplication/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, orphpstan.neonfiles
Linting:
- No ESLint, Prettier, or stylelint for frontend code
package.jsonexists 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.phpfor asset minificationapplication/admin/command/Crud.phpfor code generationapplication/admin/command/Api.phpfor API documentation generationapplication/admin/command/Menu.phpfor menu generationapplication/admin/command/Install.phpfor 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
- FastAdmin Nature -- This is a rapid development admin scaffold. FastAdmin projects prioritize speed over test coverage by design.
- No
require-dev--composer.jsonhas no testing-related dev dependencies (no PHPUnit, Mockery, etc.) - No
scripts.test--composer.jsondefines no test scripts - No CI/CD -- No continuous integration pipeline to enforce test execution
- Tight Coupling -- Heavy reliance on ThinkPHP singletons and static methods makes unit testing difficult without significant refactoring
- 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:
"require-dev": {
"phpunit/phpunit": "^9.6",
"mockery/mockery": "^1.6"
}
Step 2: Create phpunit.xml at project root:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit bootstrap="tests/bootstrap.php"
colors="true"
stopOnFailure="false">
<testsuites>
<testsuite name="Application Test Suite">
<directory>./tests/</directory>
</testsuite>
</testsuites>
<php>
<env name="APP_ENV" value="testing"/>
</php>
</phpunit>
Step 3: Create tests/bootstrap.php:
<?php
// Load ThinkPHP bootstrap
define('APP_PATH', __DIR__ . '/../application/');
define('ROOT_PATH', __DIR__ . '/../');
define('RUNTIME_PATH', ROOT_PATH . 'runtime/');
require __DIR__ . '/../thinkphp/base.php';
// Set testing config
\think\Config::set('app_debug', false);
Step 4: Add composer script:
"scripts": {
"test": "phpunit"
}
Run Commands (after setup):
composer install --dev # Install dev dependencies
vendor/bin/phpunit # Run all tests
vendor/bin/phpunit --coverage-html coverage/ # Generate coverage report
composer test # Run via composer script
Testing Challenges Specific to This Codebase
- Singleton Auth --
Auth::instance()is called directly throughout, requiring careful mock setup or refactoring to dependency injection - Static Db Calls --
Db::name(),Db::query(),Db::startTrans()used everywhere instead of injected connections - Global Functions --
__(),cdnurl(), etc. depend on ThinkPHP runtime being bootstrapped - Request Context -- Controllers depend on
$this->requestpopulated by framework routing - Session/Cookie -- Many operations depend on session/cookie state
- Config Dependency -- Heavy use of
Config::get()makes isolation testing difficult - View Rendering -- Some tests would need to verify HTML output from templates
Testing analysis: 2026-04-21