PHPackages                             fuwasegu/php-sql-snapshot - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Testing &amp; Quality](/categories/testing)
4. /
5. fuwasegu/php-sql-snapshot

ActiveLibrary[Testing &amp; Quality](/categories/testing)

fuwasegu/php-sql-snapshot
=========================

PHPUnit extension for testing SQL queries using AST comparison instead of string comparison

1.0.0(6mo ago)111[1 PRs](https://github.com/fuwasegu/php-sql-snapshot/pulls)MITPHPPHP ^8.2CI passing

Since Dec 17Pushed 6mo agoCompare

[ Source](https://github.com/fuwasegu/php-sql-snapshot)[ Packagist](https://packagist.org/packages/fuwasegu/php-sql-snapshot)[ RSS](/packages/fuwasegu-php-sql-snapshot/feed)WikiDiscussions main Synced today

READMEChangelog (1)Dependencies (4)Versions (2)Used By (0)

PHP SQL Snapshot
================

[](#php-sql-snapshot)

PHPUnit extension for semantic SQL query testing using AST (Abstract Syntax Tree) comparison. Test SQL queries by their meaning, not their formatting.

The Problem
-----------

[](#the-problem)

Traditional SQL testing using string comparison fails when queries are semantically identical but formatted differently:

```
// These queries are semantically identical
$expected = "SELECT id, name FROM users WHERE active = 1 AND role = 'admin'";
$actual   = "SELECT name, id FROM users WHERE role = 'admin' AND active = 1";

// String comparison fails!
$this->assertEquals($expected, $actual); // FAILS
```

The Solution
------------

[](#the-solution)

This library parses SQL queries into AST and compares them semantically, ignoring:

- Column order in SELECT clauses
- Condition order in WHERE clauses (within AND groups)
- Whitespace and formatting differences
- Quote styles around identifiers

```
use PhpSqlSnapshot\PHPUnit\SqlAssertionTrait;

class MyDatabaseTest extends TestCase
{
    use SqlAssertionTrait;

    public function testQueryGeneration(): void
    {
        $expected = "SELECT id, name FROM users WHERE active = 1 AND role = 'admin'";
        $actual = "SELECT name, id FROM users WHERE role = 'admin' AND active = 1";

        // AST comparison succeeds!
        $this->assertMySqlEquals($expected, $actual);
    }
}
```

Features
--------

[](#features)

- **Database Agnostic**: Supports MySQL and PostgreSQL
- **Order Independent**: Ignores column and condition ordering
- **Format Independent**: Ignores whitespace, newlines, and formatting
- **Type Safe**: Strongly typed PHP 8.2+ API
- **PHPUnit Native**: Works seamlessly with PHPUnit assertions
- **Clear Error Messages**: Detailed diff output when queries don't match
- **Comprehensive Dialect Support**: JSON functions, CTEs, UNION, subqueries, and more

Requirements
------------

[](#requirements)

- PHP 8.2 or higher (tested on 8.2, 8.3, 8.4, 8.5)
- PHPUnit 10.0 or higher

Installation
------------

[](#installation)

Install via Composer:

```
composer require --dev fuwasegu/php-sql-snapshot
```

Usage
-----

[](#usage)

### Basic Usage

[](#basic-usage)

```
