PHPackages                             stevegrunwell/phpunit-markup-assertions - 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. stevegrunwell/phpunit-markup-assertions

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

stevegrunwell/phpunit-markup-assertions
=======================================

Assertions for PHPUnit to verify the presence or state of elements within markup

v2.0.0(11mo ago)16156.6k—5.3%2[5 issues](https://github.com/stevegrunwell/phpunit-markup-assertions/issues)[4 PRs](https://github.com/stevegrunwell/phpunit-markup-assertions/pulls)5MITPHPPHP ^7.1 || ^8.0CI passing

Since Oct 25Pushed 7mo ago2 watchersCompare

[ Source](https://github.com/stevegrunwell/phpunit-markup-assertions)[ Packagist](https://packagist.org/packages/stevegrunwell/phpunit-markup-assertions)[ GitHub Sponsors](https://github.com/stevegrunwell)[ RSS](/packages/stevegrunwell-phpunit-markup-assertions/feed)WikiDiscussions develop Synced yesterday

READMEChangelog (7)Dependencies (7)Versions (13)Used By (5)

PHPUnit Markup Assertions
=========================

[](#phpunit-markup-assertions)

[![Build Status](https://github.com/stevegrunwell/phpunit-markup-assertions/workflows/Unit%20Tests/badge.svg)](https://github.com/stevegrunwell/phpunit-markup-assertions/workflows/Unit%20Tests/badge.svg)[![Code Coverage](https://camo.githubusercontent.com/7efa3413d39706258180bcc1410b3a2fa6a6d8acd0342047f57f239959d2347e/68747470733a2f2f636f766572616c6c732e696f2f7265706f732f6769746875622f73746576656772756e77656c6c2f706870756e69742d6d61726b75702d617373657274696f6e732f62616467652e7376673f6272616e63683d646576656c6f70)](https://coveralls.io/github/stevegrunwell/phpunit-markup-assertions?branch=develop)[![GitHub Release](https://camo.githubusercontent.com/0acfb4d0b27f42ba7aadbb7c7f64e935e3614490080d9b93640df9e82c5fa887/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f73746576656772756e77656c6c2f706870756e69742d6d61726b75702d617373657274696f6e732e737667)](https://github.com/stevegrunwell/phpunit-markup-assertions/releases)

This library introduces the `MarkupAssertionsTrait` trait for use in [PHPUnit](https://phpunit.de) tests.

These assertions enable you to inspect generated markup without having to muddy tests with [`DOMDocument`](http://php.net/manual/en/class.domdocument.php) or nasty regular expressions. If you're generating markup at all with PHP, the PHPUnit Markup Assertions trait aims to make the output testable without making your tests fragile.

Example
-------

[](#example)

```
use PHPUnit\Framework\TestCase;
use SteveGrunwell\PHPUnit_Markup_Assertions\MarkupAssertionsTrait;

class MyUnitTest extends TestCase
{
    use MarkupAssertionsTrait;

    /**
     * Ensure the #first-name and #last-name selectors are present in the form.
     */
    public function testRenderFormContainsInputs()
    {
        $markup = render_form();

        $this->assertContainsSelector('#first-name', $markup);
        $this->assertContainsSelector('#last-name', $markup);
    }
}
```

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

[](#installation)

To add PHPUnit Markup Assertions to your project, first install the library via Composer:

```
$ composer require --dev stevegrunwell/phpunit-markup-assertions
```

Next, import the `SteveGrunwell\PHPUnit_Markup_Assertions\MarkupAssertionsTrait` trait into each test case that will leverage the assertions:

```
use PHPUnit\Framework\TestCase;
use SteveGrunwell\PHPUnit_Markup_Assertions\MarkupAssertionsTrait;

class MyTestCase extends TestCase
{
    use MarkupAssertionsTrait;
}
```

### Making PHPUnit Markup Assertions available globally

[](#making-phpunit-markup-assertions-available-globally)

If you'd like the methods to be available across your entire test suite, you might consider [sub-classing the PHPUnit test case and applying the trait there](https://phpunit.de/manual/current/en/extending-phpunit.html#extending-phpunit.PHPUnit_Framework_TestCase):

```
# tests/TestCase.php

namespace Tests;

use PHPUnit\Framework\TestCase as BaseTestCase;
use SteveGrunwell\PHPUnit_Markup_Assertions\MarkupAssertionsTrait;

class TestCase extends BaseTestCase
{
    use MarkupAssertionsTrait;
}
```

Then update your other test cases to use your new base:

```
# tests/Unit/ExampleTest.php

namespace Tests/Unit;

use Tests\TestCase;

class MyUnitTest extends TestCase
{
    // This class now automatically has markup assertions.
}
```

Available methods
-----------------

[](#available-methods)

These are the assertions made available to PHPUnit via the `MarkupAssertionsTrait`.

- [`assertContainsSelector()`](#assertcontainsselector)
- [`assertNotContainsSelector()`](#assertnotcontainsselector)
- [`assertSelectorCount()`](#assertselectorcount)
- [`assertHasElementWithAttributes()`](#asserthaselementwithattributes)
- [`assertNotHasElementWithAttributes()`](#assertnothaselementwithattributes)
- [`assertElementContains()`](#assertelementcontains)
- [`assertElementNotContains()`](#assertelementnotcontains)
- [`assertElementRegExp()`](#assertelementregexp)
- [`assertElementNotRegExp()`](#assertelementnotregexp)

### assertContainsSelector()

[](#assertcontainsselector)

Assert that the given string contains an element matching the given selector.

 (string) $selector A query selector for the element to find. (string) $markup The markup that should contain the `$selector`. (string) $message A message to display if the assertion fails.#### Example

[](#example-1)

```
public function testBodyContainsImage()
{
    $body = getPageBody();

    $this->assertContainsSelector('img', $body, 'Did not find an image in the page body.');
}
```

### assertNotContainsSelector()

[](#assertnotcontainsselector)

Assert that the given string does not contain an element matching the given selector.

This method is the inverse of [`assertContainsSelector()`](#assertcontainsselector).

 (string) $selector A query selector for the element to find. (string) $markup The markup that should not contain the `$selector`. (string) $message A message to display if the assertion fails.### assertSelectorCount()

[](#assertselectorcount)

Assert the number of times an element matching the given selector is found.

 (int) $count The number of matching elements expected. (string) $selector A query selector for the element to find. (string) $markup The markup to run the assertion against. (string) $message A message to display if the assertion fails.#### Example

[](#example-2)

```
public function testPostList()
{
    factory(Post::class, 10)->create();

    $response = $this->get('/posts');

    $this->assertSelectorCount(10, 'li.post-item', $response->getBody());
}
```

### assertHasElementWithAttributes()

[](#asserthaselementwithattributes)

Assert that an element with the given attributes exists in the given markup.

 (array) $attributes An array of HTML attributes that should be found on the element. (string) $markup The markup that should contain an element with the provided `$attributes`. (string) $message A message to display if the assertion fails.#### Example

[](#example-3)

```
public function testExpectedInputsArePresent()
{
    $user = getUser();
    $form = getFormMarkup();

    $this->assertHasElementWithAttributes(
        [
            'name' => 'first-name',
            'value' => $user->first_name,
        ],
        $form,
        'Did not find the expected input for the user first name.'
    );
}
```

### assertNotHasElementWithAttributes()

[](#assertnothaselementwithattributes)

Assert that an element with the given attributes does not exist in the given markup.

 (array) $attributes An array of HTML attributes that should not be found on the element. (string) $markup The markup that should not contain an element with the provided `$attributes`. (string) $message A message to display if the assertion fails.### assertElementContains()

[](#assertelementcontains)

Assert that the element with the given selector contains a string.

 (string) $contents The string to look for within the DOM node's contents. (string) $selector A query selector for the element to find. (string) $markup The markup that should contain the `$selector`. (string) $message A message to display if the assertion fails.#### Example

[](#example-4)

```
public function testColumnShowsUserEmail()
{
    $user = getUser();
    $table = getTableMarkup();

    $this->assertElementContains(
        $user->email,
        'td.email',
        $table,
        'The  should contain the user\'s email address.'
    );
}
```

### assertElementNotContains()

[](#assertelementnotcontains)

Assert that the element with the given selector does not contain a string.

This method is the inverse of [`assertElementContains()`](#assertelementcontains).

 (string) $contents The string to look for within the DOM node's contents. (string) $selector A query selector for the element to find. (string) $markup The markup that should contain the `$selector`. (string) $message A message to display if the assertion fails.### assertElementRegExp()

[](#assertelementregexp)

Assert that the element with the given selector contains a string.

This method works just like [`assertElementContains()`](#assertelementcontains), but uses regular expressions instead of simple string matching.

 (string) $regexp The regular expression pattern to look for within the DOM node. (string) $selector A query selector for the element to find. (string) $markup The markup that should contain the `$selector`. (string) $message A message to display if the assertion fails.### assertElementNotRegExp()

[](#assertelementnotregexp)

Assert that the element with the given selector does not contain a string.

This method is the inverse of [`assertElementRegExp()`](#assertelementregexp) and behaves like [`assertElementNotContains()`](#assertelementnotcontains) except with regular expressions instead of simple string matching.

 (string) $regexp The regular expression pattern to look for within the DOM node. (string) $selector A query selector for the element to find. (string) $markup The markup that should contain the `$selector`. (string) $message A message to display if the assertion fails.

###  Health Score

51

—

FairBetter than 95% of packages

Maintenance52

Moderate activity, may be stable

Popularity41

Moderate usage in the ecosystem

Community21

Small or concentrated contributor base

Maturity75

Established project with proven stability

 Bus Factor1

Top contributor holds 95.9% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~469 days

Recently: every ~665 days

Total

7

Last Release

357d ago

Major Versions

v1.4.0 → v2.0.02025-07-10

PHP version history (2 changes)v1.3.1PHP ^5.6 || ^7.0 || ^8.0

v2.0.0PHP ^7.1 || ^8.0

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/233836?v=4)[Steve Grunwell](/maintainers/stevegrunwell)[@stevegrunwell](https://github.com/stevegrunwell)

---

Top Contributors

[![stevegrunwell](https://avatars.githubusercontent.com/u/233836?v=4)](https://github.com/stevegrunwell "stevegrunwell (140 commits)")[![jakobbuis](https://avatars.githubusercontent.com/u/949674?v=4)](https://github.com/jakobbuis "jakobbuis (3 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (1 commits)")[![dependabot-preview[bot]](https://avatars.githubusercontent.com/in/2141?v=4)](https://github.com/dependabot-preview[bot] "dependabot-preview[bot] (1 commits)")[![szepeviktor](https://avatars.githubusercontent.com/u/952007?v=4)](https://github.com/szepeviktor "szepeviktor (1 commits)")

---

Tags

phpphpunittestingxpathtestingphpunitdommarkup

###  Code Quality

Static AnalysisPHPStan

Code StylePHP\_CodeSniffer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/stevegrunwell-phpunit-markup-assertions/health.svg)

```
[![Health](https://phpackages.com/badges/stevegrunwell-phpunit-markup-assertions/health.svg)](https://phpackages.com/packages/stevegrunwell-phpunit-markup-assertions)
```

###  Alternatives

[craftcms/cms

Craft CMS

3.6k3.6M3.1k](/packages/craftcms-cms)[phpunit/phpunit

The PHP Unit Testing framework.

20.0k955.1M155.1k](/packages/phpunit-phpunit)[drupal/drupal-extension

Drupal extension for Behat

22215.7M173](/packages/drupal-drupal-extension)[drupal/core-dev

require-dev dependencies from drupal/drupal; use in addition to drupal/core-recommended to run tests from drupal/core.

2022.6M343](/packages/drupal-core-dev)[spatie/phpunit-snapshot-assertions

Snapshot testing with PHPUnit

69619.8M640](/packages/spatie-phpunit-snapshot-assertions)[dg/bypass-finals

Removes final keyword from source code on-the-fly and allows mocking of final methods and classes

57129.2M611](/packages/dg-bypass-finals)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
