14 KiB
Test Plan
Taiwan NPO Membership Management System
Last Updated: 2025-11-20 Laravel Version: 11 Testing Framework: PHPUnit 10.x
Table of Contents
- Testing Strategy
- Test Environment Setup
- Test Coverage Matrix
- Unit Tests
- Feature Tests
- Running Tests
- Test Data
- Expected Results
1. Testing Strategy
1.1 Testing Pyramid
/\
/ \
/ E2E\ (Future)
/______\
/ \
/ Feature \
/____________\
/ \
/ Unit Tests \
/__________________\
Current Focus:
- ✅ Unit Tests - Test individual model methods and business logic
- ✅ Feature Tests - Test complete HTTP request/response cycles
- 🟡 E2E Tests - Browser tests with Dusk (future enhancement)
1.2 Test Types
| Test Type | Purpose | Tools | Coverage Target |
|---|---|---|---|
| Unit | Test model methods, calculations, business logic | PHPUnit | 80%+ |
| Feature | Test controllers, workflows, integrations | PHPUnit, RefreshDatabase | 70%+ |
| Test email content and delivery | PHPUnit, Mail::fake() | 100% | |
| Authorization | Test permissions and middleware | PHPUnit | 100% |
| Database | Test relationships and migrations | PHPUnit, DatabaseMigrations | 100% |
1.3 Testing Principles
- Isolation: Each test is independent
- Repeatability: Tests produce same results every time
- Speed: Unit tests < 100ms, Feature tests < 500ms
- Clarity: Clear test names describing what is tested
- Coverage: All critical paths tested
2. Test Environment Setup
2.1 Test Database Configuration
File: phpunit.xml
<env name="APP_ENV" value="testing"/>
<env name="DB_CONNECTION" value="sqlite"/>
<env name="DB_DATABASE" value=":memory:"/>
<env name="QUEUE_CONNECTION" value="sync"/>
<env name="MAIL_MAILER" value="array"/>
<env name="CACHE_DRIVER" value="array"/>
<env name="SESSION_DRIVER" value="array"/>
2.2 Test Traits Used
RefreshDatabase- Migrates and seeds database for each testWithFaker- Provides Faker instance for generating test dataWithoutMiddleware- Disables middleware (use sparingly)
2.3 Setup Commands
# Install dependencies
composer install
# Copy environment file
cp .env.example .env.testing
# Generate application key
php artisan key:generate --env=testing
# Run migrations
php artisan migrate --env=testing
# Run seeders
php artisan db:seed --env=testing
# Run tests
php artisan test
3. Test Coverage Matrix
3.1 Model Coverage
| Model | Unit Test File | Tests | Priority |
|---|---|---|---|
| Member | tests/Unit/MemberTest.php | 15 | High |
| MembershipPayment | tests/Unit/MembershipPaymentTest.php | 12 | High |
| Issue | tests/Unit/IssueTest.php | 18 | High |
| Budget | tests/Unit/BudgetTest.php | 10 | Medium |
| BudgetItem | tests/Unit/BudgetTest.php | 8 | Medium |
| FinanceDocument | tests/Unit/FinanceDocumentTest.php | 8 | Medium |
| Transaction | tests/Unit/TransactionTest.php | 6 | Low |
3.2 Feature Coverage
| Feature | Feature Test File | Tests | Priority |
|---|---|---|---|
| Member Registration | tests/Feature/MemberRegistrationTest.php | 8 | High |
| Payment Verification | tests/Feature/PaymentVerificationTest.php | 15 | High |
| Finance Documents | tests/Feature/FinanceDocumentTest.php | 10 | High |
| Issue Tracking | tests/Feature/IssueTrackingTest.php | 20 | High |
| Budget Management | tests/Feature/BudgetManagementTest.php | 12 | Medium |
| Authorization | tests/Feature/AuthorizationTest.php | 15 | High |
| Emails | tests/Feature/EmailTest.php | 19 | High |
3.3 Coverage Goals
| Category | Target | Current |
|---|---|---|
| Overall Code Coverage | 75% | TBD |
| Model Coverage | 85% | TBD |
| Controller Coverage | 70% | TBD |
| Critical Paths | 100% | TBD |
4. Unit Tests
4.1 MemberTest.php
File: tests/Unit/MemberTest.php
Tests:
- ✅ Member has required fillable fields
- ✅ Member belongs to user
- ✅ Member has many payments
- ✅ hasPaidMembership() returns true when active with future expiry
- ✅ hasPaidMembership() returns false when pending
- ✅ hasPaidMembership() returns false when expired
- ✅ canSubmitPayment() returns true when pending and no pending payment
- ✅ canSubmitPayment() returns false when already has pending payment
- ✅ getPendingPayment() returns pending payment
- ✅ National ID encryption works
- ✅ National ID hashing works for search
- ✅ Status check methods work (isPending, isActive, isExpired, isSuspended)
- ✅ Status label returns correct Chinese text
- ✅ Type label returns correct Chinese text
- ✅ Status badge returns correct CSS class
4.2 MembershipPaymentTest.php
File: tests/Unit/MembershipPaymentTest.php
Tests:
- ✅ Payment belongs to member
- ✅ Payment belongs to submittedBy user
- ✅ Payment has verifier relationships (cashier, accountant, chair)
- ✅ Status check methods work (isPending, isApprovedByCashier, etc.)
- ✅ canBeApprovedByCashier() validates correctly
- ✅ canBeApprovedByAccountant() validates correctly
- ✅ canBeApprovedByChair() validates correctly
- ✅ Status label returns Chinese text
- ✅ Payment method label returns Chinese text
- ✅ Receipt file cleanup on deletion
- ✅ Workflow validation prevents skipping tiers
- ✅ Rejection tracking works
4.3 IssueTest.php
File: tests/Unit/IssueTest.php
Tests:
- ✅ Issue number auto-generation (ISS-YYYY-NNN)
- ✅ Issue belongs to creator, assignee, reviewer
- ✅ Issue has many comments, attachments, time logs
- ✅ Issue has many labels (many-to-many)
- ✅ Issue has many watchers (many-to-many)
- ✅ Status check methods work
- ✅ Workflow validation methods work
- ✅ Progress percentage calculation
- ✅ Overdue detection works
- ✅ Days until due calculation
- ✅ Total time logged calculation
- ✅ Status label returns correct text
- ✅ Priority label returns correct text
- ✅ Badge color methods work
- ✅ Scopes work (open, closed, overdue, byStatus, byPriority)
- ✅ Parent-child relationships work
- ✅ Can't skip workflow statuses
- ✅ Can reopen closed issues
4.4 BudgetTest.php
File: tests/Unit/BudgetTest.php
Tests:
- ✅ Budget belongs to createdBy and approvedBy
- ✅ Budget has many budget items
- ✅ Status check methods work
- ✅ Workflow validation methods work
- ✅ Total budgeted income calculation
- ✅ Total budgeted expense calculation
- ✅ Total actual income calculation
- ✅ Total actual expense calculation
- ✅ Budget item variance calculation
- ✅ Budget item over-budget detection
5. Feature Tests
5.1 MemberRegistrationTest.php
File: tests/Feature/MemberRegistrationTest.php
Tests:
- ✅ Public registration form is accessible
- ✅ Can register with valid data
- ✅ User and Member records created
- ✅ User is auto-logged in
- ✅ Welcome email is sent
- ✅ Validation fails with invalid email
- ✅ Validation fails with duplicate email
- ✅ Password confirmation required
5.2 PaymentVerificationTest.php
File: tests/Feature/PaymentVerificationTest.php
Tests:
- ✅ Member can submit payment with receipt
- ✅ Receipt is stored in private storage
- ✅ Payment starts with pending status
- ✅ Submission emails sent to member and cashiers
- ✅ Cashier can approve (Tier 1)
- ✅ Cashier approval sends email to accountants
- ✅ Accountant can approve (Tier 2)
- ✅ Accountant approval sends email to chairs
- ✅ Chair can approve (Tier 3)
- ✅ Chair approval activates membership automatically
- ✅ Activation email sent to member
- ✅ Cannot skip tiers (accountant can't approve pending)
- ✅ Can reject at any tier with reason
- ✅ Rejection email sent with reason
- ✅ Dashboard shows correct queues based on permissions
5.3 FinanceDocumentTest.php
File: tests/Feature/FinanceDocumentTest.php
Tests:
- ✅ Can create finance document
- ✅ Can attach file to document
- ✅ 3-tier approval workflow works
- ✅ Rejection workflow works
- ✅ Emails sent at each stage
- ✅ Cannot skip approval tiers
- ✅ Can download attachment
- ✅ Audit log created for each action
- ✅ Permissions enforced
- ✅ Validation rules work
5.4 IssueTrackingTest.php
File: tests/Feature/IssueTrackingTest.php
Tests:
- ✅ Can create issue
- ✅ Issue number auto-generated
- ✅ Can assign issue to user
- ✅ Assignment email sent
- ✅ Can update status
- ✅ Status change email sent
- ✅ Can add comments
- ✅ Comment email sent
- ✅ Can upload attachments
- ✅ Can download attachments
- ✅ Can delete attachments
- ✅ Can log time
- ✅ Total time calculated correctly
- ✅ Can add watchers
- ✅ Watchers receive notifications
- ✅ Can add labels
- ✅ Can filter by labels
- ✅ Can create sub-tasks
- ✅ Workflow validation works
- ✅ Overdue detection works
5.5 BudgetManagementTest.php
File: tests/Feature/BudgetManagementTest.php
Tests:
- ✅ Can create budget
- ✅ Can add budget items
- ✅ Can submit for approval
- ✅ Can approve budget
- ✅ Can activate budget
- ✅ Can close budget
- ✅ Workflow validation works
- ✅ Transactions update actual amounts
- ✅ Variance calculations work
- ✅ Can link transactions to budget items
- ✅ Over-budget alerts work
- ✅ Permissions enforced
5.6 AuthorizationTest.php
File: tests/Feature/AuthorizationTest.php
Tests:
- ✅ Admin middleware works
- ✅ Paid membership middleware works
- ✅ Cashier permission enforced
- ✅ Accountant permission enforced
- ✅ Chair permission enforced
- ✅ Membership manager permission enforced
- ✅ Unauthorized users get 403
- ✅ Role assignment works
- ✅ Permission inheritance works
- ✅ Admin role has all permissions
- ✅ Members cannot access admin routes
- ✅ Unpaid members cannot access paid resources
- ✅ Suspended members redirected
- ✅ Expired members redirected
- ✅ Guest users redirected to login
5.7 EmailTest.php
File: tests/Feature/EmailTest.php
Tests:
- ✅ MemberRegistrationWelcomeMail content
- ✅ PaymentSubmittedMail (member variant)
- ✅ PaymentSubmittedMail (cashier variant)
- ✅ PaymentApprovedByCashierMail
- ✅ PaymentApprovedByAccountantMail
- ✅ PaymentFullyApprovedMail
- ✅ PaymentRejectedMail
- ✅ MembershipActivatedMail
- ✅ FinanceDocumentSubmitted
- ✅ FinanceDocumentApproved*
- ✅ FinanceDocumentRejected
- ✅ IssueAssignedMail
- ✅ IssueStatusChangedMail
- ✅ IssueCommentedMail
- ✅ IssueDueSoonMail
- ✅ IssueOverdueMail
- ✅ IssueClosedMail
- ✅ All emails queued correctly
- ✅ Email recipients correct
6. Running Tests
6.1 Run All Tests
php artisan test
6.2 Run Specific Test Suite
# Unit tests only
php artisan test --testsuite=Unit
# Feature tests only
php artisan test --testsuite=Feature
# Specific test file
php artisan test tests/Unit/MemberTest.php
# Specific test method
php artisan test --filter=test_member_can_submit_payment
6.3 Run with Coverage
php artisan test --coverage
# Minimum coverage threshold
php artisan test --coverage --min=75
6.4 Parallel Testing
php artisan test --parallel
7. Test Data
7.1 TestDataSeeder.php
File: database/seeders/TestDataSeeder.php
Creates comprehensive test data:
- 5 test users with different roles
- 20 members in various states (pending, active, expired, suspended)
- 30 payments at different approval stages
- 15 issues with various statuses
- 5 budgets with items
- 10 finance documents
- Sample transactions
7.2 Using Test Data
# Seed test data
php artisan db:seed --class=TestDataSeeder --env=testing
# Reset and seed
php artisan migrate:fresh --seed --class=TestDataSeeder --env=testing
8. Expected Results
8.1 Success Criteria
All tests pass with:
- ✅ No failures
- ✅ No errors
- ✅ No warnings
- ✅ Coverage > 75%
8.2 Test Execution Time
| Test Suite | Expected Time | Acceptable Max |
|---|---|---|
| Unit Tests | < 5 seconds | 10 seconds |
| Feature Tests | < 30 seconds | 60 seconds |
| All Tests | < 40 seconds | 90 seconds |
8.3 CI/CD Integration
Tests should run automatically on:
- Every commit (via GitHub Actions)
- Every pull request
- Before deployment
Sample GitHub Actions:
name: Tests
on: [push, pull_request]
jobs:
tests:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Install Dependencies
run: composer install
- name: Run Tests
run: php artisan test --coverage --min=75
9. Testing Checklist
Before marking feature as complete:
- Unit tests written for all model methods
- Feature tests written for all controller actions
- Email tests verify content and recipients
- Authorization tests verify permissions
- All tests pass
- Coverage meets minimum threshold (75%)
- No skipped or incomplete tests
- Test data seeder updated
- Documentation updated
- Edge cases tested
- Error conditions tested
10. Test Maintenance
10.1 When to Update Tests
- Feature changes
- Bug fixes
- New requirements
- Security updates
10.2 Refactoring Tests
Keep tests DRY (Don't Repeat Yourself):
- Use setUp() for common initialization
- Create test helper methods
- Use factories for model creation
- Share fixtures across tests
End of Test Plan