VOOZH about

URL: https://deepwiki.com/stefanak-michal/php-bolt-driver/8.1-test-architecture-and-organization

⇱ Test Architecture and Organization | stefanak-michal/php-bolt-driver | DeepWiki


Loading...
Last indexed: 14 February 2026 (a283bd)
Menu

Test Architecture and Organization

This document details the test infrastructure architecture for the PHP Bolt Protocol Client library, including the test class hierarchy, mock connection patterns, validation approaches, and organizational principles. For information about specific test suites and CI/CD pipelines, see CI/CD Pipeline and Cross-Version Testing. For integration testing details, see Integration Testing.

Purpose and Scope

The testing architecture provides a layered foundation for validating protocol implementations, message serialization, state transitions, and cross-version compatibility. The design emphasizes:

  • Code reuse through abstract base classes and trait patterns
  • Mock-based unit testing for protocol validation without database dependencies
  • State machine validation ensuring correct ServerState transitions
  • Binary serialization verification validating PackStream encoding/decoding
  • Protocol version compatibility testing across Bolt versions 1 through 6

Test Class Hierarchy

The test infrastructure uses a three-layer inheritance model that progressively adds capabilities from generic test utilities to protocol-specific validation methods.


Sources: tests/TestLayer.php1-111 tests/protocol/V1Test.php1-213 tests/protocol/V3Test.php1-219

TestLayer Base Class

The TestLayer abstract class tests/TestLayer.php12-110 provides foundational utilities used across all test types. It extends PHPUnit's TestCase and establishes two primary capabilities:

Environment Configuration

The setUpBeforeClass() method tests/TestLayer.php14-29 reads environment variables and populates global configuration:

Environment VariableGlobal VariablePurpose
GDB_USERNAME$GLOBALS['NEO_USER']Database username
GDB_PASSWORD$GLOBALS['NEO_PASS']Database password
GDB_HOST$GLOBALS['NEO_HOST']Database host
GDB_PORT$GLOBALS['NEO_PORT']Database port

This allows CI/CD pipelines to configure test connections via environment variables without modifying test code.

Unified Authentication: sayHello()

The sayHello() method tests/TestLayer.php37-60 abstracts protocol-specific authentication patterns:


This pattern enables test code to authenticate against any protocol version without conditional logic at the call site.

Protocol Version Detection: getCompatibleBoltVersion()

The getCompatibleBoltVersion() method tests/TestLayer.php69-109 queries Neo4j's HTTP discovery API to determine the appropriate Bolt protocol version:

Neo4j VersionBolt Version
≥ 2025.106
≥ 5.265.8
≥ 5.235.6
≥ 5.135.4
≥ 5.95.3
≥ 5.75.2
≥ 5.55.1
≥ 5.05
≥ 4.44.4
≥ 4.34.3

This method enables integration tests to dynamically select compatible protocol versions based on the running database instance.

Sources: tests/TestLayer.php1-111

ProtocolLayer and Mock Connection Pattern

The ProtocolLayer abstract class extends TestLayer and provides the core infrastructure for protocol unit testing through mock connections. While the class file is not shown in the provided sources, its usage is evident throughout protocol test files.

Mock Connection Architecture

Protocol tests use a mock connection that operates on static buffers rather than real network I/O:


Read Array Format

The self::$readArray static property tests/protocol/V1Test.php29-32 defines server responses as signature-content pairs:


Each array element is a tuple where:

  • First element: Response signature byte (e.g., 0x70 = SUCCESS, 0x7F = FAILURE)
  • Second element: Response content as object or array

Write Buffer Format

The self::$writeBuffer static property tests/protocol/V1Test.php33-44 contains expected hexadecimal representations of serialized messages:


Each hex string represents PackStream-encoded data chunks. Tests validate that protocol implementations generate exactly these byte sequences when sending messages.

Sources: tests/protocol/V1Test.php17-60

Test Organization and Naming Conventions

Protocol test classes follow consistent naming and organizational patterns:

File Structure

tests/
├── protocol/
│ ├── ProtocolLayer.php # Base for protocol tests
│ ├── V1Test.php # Bolt v1 tests
│ ├── V2Test.php # Bolt v2 tests
│ ├── V3Test.php # Bolt v3 tests
│ ├── V4Test.php # Bolt v4 tests
│ ├── V4_1Test.php # Bolt v4.1 tests
│ ├── V4_2Test.php # Bolt v4.2 tests
│ ├── V4_3Test.php # Bolt v4.3 tests
│ ├── V4_4Test.php # Bolt v4.4 tests
│ ├── V5_1Test.php # Bolt v5.1 tests
│ ├── V5_2Test.php # Bolt v5.2 tests
│ ├── V5_3Test.php # Bolt v5.3 tests
│ └── V6Test.php # Bolt v6 tests
├── structures/
│ ├── StructureLayer.php # Base for structure tests
│ ├── v1/ # v1 structure tests
│ ├── v4_3/ # v4.3 structure tests
│ ├── v5/ # v5 structure tests
│ └── v6/ # v6 structure tests
└── TestLayer.php # Base for all tests

Test Method Naming

Each protocol test class follows a standard method structure:

