Unit Testing

Updated . Posted . Visible to the public.

Running Unit Test in DDEV

There are 3 ways to run a unit test with composer:

1. Basic Composer PHPUnit Test

ddev exec composer run phpunit:test -- --filter="testInitiateTokenFlow.*success_initiate_token" tests/unit/Mage/Oauth/Model/ServerTest.php

What it does:

  • Runs the default PHPUnit configuration from .phpunit.dist.xml
  • Uses the standard testsuites: Base,Error,Mage,Varien
  • Applies the filter to find the specific test
  • Uses standard PHPUnit output format

Simple Bootstrap Flow:

  1. PHPUnit starts
  2. Reads .phpunit.dist.xml
  3. Finds bootstrap="tests/bootstrap.php"
  4. Executes tests/bootstrap.php
  5. Tests run with OpenMage framework loaded

Output:

PHPUnit 9.6.23 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 00:00.153, Memory: 6.00 MB

OK (1 test, 2 assertions)

Characteristics:

  • ✅ Simple dot notation (.) for passed tests
  • ✅ Basic timing and memory information
  • ✅ Minimal output, good for CI/CD
  • ✅ Fast execution

2. TestDox Format

ddev exec composer run phpunit:test -- --filter="testInitiateTokenFlow.*success_initiate_token" --testdox tests/unit/Mage/Oauth/Model/ServerTest.php

What it does:

  • Same as basic, but adds --testdox flag
  • Converts test method names into human-readable descriptions
  • Groups tests by class
  • Shows descriptive test names instead of dots

Output:

PHPUnit 9.6.23 by Sebastian Bergmann and contributors.

Server (OpenMage\Tests\Unit\Mage\Oauth\Model\Server)
 ✔ Initiate token flow with data set "success_initiate_token"

Time: 00:00.148, Memory: 6.00 MB

OK (1 test, 2 assertions)

Characteristics:

  • Human-readable test names: "Initiate token flow with data set 'success_initiate_token'"
  • Class grouping: Shows which test class the test belongs to
  • Visual indicators: Uses for passed tests, for failed tests
  • Better for documentation: Easy to understand what each test does
  • Slightly slower: Minimal performance impact

3. TestSuite Approach

ddev exec composer run phpunit:test -- --testsuite Mage --filter="testInitiateTokenFlow.*success_initiate_token"

What it does:

  • Runs only the Mage testsuite (instead of all testsuites)
  • Limits the scope to tests in tests/unit/Mage/ directory
  • Still applies the filter for the specific test
  • More targeted execution

Output:

PHPUnit 9.6.23 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 00:00.140, Memory: 8.00 MB

OK (1 test, 2 assertions)

Characteristics:

  • Faster execution: Only loads Mage testsuite
  • Lower memory usage: Doesn't load other testsuites
  • Targeted testing: Focuses on specific module
  • Same output format: Uses standard PHPUnit format

Key Differences Summary

Aspect Basic TestDox TestSuite
Output Format Dots (.) Human-readable names Dots (.)
Readability Low High Low
Performance Good Slightly slower Fastest
Memory Usage 6.00 MB 6.00 MB 8.00 MB
Execution Time 0.153s 0.148s 0.140s
Test Discovery All testsuites All testsuites Only Mage testsuite
Use Case CI/CD, automation Development, debugging Module-specific testing

When to Use Each:

Basic Command:

  • CI/CD pipelines - clean, minimal output
  • Automated testing - fast and reliable
  • Quick verification - when you just need pass/fail

TestDox Command:

  • Development - easy to understand what's being tested
  • Debugging - clear test descriptions help identify issues
  • Documentation - great for showing test coverage to stakeholders
  • Code reviews - reviewers can understand test intent

TestSuite Command:

  • Module testing - when working on specific OpenMage modules
  • Performance testing - fastest execution for large test suites
  • Focused development - testing only the module you're working on
  • Resource-constrained environments - lower memory usage

Real-World Example:

If you're developing OAuth functionality and want to see all OAuth-related tests in a readable format:

# See all OAuth tests with readable names
ddev exec composer run phpunit:test -- --testsuite Mage --filter="Oauth" --testdox

This would show you all OAuth tests across the Mage testsuite with human-readable descriptions, making it easy to understand the test coverage and identify any issues.

Examples

