Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Eseperio/verifactu-php/llms.txt

Use this file to discover all available pages before exploring further.

Verifactu PHP ships with a comprehensive test suite covering models, serialization services, hash generation, XML signing, response parsing, QR generation, SOAP client creation, and live sandbox submissions. All tests are driven by PHPUnit 10 and are organized into clearly separated suites so you can run exactly the tests you need.

Test Suite Overview

Tests live under the tests/ directory and are divided into three top-level groups:
tests/
├── Framework/
│   └── EnhancedTestPrinter.php          # Custom PHPUnit printer
├── Unit/
│   ├── Models/
│   │   ├── InvoiceCancellationTest.php  # Cancellation model validation
│   │   ├── InvoiceSubmissionTest.php    # Submission model validation
│   │   └── ModelTest.php               # Base model behaviour
│   ├── Services/
│   │   ├── HashGeneratorServiceTest.php
│   │   ├── InvoiceSerializerTest.php
│   │   ├── QrGeneratorServiceTest.php
│   │   ├── ResponseParserServiceTest.php
│   │   ├── SoapClientFactoryServiceTest.php
│   │   └── XmlSignerServiceTest.php
│   └── XmlGenerationTest.php
└── Verifactu/
    ├── ReadmeAltaExampleTest.php        # README "register invoice" example
    ├── ReadmeExamplesTest.php           # All other README code examples
    └── VerifactuSandboxTest.php         # Live AEAT sandbox integration tests
phpunit.xml defines four named test suites:
SuiteDirectory / FileWhat It Tests
Unittests/Unit/Models and services in isolation (no network)
Servicestests/Unit/Services/Service-layer unit tests only
VerifactuReadmeAltaExampleTest.php, ReadmeExamplesTest.phpEnsures README examples are always correct
IntegrationVerifactuSandboxTest.phpLive calls to the AEAT sandbox (requires certificate)

Composer Test Commands

All test commands automatically check for a .env file and create one from .env.example if it is missing, displaying a warning if so.
CommandWhat It Runs
composer testFull test suite (all suites)
composer test-unitUnit suite only — no network required
composer test-sandboxIntegration suite — requires a configured .env certificate
composer test-verifactuREADME example tests and sandbox tests under tests/Verifactu/
composer coverageFull suite with HTML coverage report written to var/coverage/html/
# Run everything
composer test

# Fast feedback — unit tests only
composer test-unit

# Live sandbox tests (certificate required)
composer test-sandbox

# HTML coverage report
composer coverage
The Integration suite (composer test-sandbox) makes real HTTPS calls to the AEAT homologation endpoint. You must supply a valid certificate and matching issuer details in .env. Tests skip automatically when the certificate configuration is absent or incomplete.

Setting Up .env for Sandbox Tests

1

Copy the example environment file

The repository ships with .env.example containing all required variable names. Copy it to .env in the project root:
cp .env.example .env
If you run any composer test* command without a .env present, the check-env Composer script creates it automatically from .env.example and prints a warning reminding you to configure it.
2

Set your certificate details

Open .env and fill in your certificate path and password. For sandbox tests, point to a certificate accepted by the AEAT pre-production environment:
# Path to your certificate file (P12/PFX)
VERIFACTU_CERT_PATH=/path/to/your/certificate.p12

# Password for your certificate
VERIFACTU_CERT_PASSWORD=your_certificate_password

# Certificate type: 'certificate' or 'seal'
VERIFACTU_CERT_TYPE=certificate

# Environment: always 'sandbox' for integration tests
VERIFACTU_ENVIRONMENT=sandbox
3

Set the issuer identity variables

Integration tests submit invoices on behalf of a real issuer identity. These values must exactly match the data AEAT holds for that NIF in their census — including punctuation and casing.
# Required by integration tests — must match your AEAT census data exactly
TEST_ISSUER_NIF=B12345678
TEST_ISSUER_NAME="Example Company SL"
If these values do not match AEAT’s census, you will receive error 4104 (“El valor del campo NIF del bloque ObligadoEmision no está identificado”). See the Error Handling guide for how to resolve this.
4

Run the sandbox tests

composer test-sandbox
The test runner will:
  1. Load .env via vlucas/phpdotenv.
  2. Configure the library using the certificate and sandbox environment.
  3. Submit test invoices to https://prewww1.aeat.es/…/VerifactuSOAP.
  4. Assert that AEAT returns STATUS_OK ('Correcto') for each submission.
Tests that detect an unconfigured certificate path or a missing .env value call $this->markTestSkipped() automatically — they will appear as skipped rather than failed.

Auto-Creation of .env from .env.example

The check-env Composer script is prepended to every test command:
"check-env": "php -r \"if (!file_exists('.env') && file_exists('.env.example')) { copy('.env.example', '.env'); echo PHP_EOL . '⚠️  No .env file found. Created from .env.example. Please edit .env with your certificate details.' . PHP_EOL . PHP_EOL; }\""
This means:
  • Running composer test on a freshly cloned repo will never fail with a missing file error.
  • You will see a visible warning in the console output reminding you to populate the generated .env.
  • The .env file is listed in .gitignore — it will never be accidentally committed.

Code Quality Tools

Beyond tests, the project provides several static-analysis and style-enforcement commands:
CommandToolWhat It Does
composer phpstanPHPStanStatic analysis — detects type errors and logic bugs without running code
composer phpstan-baselinePHPStanRegenerate the PHPStan baseline to acknowledge existing issues
composer cs-checkPHP CS FixerCheck PSR-12 code style (dry run — no changes written)
composer cs-fixPHP CS FixerAuto-fix PSR-12 code style violations
composer rectorRectorApply automated refactoring rules
composer rector-dryRectorPreview Rector changes without writing them
Run all checks together before submitting a pull request:
# Check style + static analysis + all tests
composer quality

# Fix style + apply refactoring + run tests
composer quality-fix

Writing Your Own Tests

When adding tests to the project, follow the conventions in CONTRIBUTING.md:
  • Place unit tests under tests/Unit/ in a subdirectory that mirrors the src/ path of the class under test.
  • Place integration tests (those that make real network calls) under tests/Verifactu/ and guard them with a skip check when the certificate is absent.
  • Target 80%+ code coverage for new code.
  • Use descriptive test method names in the format testItDoesX() or test_it_does_x().
A minimal unit test skeleton for a model:
use PHPUnit\Framework\TestCase;
use eseperio\verifactu\models\InvoiceSubmission;

class InvoiceSubmissionTest extends TestCase
{
    public function testValidateReturnsEmptyArrayWhenAllRequiredFieldsAreSet(): void
    {
        $invoice = new InvoiceSubmission();
        // ... set all required properties ...

        $result = $invoice->validate();

        $this->assertEmpty($result);
    }

    public function testValidateReturnsErrorsWhenRequiredFieldsAreMissing(): void
    {
        $invoice = new InvoiceSubmission();
        // Leave required fields empty

        $result = $invoice->validate();

        $this->assertIsArray($result);
        // Keys are in the format 'ClassName::$propertyName'
        $this->assertNotEmpty($result);
    }
}
Run your new test in isolation before committing:
vendor/bin/phpunit tests/Unit/Models/InvoiceSubmissionTest.php

Build docs developers (and LLMs) love