Method PatternPurposeExample
test__construct()Instantiate protocolReturns protocol instance
testInit() / testHello()AuthenticationTests connection setup
testRun()Query executionTests RUN message
testPullAll() / testPull()Result fetchingTests streaming
testDiscardAll() / testDiscard()Result discardingTests discard
testBegin()Transaction startTests BEGIN
testCommit()Transaction commitTests COMMIT
testRollback()Transaction rollbackTests ROLLBACK
testReset()Connection resetTests RESET
testAckFailure()Error acknowledgmentTests ACK_FAILURE (v1)
testGoodbye()Connection closeTests GOODBYE (v3+)
testRoute()Cluster routingTests ROUTE (v4.3+)
testLogon() / testLogoff()Split authTests LOGON/LOGOFF (v5+)

Sources: tests/protocol/V1Test.php17-212 tests/protocol/V3Test.php17-218

The @depends Annotation Pattern

Protocol tests use PHPUnit's @depends annotation to establish test execution order and share protocol instances across test methods. This pattern reduces test execution time by avoiding redundant protocol instantiation.

Dependency Chain


Implementation Example

The constructor test tests/protocol/V1Test.php17-22 creates and returns the protocol instance:


Subsequent tests declare the dependency tests/protocol/V1Test.php24-27:


This pattern ensures:

  1. Protocol is instantiated once per test class
  2. Tests can be executed in any order (no implicit dependencies)
  3. Each test receives a fresh protocol instance in a known state
  4. Reduced test suite execution time

Sources: tests/protocol/V1Test.php17-27 tests/protocol/V3Test.php17-27

Test Validation Patterns

Protocol tests validate three primary aspects: message serialization, response handling, and state transitions.

Message Serialization Validation

Tests verify that protocol methods generate correct binary output by checking against self::$writeBuffer tests/protocol/V1Test.php33-50:


The hexadecimal strings represent PackStream-encoded chunks that would be written to the socket. This validates that the Packer correctly serializes method parameters.

Response Handling Validation

Tests configure self::$readArray with various response scenarios and validate protocol behavior tests/protocol/V1Test.php52-60:

SUCCESS Response


FAILURE Response


IGNORED Response


State Transition Validation

Tests validate that ServerState transitions occur correctly based on message types and responses tests/protocol/V1Test.php88-101:

Initial StateMessageResponseFinal State
CONNECTEDinit()SUCCESSREADY
CONNECTEDinit()FAILUREDEFUNCT
READYrun()SUCCESSSTREAMING
READYrun()FAILUREFAILED
INTERRUPTEDrun()IGNOREDINTERRUPTED
STREAMINGpullAll()SUCCESSREADY
STREAMINGdiscardAll()SUCCESSREADY
FAILEDackFailure()SUCCESSREADY
FAILEDreset()SUCCESSREADY

The checkFailure() Helper

The checkFailure() method (defined in ProtocolLayer, implementation not shown) validates FAILURE response structure:


Sources: tests/protocol/V1Test.php27-101 tests/protocol/V3Test.php27-110

Multi-Scenario Testing Pattern

Most protocol test methods validate three scenarios: success, failure, and interrupted states. This pattern ensures robust error handling.

Standard Test Structure


Example: testRun()

The testRun() method tests/protocol/V1Test.php65-102 demonstrates this pattern:


This ensures each message type is validated against all possible server response scenarios.

Sources: tests/protocol/V1Test.php65-102 tests/protocol/V3Test.php70-110

Protocol Version Coverage

The test suite provides comprehensive coverage across all Bolt protocol versions:

Test ClassProtocol VersionKey Features Tested
V1Test1.0INIT, RUN, PULL_ALL, DISCARD_ALL, RESET, ACK_FAILURE
V2Test2.0Same as V1 (V2 is identical to V1)
V3Test3.0HELLO, BEGIN, COMMIT, ROLLBACK, GOODBYE
V4Test4.0PULL, DISCARD (with parameters)
V4_1Test4.1Enhanced HELLO
V4_2Test4.2No new messages (bug fixes only)
V4_3Test4.3ROUTE (basic routing)
V4_4Test4.4ROUTE (enhanced with db parameter)
V5_1Test5.1Split authentication (HELLO + LOGON)
V5_2Test5.2LOGOFF
V5_3Test5.3Additional features
V6Test6.0Vector structures, TELEMETRY

Minimal Test Classes

Some protocol versions have minimal test classes tests/protocol/V2Test.php15-24 that only test construction:


This indicates that:

  1. The protocol version has no unique messages beyond its parent
  2. Implementation is verified through inheritance
  3. Constructor test ensures proper instantiation and dependency injection

Sources: tests/protocol/V2Test.php1-24 tests/protocol/V4_2Test.php1-24 tests/protocol/V6Test.php1-23

Integration with Unpacker

Protocol tests indirectly validate the Unpacker class by consuming unpacked responses. The mock connection's read() method uses a real Unpacker instance to convert binary data from self::$readArray into PHP values.


The Unpacker src/packstream/v1/Unpacker.php32-42 converts binary PackStream format to PHP structures:

This integration validates both protocol message handling and serialization correctness.

Sources: src/packstream/v1/Unpacker.php1-294 tests/protocol/V1Test.php29-32

Refresh this wiki

On this page