kiat@LivenPC:~/openmage$ ddev exec composer run phpunit:test -- --filter="testInitiateTokenFlow.*success_initiate_token" tests/unit/Mage/Oauth/Model/ServerTest.php
you may want to add the packages.firegento.com repository to composer.
add it with: composer.phar config -g repositories.firegento composer https://packages.firegento.com
> XDEBUG_MODE=off php vendor/bin/phpunit --configuration .phpunit.dist.xml --testsuite Base,Error,Mage,Varien --no-coverage '--filter=testInitiateTokenFlow.*success_initiate_token' 'tests/unit/Mage/Oauth/Model/ServerTest.php'
PHPUnit 9.6.23 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 00:00.144, Memory: 6.00 MB

OK (1 test, 2 assertions)
kiat@LivenPC:~/openmage$ ddev exec composer run phpunit:test -- --filter="testInitiateTokenFlow.*success_initiate_token" --testdox tests/unit/Mage/Oauth/Model/ServerTest.php
you may want to add the packages.firegento.com repository to composer.
add it with: composer.phar config -g repositories.firegento composer https://packages.firegento.com
> XDEBUG_MODE=off php vendor/bin/phpunit --configuration .phpunit.dist.xml --testsuite Base,Error,Mage,Varien --no-coverage '--filter=testInitiateTokenFlow.*success_initiate_token' '--testdox' 'tests/unit/Mage/Oauth/Model/ServerTest.php'
PHPUnit 9.6.23 by Sebastian Bergmann and contributors.

Server (OpenMage\Tests\Unit\Mage\Oauth\Model\Server)
 ✔ Initiate token flow with success_initiate_token

Time: 00:00.129, Memory: 6.00 MB

OK (1 test, 2 assertions)
kiat@LivenPC:~/openmage$ ddev exec composer run phpunit:test -- --testsuite Mage --filter="testInitiateTokenFlow.*success_initiate_token"
you may want to add the packages.firegento.com repository to composer.
add it with: composer.phar config -g repositories.firegento composer https://packages.firegento.com
> XDEBUG_MODE=off php vendor/bin/phpunit --configuration .phpunit.dist.xml --testsuite Base,Error,Mage,Varien --no-coverage '--testsuite' 'Mage' '--filter=testInitiateTokenFlow.*success_initiate_token'
PHPUnit 9.6.23 by Sebastian Bergmann and contributors.

.                                                                   1 / 1 (100%)

Time: 00:00.122, Memory: 8.00 MB

OK (1 test, 2 assertions)
kiat@LivenPC:~/openmage$ 

Break down each part:

  • ddev exec - Runs a command inside the DDEV container (DDEV is a local development environment for PHP projects)

  • vendor/bin/phpunit - Executes PHPUnit from the project's vendor directory (the PHP testing framework)

  • --configuration .phpunit.dist.xml - Uses the PHPUnit configuration file .phpunit.dist.xml for test settings (like database connections, bootstrap files, etc.)

  • tests/unit/Mage/Oauth/Controllers/OauthFlowTest.php - Specifies the specific test file to run (your OAuth flow test)

  • --testdox - Formats the output in a human-readable format, showing test method names as descriptive sentences instead of just method names

Running OAuth Tests on Actual Server

1. Basic Test Execution

# Navigate to your OpenMage root directory
cd /var/www/html/openmage  # or wherever your OpenMage is installed

# Run OAuth tests specifically
vendor/bin/phpunit --configuration .phpunit.dist.xml tests/unit/Mage/Oauth/Controllers/OauthFlowTest.php --testdox

The easiest way is to use the predefined composer scripts:

# Run all tests (including OAuth)
composer run phpunit:test

# Run with code coverage (if XDEBUG is available)
composer run phpunit:coverage

# Run with local HTML coverage report
composer run phpunit:coverage-local

Code Coverage Fundamentals

Code coverage measures which lines of code are executed during test runs. To do this, PHPUnit needs to:

  • Track line execution - Know which lines of code were actually run
  • Monitor function calls - Track which functions/methods were called
  • Record branch coverage - Track which conditional branches were taken
  • Generate coverage data - Create detailed reports about what was tested
  • From the composer.json, there are two coverage-related scripts.

Here's what happens when you run coverage:

# 1. XDEBUG_MODE=coverage tells Xdebug to collect coverage data
XDEBUG_MODE=coverage php vendor/bin/phpunit
# 2. Xdebug starts monitoring code execution
# 3. PHPUnit runs tests
# 4. Xdebug tracks which lines are executed
# 5. PHPUnit collects coverage data from Xdebug
# 6. PHPUnit generates coverage reports

Coverage Commands Available:

From the composer.json, there are two coverage scripts:

  1. phpunit:coverage - Basic coverage with testdox output
  2. phpunit:coverage-local - HTML coverage report generation

