lastdragon-ru/phpunit-xml
Tools for working with PHPUnit’s XML configuration: parse, build, and validate phpunit.xml files programmatically. Useful for CI automation, config generation, and upgrades/migrations between PHPUnit versions, with a focused API designed for PHP projects.
Installation Add the package via Composer:
composer require --dev lastdragon-ru/phpunit-xml
Ensure PHPUnit is configured in your phpunit.xml to autoload the package’s traits.
First Use Case
Import the XMLAssertions trait in your test class:
use LastDragon\PHPUnitXML\XMLAssertions;
use PHPUnit\Framework\TestCase;
class XmlTest extends TestCase
{
use XMLAssertions;
}
Test XML equality against a schema or another XML string:
public function testXmlStructure()
{
$xmlString = '<root><child>value</child></root>';
$this->assertXmlStringEqualsXmlString($xmlString, $xmlString); // Basic equality
}
Where to Look First
XMLAssertions trait for available methods (e.g., assertXmlStringMatchesSchema, assertXmlStringEqualsXmlString).assertXmlStringEqualsXmlFile).Schema Validation Validate XML against an XSD schema:
public function testXmlAgainstSchema()
{
$xml = '<catalog><book id="101"/></catalog>';
$schema = file_get_contents('path/to/schema.xsd');
$this->assertXmlStringMatchesSchema($xml, $schema);
}
Dynamic XML Assertions Useful for API responses or generated XML:
public function testApiResponseXml()
{
$responseXml = $this->get('/api/data')->getContent();
$expectedXml = '<response><status>success</status></response>';
$this->assertXmlStringEqualsXmlString($expectedXml, $responseXml);
}
Partial XML Matching Assert specific nodes exist without strict equality:
public function testPartialXmlMatch()
{
$xml = '<root><user><name>John</name></user></root>';
$this->assertXmlStringContainsNode($xml, 'name');
}
Integration with Laravel Combine with Laravel’s HTTP tests:
public function testXmlResponseFromRoute()
{
$response = $this->getJson('/xml-endpoint');
$this->assertXmlStringEqualsXmlString(
'<data><item>test</item></data>',
$response->getContent()
);
}
tests/Resources/schemas/ and reference them via file_get_contents().try-catch blocks to log detailed failure messages:
try {
$this->assertXmlStringMatchesSchema($xml, $schema);
} catch (Exception $e) {
$this->fail('Schema validation failed: ' . $e->getMessage());
}
Namespace Conflicts
Ensure XML namespaces in test strings match the schema. Use Lxml or SimpleXML to normalize namespaces if needed:
$dom = new \DOMDocument();
$dom->loadXML($xml);
$normalized = $dom->saveXML();
Whitespace Sensitivity
XML assertions are strict about whitespace. Use DOMDocument::preserveWhiteSpace or trim strings:
$this->assertXmlStringEqualsXmlString(
trim($expected),
trim($actual)
);
Schema Location
Relative paths in schemas may break in CI/CD. Use absolute paths or file_exists() checks:
$schemaPath = base_path('tests/Resources/schemas/schema.xsd');
$this->assertFileExists($schemaPath);
Large XML Files Avoid loading entire large XML files into memory. Stream or chunk assertions where possible.
var_dump() or dd() to inspect XML structure before assertions:
$dom = new \DOMDocument();
$dom->loadXML($xml);
$this->assertEquals('expected', $dom->getElementsByTagName('tag')->item(0)->nodeValue);
$errors = [];
$this->assertXmlStringMatchesSchema($xml, $schema, $errors);
$this->assertEmpty($errors, implode("\n", $errors));
Custom Assertions Extend the trait or create a wrapper for reusable logic:
trait CustomXmlAssertions {
protected function assertXmlHasNodeValue($xml, $nodePath, $expectedValue) {
$dom = new \DOMDocument();
$dom->loadXML($xml);
$node = $dom->getElementsByTagName($nodePath)->item(0);
$this->assertNotNull($node, "Node $nodePath not found");
$this->assertEquals($expectedValue, $node->nodeValue);
}
}
Laravel Service Providers Bind the trait to a test helper service for global access:
// In a TestServiceProvider
app()->singleton('xml-assertions', function () {
return new class {
public function assertXmlHasNode($xml, $nodeName) {
// Custom logic
}
};
});
CI/CD Integration Add a pre-test hook to validate schemas:
# In phpunit.xml
<php>
<ini name="assert.exception" value="1"/>
</php>
How can I help you explore Laravel packages today?