Coverage Commands Explained

1. phpunit:coverage - Basic Coverage

composer run phpunit:coverage -- [additional-options]

What it does:

  • Sets XDEBUG_MODE=coverage to enable code coverage collection
  • Uses the same configuration as phpunit:test
  • Includes --testdox for human-readable output
  • Generates coverage data but doesn't create HTML reports

Key differences from phpunit:test:

  • XDEBUG_MODE=coverage (vs XDEBUG_MODE=off)
  • Includes --testdox automatically
  • Collects coverage metrics during test execution
  • Requires Xdebug extension to be installed

Expected output (when Xdebug is available):

PHPUnit 9.6.23 by Sebastian Bergmann and contributors.

Server (OpenMage\Tests\Unit\Mage\Oauth\Model\Server)
 ✔ Initiate token flow with data set "success_initiate_token"

Code Coverage Report:       
  Classes: 85.00% (17/20)
  Methods: 90.00% (45/50)  
  Lines:   87.50% (350/400)

Time: 00:00.450, Memory: 12.00 MB

OK (1 test, 2 assertions)

2. phpunit:coverage-local - HTML Coverage Report

composer run phpunit:coverage-local -- [additional-options]

What it does:

  • Sets XDEBUG_MODE=coverage for coverage collection
  • Uses --coverage-html build/coverage to generate HTML reports
  • Creates detailed HTML files showing line-by-line coverage
  • Saves reports to build/coverage/ directory

Key differences:

  • Generates HTML reports in build/coverage/
  • Line-by-line coverage visualization
  • Interactive HTML interface for exploring coverage
  • Detailed metrics and uncovered code highlighting
  • Requires Xdebug extension
  • Slower execution due to detailed analysis

Expected output (when Xdebug is available):

PHPUnit 9.6.23 by Sebastian Bergmann and contributors.

Server (OpenMage\Tests\Unit\Mage\Oauth\Model\Server)
 ✔ Initiate token flow with data set "success_initiate_token"

Generating code coverage report in HTML format ... done

Code Coverage Report:       
  Classes: 85.00% (17/20)
  Methods: 90.00% (45/50)  
  Lines:   87.50% (350/400)

Time: 00:01.200, Memory: 16.00 MB

OK (1 test, 2 assertions)

Comparison Table

Aspect phpunit:test phpunit:coverage phpunit:coverage-local
XDEBUG_MODE off coverage coverage
Output Format Dots TestDox + Coverage TestDox + Coverage
Coverage Data ❌ No ✅ Yes (console) ✅ Yes (HTML)
HTML Reports ❌ No ❌ No ✅ Yes
Performance Fastest Medium Slowest
Memory Usage 6-8 MB 12-15 MB 16-20 MB
Execution Time ~0.15s ~0.45s ~1.2s
Requires Xdebug ❌ No ✅ Yes ✅ Yes
Use Case CI/CD, Quick tests Development, Coverage metrics Detailed analysis, Reports

When to Use Each:

phpunit:test (Basic)

  • CI/CD pipelines - fast, no coverage needed
  • Quick verification - just need pass/fail
  • Resource-constrained environments
  • When Xdebug isn't available

phpunit:coverage (Basic Coverage)

  • Development - see coverage metrics in console
  • Code quality checks - ensure adequate test coverage
  • Pull request reviews - verify new code is tested
  • When you need coverage data but not HTML reports

phpunit:coverage-local (HTML Coverage)

  • Detailed analysis - explore uncovered code
  • Team collaboration - share coverage reports
  • Code review - visual line-by-line coverage
  • Documentation - generate coverage reports for stakeholders
  • Debugging - identify untested code paths

Current Situation in Your Environment:

Since Xdebug isn't available in your ddev environment, the coverage commands will show:

Warning: No code coverage driver available

To enable coverage, you would need to:

  1. Install Xdebug in your ddev environment
  2. Configure Xdebug for coverage collection
  3. Then the coverage commands would work as expected

For now, use phpunit:test for regular testing since it works perfectly without Xdebug and provides fast, reliable test execution.

3. Test Output Examples

When you run the OAuth tests, you'll see output like this:

$ vendor/bin/phpunit --configuration .phpunit.dist.xml tests/unit/Mage/Oauth/Controllers/OauthFlowTest.php --testdox

PHPUnit 9.6.23 by Sebastian Bergmann and contributors.

Oauth Flow (OpenMage\Tests\Unit\Mage\Oauth\Controllers\OauthFlow)
 ✔ Complete oauth flow with valid_oauth_flow
 ✔ Complete oauth flow with initiate_only_flow
 ✔ Complete oauth flow with authorize_only_flow
 ✔ Initiate controller index action with valid_initiate_request
 ✔ Initiate controller index action with initiate_with_callback
 ✔ Initiate controller index action with initiate_oob_callback
 ✔ Authorize controller actions with valid_authorize_request
 ✔ Authorize controller actions with authorize_confirm_action
 ✔ Authorize controller actions with authorize_reject_action
 ✔ Authorize controller actions with authorize_simple_page
 ✔ Token controller index action with valid_token_request
 ✔ Token controller index action with token_with_verifier
 ✔ Oauth error scenarios with invalid_consumer_key
 ✔ Oauth error scenarios with invalid_signature
 ✔ Oauth error scenarios with token_expired
 ✔ Oauth error scenarios with token_revoked
 ✔ Oauth error scenarios with invalid_verifier
 ✔ Oauth error scenarios with nonce_used
 ✔ Oauth error scenarios with timestamp_refused
 ✔ Oauth error scenarios with parameter_absent
 ✔ Oauth error scenarios with signature_method_rejected
 ✔ Oauth error scenarios with version_rejected
 ✔ Oauth signature validation
 ✔ Oauth token lifecycle

Time: 00:00.275, Memory: 8.00 MB

OK (24 tests, 57 assertions)

4. Running Specific Test Groups

You can run tests by groups using the --group option:

# Run only OAuth tests
vendor/bin/phpunit --configuration .phpunit.dist.xml --group Oauth

# Run only controller tests
vendor/bin/phpunit --configuration .phpunit.dist.xml --group Controllers

# Run only error scenario tests
vendor/bin/phpunit --configuration .phpunit.dist.xml --group Error

5. Performance Optimization

For production servers, you might want to optimize performance:

# Disable XDEBUG for faster execution
XDEBUG_MODE=off vendor/bin/phpunit --configuration .phpunit.dist.xml tests/unit/Mage/Oauth/Controllers/OauthFlowTest.php

# Set memory limit
php -d memory_limit=512M vendor/bin/phpunit --configuration .phpunit.dist.xml tests/unit/Mage/Oauth/Controllers/OauthFlowTest.php

# Run without coverage for speed
vendor/bin/phpunit --configuration .phpunit.dist.xml --no-coverage tests/unit/Mage/Oauth/Controllers/OauthFlowTest.php

6. Integration with CI/CD

For automated testing, you can integrate with your CI/CD pipeline:

# Exit with error code if tests fail
vendor/bin/phpunit --configuration .phpunit.dist.xml tests/unit/Mage/Oauth/Controllers/OauthFlowTest.php --stop-on-failure

# Generate JUnit XML for CI systems
vendor/bin/phpunit --configuration .phpunit.dist.xml tests/unit/Mage/Oauth/Controllers/OauthFlowTest.php --log-junit oauth-test-results.xml

7. Cron Job Example

To run tests automatically, you could set up a cron job:

# Add to crontab (runs daily at 2 AM)
0 2 * * * cd /var/www/html/openmage && vendor/bin/phpunit --configuration .phpunit.dist.xml tests/unit/Mage/Oauth/Controllers/OauthFlowTest.php --log-junit /var/log/oauth-tests.xml

8. Quick Verification

To quickly verify the OAuth tests are working:

# Simple test run
vendor/bin/phpunit tests/unit/Mage/Oauth/Controllers/OauthFlowTest.php

# Check if all OAuth tests pass
vendor/bin/phpunit --configuration .phpunit.dist.xml tests/unit/Mage/Oauth/Controllers/OauthFlowTest.php | grep -E "(OK|FAILURES|ERRORS)"

9. What the Tests Validate

The OAuth tests validate:

  • Controller Instantiation: All OAuth controllers can be created
  • Complete OAuth Flow: Full initiate → authorize → token → resource flow
  • Error Handling: Proper error responses for invalid requests
  • Security: OAuth signature validation
  • Token Lifecycle: Token creation and conversion
  • Callback Handling: OOB and URL callbacks

10. Expected Results

On a properly configured production server, you should see:

  • 24 tests passing
  • 57 assertions successful
  • 0 errors, 0 failures
  • Execution time: Typically under 1 second

That's it! Since your production server already has OpenMage set up, the tests should run immediately without any additional configuration.

kiatng
Last edit
kiatng
Posted by kiatng to OpenMage (2025-09-11 04:34)