<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>unit tests Archives - Developry Plugins</title>
	<atom:link href="https://developryplugins.com/tag/unit-tests/feed/" rel="self" type="application/rss+xml" />
	<link>https://developryplugins.com/tag/unit-tests/</link>
	<description></description>
	<lastBuildDate>Mon, 24 Nov 2025 11:18:16 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://developryplugins.com/wp-content/uploads/2025/11/cropped-favicon-32x32.png</url>
	<title>unit tests Archives - Developry Plugins</title>
	<link>https://developryplugins.com/tag/unit-tests/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>WordPress Plugin Testing: PHPUnit and Automated Testing Guide</title>
		<link>https://developryplugins.com/wordpress-plugin-testing-phpunit-and-automated-testing-guide/</link>
		
		<dc:creator><![CDATA[Krasen Slavov]]></dc:creator>
		<pubDate>Thu, 15 Jan 2026 09:00:00 +0000</pubDate>
				<category><![CDATA[WordPress Plugin Development Guide]]></category>
		<category><![CDATA[automated testing]]></category>
		<category><![CDATA[phpunit]]></category>
		<category><![CDATA[plugin testing]]></category>
		<category><![CDATA[unit tests]]></category>
		<category><![CDATA[wordpress testing]]></category>
		<guid isPermaLink="false">https://developryplugins.com/?p=174</guid>

					<description><![CDATA[<p>Automated testing ensures your WordPress plugin works reliably across updates, prevents regressions, and gives you confidence to refactor code. PHPUnit combined with the WordPress test framework provides a robust solution...</p>
<p>The post <a href="https://developryplugins.com/wordpress-plugin-testing-phpunit-and-automated-testing-guide/">WordPress Plugin Testing: PHPUnit and Automated Testing Guide</a> appeared first on <a href="https://developryplugins.com">Developry Plugins</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p><!-- @format --></p>
<p>Automated testing ensures your WordPress plugin works reliably across updates, prevents regressions, and gives you confidence to refactor code. PHPUnit combined with the WordPress test framework provides a robust solution for testing plugin functionality.</p>
<h2 id="why-test-wordpress-plugins">Why Test WordPress Plugins</h2>
<p>Manual testing becomes impractical as plugins grow. Automated tests catch bugs before users do, document expected behavior, and enable safe refactoring. Tests save time in the long run by preventing regressions and reducing debugging sessions.</p>
<p>Well-tested plugins are more maintainable, easier to collaborate on, and inspire user confidence. Professional development includes comprehensive testing as a standard practice.</p>
<h2 id="understanding-test-types">Understanding Test Types</h2>
<p><strong>Unit Tests:</strong> Test individual functions or methods in isolation. Fast to run and pinpoint specific issues.</p>
<p><strong>Integration Tests:</strong> Test how components work together, including WordPress functions, database operations, and plugin interactions.</p>
<p><strong>Acceptance Tests:</strong> Test complete user workflows from end to end. Slower but verify real-world usage.</p>
<p>For WordPress plugins, you’ll primarily write integration tests since most functionality interacts with WordPress core.</p>
<h2 id="setting-up-phpunit-for-wordpress">Setting Up PHPUnit for WordPress</h2>
<p>Install PHPUnit and set up the WordPress test suite using WP-CLI:</p>
<div class="sourceCode" id="cb1">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb1-1"><a href="#cb1-1" aria-hidden="true"></a><span class="co"># Navigate to your plugin directory</span></span>
<span id="cb1-2"><a href="#cb1-2" aria-hidden="true"></a><span class="bu">cd</span> wp-content/plugins/my-plugin</span>
<span id="cb1-3"><a href="#cb1-3" aria-hidden="true"></a></span>
<span id="cb1-4"><a href="#cb1-4" aria-hidden="true"></a><span class="co"># Generate test scaffolding</span></span>
<span id="cb1-5"><a href="#cb1-5" aria-hidden="true"></a><span class="ex">wp</span> scaffold plugin-tests my-plugin</span>
<span id="cb1-6"><a href="#cb1-6" aria-hidden="true"></a></span>
<span id="cb1-7"><a href="#cb1-7" aria-hidden="true"></a><span class="co"># Install test suite</span></span>
<span id="cb1-8"><a href="#cb1-8" aria-hidden="true"></a><span class="fu">bash</span> bin/install-wp-tests.sh wordpress_test root <span class="st">&#39;&#39;</span> localhost latest</span></code></pre>
</div>
<p>This creates the necessary directory structure:</p>
<pre><code>my-plugin/
├── bin/
│   └── install-wp-tests.sh
├── tests/
│   ├── bootstrap.php
│   └── test-sample.php
├── phpunit.xml.dist
└── .phpcs.xml.dist</code></pre>
<h2 id="writing-your-first-test">Writing Your First Test</h2>
<p>Create a test file in the <code>tests/</code> directory:</p>
<div class="sourceCode" id="cb3">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb3-1"><a href="#cb3-1" aria-hidden="true"></a><span class="kw">&lt;?php</span></span>
<span id="cb3-2"><a href="#cb3-2" aria-hidden="true"></a><span class="kw">class</span> Test_MyPlugin_Functions <span class="kw">extends</span> WP_UnitTestCase {</span>
<span id="cb3-3"><a href="#cb3-3" aria-hidden="true"></a></span>
<span id="cb3-4"><a href="#cb3-4" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_plugin_activated<span class="ot">()</span> {</span>
<span id="cb3-5"><a href="#cb3-5" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertTrue<span class="ot">(</span>is_plugin_active<span class="ot">(</span><span class="st">&#39;my-plugin/my-plugin.php&#39;</span><span class="ot">));</span></span>
<span id="cb3-6"><a href="#cb3-6" aria-hidden="true"></a>    }</span>
<span id="cb3-7"><a href="#cb3-7" aria-hidden="true"></a></span>
<span id="cb3-8"><a href="#cb3-8" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_custom_function_returns_expected_value<span class="ot">()</span> {</span>
<span id="cb3-9"><a href="#cb3-9" aria-hidden="true"></a>        <span class="kw">$result</span> = myplugin_get_greeting<span class="ot">(</span><span class="st">&#39;John&#39;</span><span class="ot">);</span></span>
<span id="cb3-10"><a href="#cb3-10" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertEquals<span class="ot">(</span><span class="st">&#39;Hello, John!&#39;</span><span class="ot">,</span> <span class="kw">$result</span><span class="ot">);</span></span>
<span id="cb3-11"><a href="#cb3-11" aria-hidden="true"></a>    }</span>
<span id="cb3-12"><a href="#cb3-12" aria-hidden="true"></a></span>
<span id="cb3-13"><a href="#cb3-13" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_custom_post_type_registered<span class="ot">()</span> {</span>
<span id="cb3-14"><a href="#cb3-14" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertTrue<span class="ot">(</span>post_type_exists<span class="ot">(</span><span class="st">&#39;myplugin_item&#39;</span><span class="ot">));</span></span>
<span id="cb3-15"><a href="#cb3-15" aria-hidden="true"></a>    }</span>
<span id="cb3-16"><a href="#cb3-16" aria-hidden="true"></a>}</span></code></pre>
</div>
<p>Run tests from your plugin directory:</p>
<div class="sourceCode" id="cb4">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb4-1"><a href="#cb4-1" aria-hidden="true"></a><span class="ex">phpunit</span></span></code></pre>
</div>
<h2 id="phpunit-assertions">PHPUnit Assertions</h2>
<p>Common assertions for testing WordPress plugins:</p>
<div class="sourceCode" id="cb5">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb5-1"><a href="#cb5-1" aria-hidden="true"></a><span class="co">// Equality</span></span>
<span id="cb5-2"><a href="#cb5-2" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertEquals<span class="ot">(</span><span class="kw">$expected</span><span class="ot">,</span> <span class="kw">$actual</span><span class="ot">);</span></span>
<span id="cb5-3"><a href="#cb5-3" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertSame<span class="ot">(</span><span class="kw">$expected</span><span class="ot">,</span> <span class="kw">$actual</span><span class="ot">);</span> <span class="co">// Strict comparison</span></span>
<span id="cb5-4"><a href="#cb5-4" aria-hidden="true"></a></span>
<span id="cb5-5"><a href="#cb5-5" aria-hidden="true"></a><span class="co">// Boolean</span></span>
<span id="cb5-6"><a href="#cb5-6" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertTrue<span class="ot">(</span><span class="kw">$condition</span><span class="ot">);</span></span>
<span id="cb5-7"><a href="#cb5-7" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertFalse<span class="ot">(</span><span class="kw">$condition</span><span class="ot">);</span></span>
<span id="cb5-8"><a href="#cb5-8" aria-hidden="true"></a></span>
<span id="cb5-9"><a href="#cb5-9" aria-hidden="true"></a><span class="co">// Null and Empty</span></span>
<span id="cb5-10"><a href="#cb5-10" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertNull<span class="ot">(</span><span class="kw">$value</span><span class="ot">);</span></span>
<span id="cb5-11"><a href="#cb5-11" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertEmpty<span class="ot">(</span><span class="kw">$array</span><span class="ot">);</span></span>
<span id="cb5-12"><a href="#cb5-12" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertNotEmpty<span class="ot">(</span><span class="kw">$array</span><span class="ot">);</span></span>
<span id="cb5-13"><a href="#cb5-13" aria-hidden="true"></a></span>
<span id="cb5-14"><a href="#cb5-14" aria-hidden="true"></a><span class="co">// Arrays and Strings</span></span>
<span id="cb5-15"><a href="#cb5-15" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertContains<span class="ot">(</span><span class="st">&#39;needle&#39;</span><span class="ot">,</span> <span class="kw">$haystack</span><span class="ot">);</span></span>
<span id="cb5-16"><a href="#cb5-16" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertCount<span class="ot">(</span><span class="dv">5</span><span class="ot">,</span> <span class="kw">$array</span><span class="ot">);</span></span>
<span id="cb5-17"><a href="#cb5-17" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertStringContainsString<span class="ot">(</span><span class="st">&#39;word&#39;</span><span class="ot">,</span> <span class="kw">$string</span><span class="ot">);</span></span>
<span id="cb5-18"><a href="#cb5-18" aria-hidden="true"></a></span>
<span id="cb5-19"><a href="#cb5-19" aria-hidden="true"></a><span class="co">// Instances and Types</span></span>
<span id="cb5-20"><a href="#cb5-20" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertInstanceOf<span class="ot">(</span>WP_Post::<span class="kw">class</span><span class="ot">,</span> <span class="kw">$post</span><span class="ot">);</span></span>
<span id="cb5-21"><a href="#cb5-21" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertIsArray<span class="ot">(</span><span class="kw">$value</span><span class="ot">);</span></span>
<span id="cb5-22"><a href="#cb5-22" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertIsString<span class="ot">(</span><span class="kw">$value</span><span class="ot">);</span></span>
<span id="cb5-23"><a href="#cb5-23" aria-hidden="true"></a></span>
<span id="cb5-24"><a href="#cb5-24" aria-hidden="true"></a><span class="co">// WordPress-specific</span></span>
<span id="cb5-25"><a href="#cb5-25" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertWPError<span class="ot">(</span><span class="kw">$result</span><span class="ot">);</span></span>
<span id="cb5-26"><a href="#cb5-26" aria-hidden="true"></a><span class="kw">$this</span>-&gt;assertNotWPError<span class="ot">(</span><span class="kw">$result</span><span class="ot">);</span></span></code></pre>
</div>
<h2 id="testing-wordpress-functions">Testing WordPress Functions</h2>
<p>Test interactions with WordPress core:</p>
<div class="sourceCode" id="cb6">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb6-1"><a href="#cb6-1" aria-hidden="true"></a><span class="kw">class</span> Test_Post_Functions <span class="kw">extends</span> WP_UnitTestCase {</span>
<span id="cb6-2"><a href="#cb6-2" aria-hidden="true"></a></span>
<span id="cb6-3"><a href="#cb6-3" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_create_custom_post<span class="ot">()</span> {</span>
<span id="cb6-4"><a href="#cb6-4" aria-hidden="true"></a>        <span class="kw">$post_id</span> = wp_insert_post<span class="ot">(</span><span class="kw">array</span><span class="ot">(</span></span>
<span id="cb6-5"><a href="#cb6-5" aria-hidden="true"></a>            <span class="st">&#39;post_title&#39;</span> =&gt; <span class="st">&#39;Test Post&#39;</span><span class="ot">,</span></span>
<span id="cb6-6"><a href="#cb6-6" aria-hidden="true"></a>            <span class="st">&#39;post_type&#39;</span> =&gt; <span class="st">&#39;myplugin_item&#39;</span><span class="ot">,</span></span>
<span id="cb6-7"><a href="#cb6-7" aria-hidden="true"></a>            <span class="st">&#39;post_status&#39;</span> =&gt; <span class="st">&#39;publish&#39;</span></span>
<span id="cb6-8"><a href="#cb6-8" aria-hidden="true"></a>        <span class="ot">));</span></span>
<span id="cb6-9"><a href="#cb6-9" aria-hidden="true"></a></span>
<span id="cb6-10"><a href="#cb6-10" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertGreaterThan<span class="ot">(</span><span class="dv">0</span><span class="ot">,</span> <span class="kw">$post_id</span><span class="ot">);</span></span>
<span id="cb6-11"><a href="#cb6-11" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertEquals<span class="ot">(</span><span class="st">&#39;myplugin_item&#39;</span><span class="ot">,</span> get_post_type<span class="ot">(</span><span class="kw">$post_id</span><span class="ot">));</span></span>
<span id="cb6-12"><a href="#cb6-12" aria-hidden="true"></a>    }</span>
<span id="cb6-13"><a href="#cb6-13" aria-hidden="true"></a></span>
<span id="cb6-14"><a href="#cb6-14" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_post_meta_saved_correctly<span class="ot">()</span> {</span>
<span id="cb6-15"><a href="#cb6-15" aria-hidden="true"></a>        <span class="kw">$post_id</span> = <span class="kw">$this</span>-&gt;factory<span class="ot">()</span>-&gt;post-&gt;create<span class="ot">();</span></span>
<span id="cb6-16"><a href="#cb6-16" aria-hidden="true"></a></span>
<span id="cb6-17"><a href="#cb6-17" aria-hidden="true"></a>        add_post_meta<span class="ot">(</span><span class="kw">$post_id</span><span class="ot">,</span> <span class="st">&#39;_myplugin_rating&#39;</span><span class="ot">,</span> <span class="fl">4.5</span><span class="ot">);</span></span>
<span id="cb6-18"><a href="#cb6-18" aria-hidden="true"></a></span>
<span id="cb6-19"><a href="#cb6-19" aria-hidden="true"></a>        <span class="kw">$rating</span> = get_post_meta<span class="ot">(</span><span class="kw">$post_id</span><span class="ot">,</span> <span class="st">&#39;_myplugin_rating&#39;</span><span class="ot">,</span> <span class="kw">true</span><span class="ot">);</span></span>
<span id="cb6-20"><a href="#cb6-20" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertEquals<span class="ot">(</span><span class="fl">4.5</span><span class="ot">,</span> <span class="kw">$rating</span><span class="ot">);</span></span>
<span id="cb6-21"><a href="#cb6-21" aria-hidden="true"></a>    }</span>
<span id="cb6-22"><a href="#cb6-22" aria-hidden="true"></a>}</span></code></pre>
</div>
<h2 id="using-factories-for-test-data">Using Factories for Test Data</h2>
<p>WordPress test framework includes factories for generating test data:</p>
<div class="sourceCode" id="cb7">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb7-1"><a href="#cb7-1" aria-hidden="true"></a><span class="kw">class</span> Test_With_Factories <span class="kw">extends</span> WP_UnitTestCase {</span>
<span id="cb7-2"><a href="#cb7-2" aria-hidden="true"></a></span>
<span id="cb7-3"><a href="#cb7-3" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_user_can_edit_own_post<span class="ot">()</span> {</span>
<span id="cb7-4"><a href="#cb7-4" aria-hidden="true"></a>        <span class="co">// Create test user</span></span>
<span id="cb7-5"><a href="#cb7-5" aria-hidden="true"></a>        <span class="kw">$user_id</span> = <span class="kw">$this</span>-&gt;factory<span class="ot">()</span>-&gt;user-&gt;create<span class="ot">(</span><span class="kw">array</span><span class="ot">(</span></span>
<span id="cb7-6"><a href="#cb7-6" aria-hidden="true"></a>            <span class="st">&#39;role&#39;</span> =&gt; <span class="st">&#39;author&#39;</span></span>
<span id="cb7-7"><a href="#cb7-7" aria-hidden="true"></a>        <span class="ot">));</span></span>
<span id="cb7-8"><a href="#cb7-8" aria-hidden="true"></a></span>
<span id="cb7-9"><a href="#cb7-9" aria-hidden="true"></a>        <span class="co">// Create test post owned by user</span></span>
<span id="cb7-10"><a href="#cb7-10" aria-hidden="true"></a>        <span class="kw">$post_id</span> = <span class="kw">$this</span>-&gt;factory<span class="ot">()</span>-&gt;post-&gt;create<span class="ot">(</span><span class="kw">array</span><span class="ot">(</span></span>
<span id="cb7-11"><a href="#cb7-11" aria-hidden="true"></a>            <span class="st">&#39;post_author&#39;</span> =&gt; <span class="kw">$user_id</span></span>
<span id="cb7-12"><a href="#cb7-12" aria-hidden="true"></a>        <span class="ot">));</span></span>
<span id="cb7-13"><a href="#cb7-13" aria-hidden="true"></a></span>
<span id="cb7-14"><a href="#cb7-14" aria-hidden="true"></a>        wp_set_current_user<span class="ot">(</span><span class="kw">$user_id</span><span class="ot">);</span></span>
<span id="cb7-15"><a href="#cb7-15" aria-hidden="true"></a></span>
<span id="cb7-16"><a href="#cb7-16" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertTrue<span class="ot">(</span>current_user_can<span class="ot">(</span><span class="st">&#39;edit_post&#39;</span><span class="ot">,</span> <span class="kw">$post_id</span><span class="ot">));</span></span>
<span id="cb7-17"><a href="#cb7-17" aria-hidden="true"></a>    }</span>
<span id="cb7-18"><a href="#cb7-18" aria-hidden="true"></a></span>
<span id="cb7-19"><a href="#cb7-19" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_category_assignment<span class="ot">()</span> {</span>
<span id="cb7-20"><a href="#cb7-20" aria-hidden="true"></a>        <span class="kw">$category_id</span> = <span class="kw">$this</span>-&gt;factory<span class="ot">()</span>-&gt;category-&gt;create<span class="ot">(</span><span class="kw">array</span><span class="ot">(</span></span>
<span id="cb7-21"><a href="#cb7-21" aria-hidden="true"></a>            <span class="st">&#39;name&#39;</span> =&gt; <span class="st">&#39;Test Category&#39;</span></span>
<span id="cb7-22"><a href="#cb7-22" aria-hidden="true"></a>        <span class="ot">));</span></span>
<span id="cb7-23"><a href="#cb7-23" aria-hidden="true"></a></span>
<span id="cb7-24"><a href="#cb7-24" aria-hidden="true"></a>        <span class="kw">$post_id</span> = <span class="kw">$this</span>-&gt;factory<span class="ot">()</span>-&gt;post-&gt;create<span class="ot">();</span></span>
<span id="cb7-25"><a href="#cb7-25" aria-hidden="true"></a></span>
<span id="cb7-26"><a href="#cb7-26" aria-hidden="true"></a>        wp_set_post_categories<span class="ot">(</span><span class="kw">$post_id</span><span class="ot">,</span> <span class="kw">array</span><span class="ot">(</span><span class="kw">$category_id</span><span class="ot">));</span></span>
<span id="cb7-27"><a href="#cb7-27" aria-hidden="true"></a></span>
<span id="cb7-28"><a href="#cb7-28" aria-hidden="true"></a>        <span class="kw">$categories</span> = wp_get_post_categories<span class="ot">(</span><span class="kw">$post_id</span><span class="ot">);</span></span>
<span id="cb7-29"><a href="#cb7-29" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertContains<span class="ot">(</span><span class="kw">$category_id</span><span class="ot">,</span> <span class="kw">$categories</span><span class="ot">);</span></span>
<span id="cb7-30"><a href="#cb7-30" aria-hidden="true"></a>    }</span>
<span id="cb7-31"><a href="#cb7-31" aria-hidden="true"></a>}</span></code></pre>
</div>
<p>Available factories:</p>
<ul>
<li><code>$this-&gt;factory()-&gt;post</code> &#8211; Posts</li>
<li><code>$this-&gt;factory()-&gt;user</code> &#8211; Users</li>
<li><code>$this-&gt;factory()-&gt;comment</code> &#8211; Comments</li>
<li><code>$this-&gt;factory()-&gt;term</code> &#8211; Terms</li>
<li><code>$this-&gt;factory()-&gt;category</code> &#8211; Categories</li>
<li><code>$this-&gt;factory()-&gt;tag</code> &#8211; Tags</li>
</ul>
<h2 id="setup-and-teardown-methods">setUp() and tearDown() Methods</h2>
<p>Prepare test environment before each test and clean up after:</p>
<div class="sourceCode" id="cb8">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb8-1"><a href="#cb8-1" aria-hidden="true"></a><span class="kw">class</span> Test_With_Setup <span class="kw">extends</span> WP_UnitTestCase {</span>
<span id="cb8-2"><a href="#cb8-2" aria-hidden="true"></a></span>
<span id="cb8-3"><a href="#cb8-3" aria-hidden="true"></a>    <span class="kw">protected</span> <span class="kw">$plugin</span><span class="ot">;</span></span>
<span id="cb8-4"><a href="#cb8-4" aria-hidden="true"></a>    <span class="kw">protected</span> <span class="kw">$test_post_id</span><span class="ot">;</span></span>
<span id="cb8-5"><a href="#cb8-5" aria-hidden="true"></a></span>
<span id="cb8-6"><a href="#cb8-6" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> setUp<span class="ot">()</span>: <span class="kw">void</span> {</span>
<span id="cb8-7"><a href="#cb8-7" aria-hidden="true"></a>        parent::setUp<span class="ot">();</span></span>
<span id="cb8-8"><a href="#cb8-8" aria-hidden="true"></a></span>
<span id="cb8-9"><a href="#cb8-9" aria-hidden="true"></a>        <span class="co">// Runs before each test</span></span>
<span id="cb8-10"><a href="#cb8-10" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;plugin = <span class="kw">new</span> MyPlugin<span class="ot">();</span></span>
<span id="cb8-11"><a href="#cb8-11" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;test_post_id = <span class="kw">$this</span>-&gt;factory<span class="ot">()</span>-&gt;post-&gt;create<span class="ot">();</span></span>
<span id="cb8-12"><a href="#cb8-12" aria-hidden="true"></a>    }</span>
<span id="cb8-13"><a href="#cb8-13" aria-hidden="true"></a></span>
<span id="cb8-14"><a href="#cb8-14" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> tearDown<span class="ot">()</span>: <span class="kw">void</span> {</span>
<span id="cb8-15"><a href="#cb8-15" aria-hidden="true"></a>        <span class="co">// Runs after each test</span></span>
<span id="cb8-16"><a href="#cb8-16" aria-hidden="true"></a>        wp_delete_post<span class="ot">(</span><span class="kw">$this</span>-&gt;test_post_id<span class="ot">,</span> <span class="kw">true</span><span class="ot">);</span></span>
<span id="cb8-17"><a href="#cb8-17" aria-hidden="true"></a>        <span class="kw">unset</span><span class="ot">(</span><span class="kw">$this</span>-&gt;plugin<span class="ot">);</span></span>
<span id="cb8-18"><a href="#cb8-18" aria-hidden="true"></a></span>
<span id="cb8-19"><a href="#cb8-19" aria-hidden="true"></a>        parent::tearDown<span class="ot">();</span></span>
<span id="cb8-20"><a href="#cb8-20" aria-hidden="true"></a>    }</span>
<span id="cb8-21"><a href="#cb8-21" aria-hidden="true"></a></span>
<span id="cb8-22"><a href="#cb8-22" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_plugin_initialized<span class="ot">()</span> {</span>
<span id="cb8-23"><a href="#cb8-23" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertInstanceOf<span class="ot">(</span>MyPlugin::<span class="kw">class</span><span class="ot">,</span> <span class="kw">$this</span>-&gt;plugin<span class="ot">);</span></span>
<span id="cb8-24"><a href="#cb8-24" aria-hidden="true"></a>    }</span>
<span id="cb8-25"><a href="#cb8-25" aria-hidden="true"></a></span>
<span id="cb8-26"><a href="#cb8-26" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_post_exists<span class="ot">()</span> {</span>
<span id="cb8-27"><a href="#cb8-27" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertNotNull<span class="ot">(</span>get_post<span class="ot">(</span><span class="kw">$this</span>-&gt;test_post_id<span class="ot">));</span></span>
<span id="cb8-28"><a href="#cb8-28" aria-hidden="true"></a>    }</span>
<span id="cb8-29"><a href="#cb8-29" aria-hidden="true"></a>}</span></code></pre>
</div>
<h2 id="testing-hooks-and-filters">Testing Hooks and Filters</h2>
<p>Verify actions and filters execute correctly:</p>
<div class="sourceCode" id="cb9">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb9-1"><a href="#cb9-1" aria-hidden="true"></a><span class="kw">class</span> Test_Hooks <span class="kw">extends</span> WP_UnitTestCase {</span>
<span id="cb9-2"><a href="#cb9-2" aria-hidden="true"></a></span>
<span id="cb9-3"><a href="#cb9-3" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_action_adds_meta_box<span class="ot">()</span> {</span>
<span id="cb9-4"><a href="#cb9-4" aria-hidden="true"></a>        <span class="kw">global</span> <span class="kw">$wp_meta_boxes</span><span class="ot">;</span></span>
<span id="cb9-5"><a href="#cb9-5" aria-hidden="true"></a></span>
<span id="cb9-6"><a href="#cb9-6" aria-hidden="true"></a>        do_action<span class="ot">(</span><span class="st">&#39;add_meta_boxes&#39;</span><span class="ot">);</span></span>
<span id="cb9-7"><a href="#cb9-7" aria-hidden="true"></a></span>
<span id="cb9-8"><a href="#cb9-8" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertArrayHasKey<span class="ot">(</span><span class="st">&#39;myplugin_meta_box&#39;</span><span class="ot">,</span></span>
<span id="cb9-9"><a href="#cb9-9" aria-hidden="true"></a>            <span class="kw">$wp_meta_boxes</span><span class="ot">[</span><span class="st">&#39;post&#39;</span><span class="ot">][</span><span class="st">&#39;normal&#39;</span><span class="ot">][</span><span class="st">&#39;high&#39;</span><span class="ot">]);</span></span>
<span id="cb9-10"><a href="#cb9-10" aria-hidden="true"></a>    }</span>
<span id="cb9-11"><a href="#cb9-11" aria-hidden="true"></a></span>
<span id="cb9-12"><a href="#cb9-12" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_filter_modifies_title<span class="ot">()</span> {</span>
<span id="cb9-13"><a href="#cb9-13" aria-hidden="true"></a>        add_filter<span class="ot">(</span><span class="st">&#39;the_title&#39;</span><span class="ot">,</span> <span class="st">&#39;myplugin_modify_title&#39;</span><span class="ot">);</span></span>
<span id="cb9-14"><a href="#cb9-14" aria-hidden="true"></a></span>
<span id="cb9-15"><a href="#cb9-15" aria-hidden="true"></a>        <span class="kw">$post_id</span> = <span class="kw">$this</span>-&gt;factory<span class="ot">()</span>-&gt;post-&gt;create<span class="ot">(</span><span class="kw">array</span><span class="ot">(</span></span>
<span id="cb9-16"><a href="#cb9-16" aria-hidden="true"></a>            <span class="st">&#39;post_title&#39;</span> =&gt; <span class="st">&#39;Original Title&#39;</span></span>
<span id="cb9-17"><a href="#cb9-17" aria-hidden="true"></a>        <span class="ot">));</span></span>
<span id="cb9-18"><a href="#cb9-18" aria-hidden="true"></a></span>
<span id="cb9-19"><a href="#cb9-19" aria-hidden="true"></a>        <span class="kw">$title</span> = apply_filters<span class="ot">(</span><span class="st">&#39;the_title&#39;</span><span class="ot">,</span> get_the_title<span class="ot">(</span><span class="kw">$post_id</span><span class="ot">));</span></span>
<span id="cb9-20"><a href="#cb9-20" aria-hidden="true"></a></span>
<span id="cb9-21"><a href="#cb9-21" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertStringContainsString<span class="ot">(</span><span class="st">&#39;Modified&#39;</span><span class="ot">,</span> <span class="kw">$title</span><span class="ot">);</span></span>
<span id="cb9-22"><a href="#cb9-22" aria-hidden="true"></a>    }</span>
<span id="cb9-23"><a href="#cb9-23" aria-hidden="true"></a></span>
<span id="cb9-24"><a href="#cb9-24" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_custom_filter_value<span class="ot">()</span> {</span>
<span id="cb9-25"><a href="#cb9-25" aria-hidden="true"></a>        <span class="kw">$value</span> = apply_filters<span class="ot">(</span><span class="st">&#39;myplugin_custom_filter&#39;</span><span class="ot">,</span> <span class="dv">10</span><span class="ot">);</span></span>
<span id="cb9-26"><a href="#cb9-26" aria-hidden="true"></a></span>
<span id="cb9-27"><a href="#cb9-27" aria-hidden="true"></a>        <span class="co">// Default value</span></span>
<span id="cb9-28"><a href="#cb9-28" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertEquals<span class="ot">(</span><span class="dv">10</span><span class="ot">,</span> <span class="kw">$value</span><span class="ot">);</span></span>
<span id="cb9-29"><a href="#cb9-29" aria-hidden="true"></a></span>
<span id="cb9-30"><a href="#cb9-30" aria-hidden="true"></a>        <span class="co">// Add filter</span></span>
<span id="cb9-31"><a href="#cb9-31" aria-hidden="true"></a>        add_filter<span class="ot">(</span><span class="st">&#39;myplugin_custom_filter&#39;</span><span class="ot">,</span> <span class="kw">function</span><span class="ot">(</span><span class="kw">$val</span><span class="ot">)</span> {</span>
<span id="cb9-32"><a href="#cb9-32" aria-hidden="true"></a>            <span class="kw">return</span> <span class="kw">$val</span> * <span class="dv">2</span><span class="ot">;</span></span>
<span id="cb9-33"><a href="#cb9-33" aria-hidden="true"></a>        }<span class="ot">);</span></span>
<span id="cb9-34"><a href="#cb9-34" aria-hidden="true"></a></span>
<span id="cb9-35"><a href="#cb9-35" aria-hidden="true"></a>        <span class="kw">$filtered_value</span> = apply_filters<span class="ot">(</span><span class="st">&#39;myplugin_custom_filter&#39;</span><span class="ot">,</span> <span class="dv">10</span><span class="ot">);</span></span>
<span id="cb9-36"><a href="#cb9-36" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertEquals<span class="ot">(</span><span class="dv">20</span><span class="ot">,</span> <span class="kw">$filtered_value</span><span class="ot">);</span></span>
<span id="cb9-37"><a href="#cb9-37" aria-hidden="true"></a>    }</span>
<span id="cb9-38"><a href="#cb9-38" aria-hidden="true"></a>}</span></code></pre>
</div>
<h2 id="testing-ajax-functionality">Testing AJAX Functionality</h2>
<p>Test AJAX handlers using WordPress test helpers:</p>
<div class="sourceCode" id="cb10">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb10-1"><a href="#cb10-1" aria-hidden="true"></a><span class="kw">class</span> Test_AJAX <span class="kw">extends</span> WP_Ajax_UnitTestCase {</span>
<span id="cb10-2"><a href="#cb10-2" aria-hidden="true"></a></span>
<span id="cb10-3"><a href="#cb10-3" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_ajax_like_post<span class="ot">()</span> {</span>
<span id="cb10-4"><a href="#cb10-4" aria-hidden="true"></a>        <span class="kw">$post_id</span> = <span class="kw">$this</span>-&gt;factory<span class="ot">()</span>-&gt;post-&gt;create<span class="ot">();</span></span>
<span id="cb10-5"><a href="#cb10-5" aria-hidden="true"></a></span>
<span id="cb10-6"><a href="#cb10-6" aria-hidden="true"></a>        <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;action&#39;</span><span class="ot">]</span> = <span class="st">&#39;myplugin_like_post&#39;</span><span class="ot">;</span></span>
<span id="cb10-7"><a href="#cb10-7" aria-hidden="true"></a>        <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;post_id&#39;</span><span class="ot">]</span> = <span class="kw">$post_id</span><span class="ot">;</span></span>
<span id="cb10-8"><a href="#cb10-8" aria-hidden="true"></a>        <span class="kw">$_POST</span><span class="ot">[</span><span class="st">&#39;nonce&#39;</span><span class="ot">]</span> = wp_create_nonce<span class="ot">(</span><span class="st">&#39;myplugin_like_nonce&#39;</span><span class="ot">);</span></span>
<span id="cb10-9"><a href="#cb10-9" aria-hidden="true"></a></span>
<span id="cb10-10"><a href="#cb10-10" aria-hidden="true"></a>        <span class="kw">try</span> {</span>
<span id="cb10-11"><a href="#cb10-11" aria-hidden="true"></a>            <span class="kw">$this</span>-&gt;_handleAjax<span class="ot">(</span><span class="st">&#39;myplugin_like_post&#39;</span><span class="ot">);</span></span>
<span id="cb10-12"><a href="#cb10-12" aria-hidden="true"></a>        } <span class="kw">catch</span> <span class="ot">(</span>WPAjaxDieContinueException <span class="kw">$e</span><span class="ot">)</span> {</span>
<span id="cb10-13"><a href="#cb10-13" aria-hidden="true"></a>            <span class="co">// Expected exception</span></span>
<span id="cb10-14"><a href="#cb10-14" aria-hidden="true"></a>        }</span>
<span id="cb10-15"><a href="#cb10-15" aria-hidden="true"></a></span>
<span id="cb10-16"><a href="#cb10-16" aria-hidden="true"></a>        <span class="kw">$response</span> = <span class="fu">json_decode</span><span class="ot">(</span><span class="kw">$this</span>-&gt;_last_response<span class="ot">);</span></span>
<span id="cb10-17"><a href="#cb10-17" aria-hidden="true"></a></span>
<span id="cb10-18"><a href="#cb10-18" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertTrue<span class="ot">(</span><span class="kw">$response</span>-&gt;success<span class="ot">);</span></span>
<span id="cb10-19"><a href="#cb10-19" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertEquals<span class="ot">(</span><span class="dv">1</span><span class="ot">,</span> <span class="kw">$response</span>-&gt;data-&gt;likes<span class="ot">);</span></span>
<span id="cb10-20"><a href="#cb10-20" aria-hidden="true"></a>    }</span>
<span id="cb10-21"><a href="#cb10-21" aria-hidden="true"></a>}</span></code></pre>
</div>
<h2 id="testing-database-operations">Testing Database Operations</h2>
<p>Test custom database tables and queries:</p>
<div class="sourceCode" id="cb11">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb11-1"><a href="#cb11-1" aria-hidden="true"></a><span class="kw">class</span> Test_Database <span class="kw">extends</span> WP_UnitTestCase {</span>
<span id="cb11-2"><a href="#cb11-2" aria-hidden="true"></a></span>
<span id="cb11-3"><a href="#cb11-3" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_custom_table_created<span class="ot">()</span> {</span>
<span id="cb11-4"><a href="#cb11-4" aria-hidden="true"></a>        <span class="kw">global</span> <span class="kw">$wpdb</span><span class="ot">;</span></span>
<span id="cb11-5"><a href="#cb11-5" aria-hidden="true"></a></span>
<span id="cb11-6"><a href="#cb11-6" aria-hidden="true"></a>        myplugin_create_custom_table<span class="ot">();</span></span>
<span id="cb11-7"><a href="#cb11-7" aria-hidden="true"></a></span>
<span id="cb11-8"><a href="#cb11-8" aria-hidden="true"></a>        <span class="kw">$table_name</span> = <span class="kw">$wpdb</span>-&gt;prefix . <span class="st">&#39;myplugin_data&#39;</span><span class="ot">;</span></span>
<span id="cb11-9"><a href="#cb11-9" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertEquals<span class="ot">(</span><span class="kw">$table_name</span><span class="ot">,</span></span>
<span id="cb11-10"><a href="#cb11-10" aria-hidden="true"></a>            <span class="kw">$wpdb</span>-&gt;get_var<span class="ot">(</span><span class="st">&quot;SHOW TABLES LIKE &#39;</span><span class="kw">$table_name</span><span class="st">&#39;&quot;</span><span class="ot">));</span></span>
<span id="cb11-11"><a href="#cb11-11" aria-hidden="true"></a>    }</span>
<span id="cb11-12"><a href="#cb11-12" aria-hidden="true"></a></span>
<span id="cb11-13"><a href="#cb11-13" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_insert_custom_data<span class="ot">()</span> {</span>
<span id="cb11-14"><a href="#cb11-14" aria-hidden="true"></a>        <span class="kw">global</span> <span class="kw">$wpdb</span><span class="ot">;</span></span>
<span id="cb11-15"><a href="#cb11-15" aria-hidden="true"></a></span>
<span id="cb11-16"><a href="#cb11-16" aria-hidden="true"></a>        <span class="kw">$table_name</span> = <span class="kw">$wpdb</span>-&gt;prefix . <span class="st">&#39;myplugin_data&#39;</span><span class="ot">;</span></span>
<span id="cb11-17"><a href="#cb11-17" aria-hidden="true"></a></span>
<span id="cb11-18"><a href="#cb11-18" aria-hidden="true"></a>        <span class="kw">$result</span> = <span class="kw">$wpdb</span>-&gt;insert<span class="ot">(</span><span class="kw">$table_name</span><span class="ot">,</span> <span class="kw">array</span><span class="ot">(</span></span>
<span id="cb11-19"><a href="#cb11-19" aria-hidden="true"></a>            <span class="st">&#39;name&#39;</span> =&gt; <span class="st">&#39;Test Item&#39;</span><span class="ot">,</span></span>
<span id="cb11-20"><a href="#cb11-20" aria-hidden="true"></a>            <span class="st">&#39;value&#39;</span> =&gt; <span class="dv">100</span></span>
<span id="cb11-21"><a href="#cb11-21" aria-hidden="true"></a>        <span class="ot">));</span></span>
<span id="cb11-22"><a href="#cb11-22" aria-hidden="true"></a></span>
<span id="cb11-23"><a href="#cb11-23" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertNotFalse<span class="ot">(</span><span class="kw">$result</span><span class="ot">);</span></span>
<span id="cb11-24"><a href="#cb11-24" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertEquals<span class="ot">(</span><span class="dv">1</span><span class="ot">,</span> <span class="kw">$wpdb</span>-&gt;insert_id<span class="ot">);</span></span>
<span id="cb11-25"><a href="#cb11-25" aria-hidden="true"></a>    }</span>
<span id="cb11-26"><a href="#cb11-26" aria-hidden="true"></a>}</span></code></pre>
</div>
<h2 id="mocking-external-api-calls">Mocking External API Calls</h2>
<p>Use pre_http_request filter to mock external APIs:</p>
<div class="sourceCode" id="cb12">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb12-1"><a href="#cb12-1" aria-hidden="true"></a><span class="kw">class</span> Test_External_API <span class="kw">extends</span> WP_UnitTestCase {</span>
<span id="cb12-2"><a href="#cb12-2" aria-hidden="true"></a></span>
<span id="cb12-3"><a href="#cb12-3" aria-hidden="true"></a>    <span class="kw">public</span> <span class="kw">function</span> test_api_call_returns_data<span class="ot">()</span> {</span>
<span id="cb12-4"><a href="#cb12-4" aria-hidden="true"></a>        <span class="co">// Mock the HTTP request</span></span>
<span id="cb12-5"><a href="#cb12-5" aria-hidden="true"></a>        add_filter<span class="ot">(</span><span class="st">&#39;pre_http_request&#39;</span><span class="ot">,</span> <span class="kw">function</span><span class="ot">(</span><span class="kw">$response</span><span class="ot">,</span> <span class="kw">$args</span><span class="ot">,</span> <span class="kw">$url</span><span class="ot">)</span> {</span>
<span id="cb12-6"><a href="#cb12-6" aria-hidden="true"></a>            <span class="kw">if</span> <span class="ot">(</span><span class="fu">strpos</span><span class="ot">(</span><span class="kw">$url</span><span class="ot">,</span> <span class="st">&#39;api.example.com&#39;</span><span class="ot">)</span> !== <span class="kw">false</span><span class="ot">)</span> {</span>
<span id="cb12-7"><a href="#cb12-7" aria-hidden="true"></a>                <span class="kw">return</span> <span class="kw">array</span><span class="ot">(</span></span>
<span id="cb12-8"><a href="#cb12-8" aria-hidden="true"></a>                    <span class="st">&#39;response&#39;</span> =&gt; <span class="kw">array</span><span class="ot">(</span><span class="st">&#39;code&#39;</span> =&gt; <span class="dv">200</span><span class="ot">),</span></span>
<span id="cb12-9"><a href="#cb12-9" aria-hidden="true"></a>                    <span class="st">&#39;body&#39;</span> =&gt; <span class="fu">json_encode</span><span class="ot">(</span><span class="kw">array</span><span class="ot">(</span></span>
<span id="cb12-10"><a href="#cb12-10" aria-hidden="true"></a>                        <span class="st">&#39;status&#39;</span> =&gt; <span class="st">&#39;success&#39;</span><span class="ot">,</span></span>
<span id="cb12-11"><a href="#cb12-11" aria-hidden="true"></a>                        <span class="st">&#39;data&#39;</span> =&gt; <span class="kw">array</span><span class="ot">(</span><span class="st">&#39;value&#39;</span> =&gt; <span class="dv">42</span><span class="ot">)</span></span>
<span id="cb12-12"><a href="#cb12-12" aria-hidden="true"></a>                    <span class="ot">))</span></span>
<span id="cb12-13"><a href="#cb12-13" aria-hidden="true"></a>                <span class="ot">);</span></span>
<span id="cb12-14"><a href="#cb12-14" aria-hidden="true"></a>            }</span>
<span id="cb12-15"><a href="#cb12-15" aria-hidden="true"></a>            <span class="kw">return</span> <span class="kw">$response</span><span class="ot">;</span></span>
<span id="cb12-16"><a href="#cb12-16" aria-hidden="true"></a>        }<span class="ot">,</span> <span class="dv">10</span><span class="ot">,</span> <span class="dv">3</span><span class="ot">);</span></span>
<span id="cb12-17"><a href="#cb12-17" aria-hidden="true"></a></span>
<span id="cb12-18"><a href="#cb12-18" aria-hidden="true"></a>        <span class="kw">$result</span> = myplugin_fetch_external_data<span class="ot">();</span></span>
<span id="cb12-19"><a href="#cb12-19" aria-hidden="true"></a></span>
<span id="cb12-20"><a href="#cb12-20" aria-hidden="true"></a>        <span class="kw">$this</span>-&gt;assertEquals<span class="ot">(</span><span class="dv">42</span><span class="ot">,</span> <span class="kw">$result</span><span class="ot">[</span><span class="st">&#39;value&#39;</span><span class="ot">]);</span></span>
<span id="cb12-21"><a href="#cb12-21" aria-hidden="true"></a>    }</span>
<span id="cb12-22"><a href="#cb12-22" aria-hidden="true"></a>}</span></code></pre>
</div>
<h2 id="code-coverage-analysis">Code Coverage Analysis</h2>
<p>Generate code coverage reports to identify untested code:</p>
<div class="sourceCode" id="cb13">
<pre class="sourceCode bash"><code class="sourceCode bash"><span id="cb13-1"><a href="#cb13-1" aria-hidden="true"></a><span class="ex">phpunit</span> --coverage-html coverage/</span></code></pre>
</div>
<p>View the HTML report in <code>coverage/index.html</code>. Aim for at least 70% coverage for critical code paths.</p>
<p>Configure coverage in <code>phpunit.xml</code>:</p>
<div class="sourceCode" id="cb14">
<pre class="sourceCode xml"><code class="sourceCode xml"><span id="cb14-1"><a href="#cb14-1" aria-hidden="true"></a><span class="kw">&lt;coverage</span><span class="ot"> processUncoveredFiles=</span><span class="st">&quot;true&quot;</span><span class="kw">&gt;</span></span>
<span id="cb14-2"><a href="#cb14-2" aria-hidden="true"></a>    <span class="kw">&lt;include&gt;</span></span>
<span id="cb14-3"><a href="#cb14-3" aria-hidden="true"></a>        <span class="kw">&lt;directory</span><span class="ot"> suffix=</span><span class="st">&quot;.php&quot;</span><span class="kw">&gt;</span>./src<span class="kw">&lt;/directory&gt;</span></span>
<span id="cb14-4"><a href="#cb14-4" aria-hidden="true"></a>    <span class="kw">&lt;/include&gt;</span></span>
<span id="cb14-5"><a href="#cb14-5" aria-hidden="true"></a>    <span class="kw">&lt;exclude&gt;</span></span>
<span id="cb14-6"><a href="#cb14-6" aria-hidden="true"></a>        <span class="kw">&lt;directory&gt;</span>./vendor<span class="kw">&lt;/directory&gt;</span></span>
<span id="cb14-7"><a href="#cb14-7" aria-hidden="true"></a>        <span class="kw">&lt;directory&gt;</span>./tests<span class="kw">&lt;/directory&gt;</span></span>
<span id="cb14-8"><a href="#cb14-8" aria-hidden="true"></a>    <span class="kw">&lt;/exclude&gt;</span></span>
<span id="cb14-9"><a href="#cb14-9" aria-hidden="true"></a><span class="kw">&lt;/coverage&gt;</span></span></code></pre>
</div>
<h2 id="continuous-integration-with-github-actions">Continuous Integration with GitHub Actions</h2>
<p>Automate testing on every commit:</p>
<div class="sourceCode" id="cb15">
<pre class="sourceCode yaml"><code class="sourceCode yaml"><span id="cb15-1"><a href="#cb15-1" aria-hidden="true"></a><span class="co"># .github/workflows/test.yml</span></span>
<span id="cb15-2"><a href="#cb15-2" aria-hidden="true"></a><span class="fu">name</span><span class="kw">:</span><span class="at"> PHPUnit Tests</span></span>
<span id="cb15-3"><a href="#cb15-3" aria-hidden="true"></a></span>
<span id="cb15-4"><a href="#cb15-4" aria-hidden="true"></a><span class="fu">on</span><span class="kw">:</span><span class="at"> </span><span class="kw">[</span><span class="at">push</span><span class="kw">,</span><span class="at"> pull_request</span><span class="kw">]</span></span>
<span id="cb15-5"><a href="#cb15-5" aria-hidden="true"></a></span>
<span id="cb15-6"><a href="#cb15-6" aria-hidden="true"></a><span class="fu">jobs</span><span class="kw">:</span></span>
<span id="cb15-7"><a href="#cb15-7" aria-hidden="true"></a><span class="at">  </span><span class="fu">test</span><span class="kw">:</span></span>
<span id="cb15-8"><a href="#cb15-8" aria-hidden="true"></a><span class="at">    </span><span class="fu">runs-on</span><span class="kw">:</span><span class="at"> ubuntu-latest</span></span>
<span id="cb15-9"><a href="#cb15-9" aria-hidden="true"></a></span>
<span id="cb15-10"><a href="#cb15-10" aria-hidden="true"></a><span class="at">    </span><span class="fu">strategy</span><span class="kw">:</span></span>
<span id="cb15-11"><a href="#cb15-11" aria-hidden="true"></a><span class="at">      </span><span class="fu">matrix</span><span class="kw">:</span></span>
<span id="cb15-12"><a href="#cb15-12" aria-hidden="true"></a><span class="at">        </span><span class="fu">php</span><span class="kw">:</span><span class="at"> </span><span class="kw">[</span><span class="st">&quot;7.4&quot;</span><span class="kw">,</span><span class="at"> </span><span class="st">&quot;8.0&quot;</span><span class="kw">,</span><span class="at"> </span><span class="st">&quot;8.1&quot;</span><span class="kw">]</span></span>
<span id="cb15-13"><a href="#cb15-13" aria-hidden="true"></a><span class="at">        </span><span class="fu">wordpress</span><span class="kw">:</span><span class="at"> </span><span class="kw">[</span><span class="st">&quot;latest&quot;</span><span class="kw">,</span><span class="at"> </span><span class="st">&quot;6.0&quot;</span><span class="kw">]</span></span>
<span id="cb15-14"><a href="#cb15-14" aria-hidden="true"></a></span>
<span id="cb15-15"><a href="#cb15-15" aria-hidden="true"></a><span class="at">    </span><span class="fu">steps</span><span class="kw">:</span></span>
<span id="cb15-16"><a href="#cb15-16" aria-hidden="true"></a><span class="at">      </span><span class="kw">-</span><span class="at"> </span><span class="fu">uses</span><span class="kw">:</span><span class="at"> actions/checkout@v2</span></span>
<span id="cb15-17"><a href="#cb15-17" aria-hidden="true"></a></span>
<span id="cb15-18"><a href="#cb15-18" aria-hidden="true"></a><span class="at">      </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Setup PHP</span></span>
<span id="cb15-19"><a href="#cb15-19" aria-hidden="true"></a><span class="at">        </span><span class="fu">uses</span><span class="kw">:</span><span class="at"> shivammathur/setup-php@v2</span></span>
<span id="cb15-20"><a href="#cb15-20" aria-hidden="true"></a><span class="at">        </span><span class="fu">with</span><span class="kw">:</span></span>
<span id="cb15-21"><a href="#cb15-21" aria-hidden="true"></a><span class="at">          </span><span class="fu">php-version</span><span class="kw">:</span><span class="at"> ${{ matrix.php }}</span></span>
<span id="cb15-22"><a href="#cb15-22" aria-hidden="true"></a></span>
<span id="cb15-23"><a href="#cb15-23" aria-hidden="true"></a><span class="at">      </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Install dependencies</span></span>
<span id="cb15-24"><a href="#cb15-24" aria-hidden="true"></a><span class="at">        </span><span class="fu">run</span><span class="kw">:</span><span class="at"> composer install</span></span>
<span id="cb15-25"><a href="#cb15-25" aria-hidden="true"></a></span>
<span id="cb15-26"><a href="#cb15-26" aria-hidden="true"></a><span class="at">      </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Install WordPress Test Suite</span></span>
<span id="cb15-27"><a href="#cb15-27" aria-hidden="true"></a><span class="at">        </span><span class="fu">run</span><span class="kw">:</span><span class="at"> bash bin/install-wp-tests.sh wordpress_test root root localhost ${{ matrix.wordpress }}</span></span>
<span id="cb15-28"><a href="#cb15-28" aria-hidden="true"></a></span>
<span id="cb15-29"><a href="#cb15-29" aria-hidden="true"></a><span class="at">      </span><span class="kw">-</span><span class="at"> </span><span class="fu">name</span><span class="kw">:</span><span class="at"> Run PHPUnit</span></span>
<span id="cb15-30"><a href="#cb15-30" aria-hidden="true"></a><span class="at">        </span><span class="fu">run</span><span class="kw">:</span><span class="at"> phpunit</span></span></code></pre>
</div>
<h2 id="test-driven-development-tdd">Test-Driven Development (TDD)</h2>
<p>Follow the Red-Green-Refactor cycle:</p>
<ol type="1">
<li><strong>Red:</strong> Write a failing test for new functionality</li>
<li><strong>Green:</strong> Write minimal code to make the test pass</li>
<li><strong>Refactor:</strong> Improve code while keeping tests green</li>
</ol>
<p>Example TDD workflow:</p>
<div class="sourceCode" id="cb16">
<pre class="sourceCode php"><code class="sourceCode php"><span id="cb16-1"><a href="#cb16-1" aria-hidden="true"></a><span class="co">// Step 1: Write failing test</span></span>
<span id="cb16-2"><a href="#cb16-2" aria-hidden="true"></a><span class="kw">public</span> <span class="kw">function</span> test_calculate_discount<span class="ot">()</span> {</span>
<span id="cb16-3"><a href="#cb16-3" aria-hidden="true"></a>    <span class="kw">$result</span> = myplugin_calculate_discount<span class="ot">(</span><span class="dv">100</span><span class="ot">,</span> <span class="dv">10</span><span class="ot">);</span></span>
<span id="cb16-4"><a href="#cb16-4" aria-hidden="true"></a>    <span class="kw">$this</span>-&gt;assertEquals<span class="ot">(</span><span class="dv">90</span><span class="ot">,</span> <span class="kw">$result</span><span class="ot">);</span></span>
<span id="cb16-5"><a href="#cb16-5" aria-hidden="true"></a>}</span>
<span id="cb16-6"><a href="#cb16-6" aria-hidden="true"></a></span>
<span id="cb16-7"><a href="#cb16-7" aria-hidden="true"></a><span class="co">// Step 2: Implement function</span></span>
<span id="cb16-8"><a href="#cb16-8" aria-hidden="true"></a><span class="kw">function</span> myplugin_calculate_discount<span class="ot">(</span><span class="kw">$price</span><span class="ot">,</span> <span class="kw">$discount</span><span class="ot">)</span> {</span>
<span id="cb16-9"><a href="#cb16-9" aria-hidden="true"></a>    <span class="kw">return</span> <span class="kw">$price</span> - <span class="kw">$discount</span><span class="ot">;</span></span>
<span id="cb16-10"><a href="#cb16-10" aria-hidden="true"></a>}</span>
<span id="cb16-11"><a href="#cb16-11" aria-hidden="true"></a></span>
<span id="cb16-12"><a href="#cb16-12" aria-hidden="true"></a><span class="co">// Step 3: Refactor</span></span>
<span id="cb16-13"><a href="#cb16-13" aria-hidden="true"></a><span class="kw">function</span> myplugin_calculate_discount<span class="ot">(</span><span class="kw">$price</span><span class="ot">,</span> <span class="kw">$discount_percent</span><span class="ot">)</span> {</span>
<span id="cb16-14"><a href="#cb16-14" aria-hidden="true"></a>    <span class="kw">return</span> <span class="kw">$price</span> * <span class="ot">(</span><span class="dv">1</span> - <span class="kw">$discount_percent</span> / <span class="dv">100</span><span class="ot">);</span></span>
<span id="cb16-15"><a href="#cb16-15" aria-hidden="true"></a>}</span></code></pre>
</div>
<h2 id="best-practices">Best Practices</h2>
<p><strong>Test Organization:</strong> Group related tests in classes. Use descriptive test method names that explain what’s being tested.</p>
<p><strong>Independence:</strong> Each test should run independently. Don’t rely on test execution order or shared state.</p>
<p><strong>Speed:</strong> Keep tests fast. Use transactions to roll back database changes automatically. Mock external dependencies.</p>
<p><strong>Clarity:</strong> Write clear assertions with helpful failure messages. One logical assertion per test method.</p>
<p><strong>Maintenance:</strong> Update tests alongside code changes. Treat test code with the same care as production code.</p>
<p>Automated testing transforms plugin development from reactive debugging to proactive quality assurance. Invest time in testing now to save exponentially more time later.</p>
<ul>
<li>Why testing WordPress plugins matters</li>
<li>Types of tests: unit, integration, acceptance</li>
<li>Understanding PHPUnit testing framework</li>
<li>Installing PHPUnit for WordPress</li>
<li>WordPress core test suite setup</li>
<li>Creating test scaffolding with WP-CLI</li>
<li>wp scaffold plugin-tests command</li>
<li>Test directory structure</li>
<li>bootstrap.php configuration</li>
<li>Writing your first PHPUnit test</li>
<li>Test case classes extending WP_UnitTestCase</li>
<li>Test method naming conventions</li>
<li>Assertions in PHPUnit</li>
<li>assertEquals(), assertTrue(), assertFalse()</li>
<li>assertCount(), assertEmpty(), assertContains()</li>
<li>Testing WordPress functions and hooks</li>
<li>Testing actions and filters</li>
<li>Mock objects and method stubs</li>
<li>WordPress factory for test data</li>
<li>Creating test posts, users, and terms</li>
<li>setUp() and tearDown() methods</li>
<li>Database transactions in tests</li>
<li>Test fixtures and sample data</li>
<li>Testing AJAX functionality</li>
<li>Testing custom post types</li>
<li>Testing meta boxes and custom fields</li>
<li>Testing shortcodes</li>
<li>Testing widgets</li>
<li>Testing REST API endpoints</li>
<li>Testing database queries</li>
<li>Testing caching logic</li>
<li>Code coverage analysis</li>
<li>Generating coverage reports</li>
<li>Improving test coverage</li>
<li>Test-driven development (TDD) workflow</li>
<li>Writing tests before code</li>
<li>Red-Green-Refactor cycle</li>
<li>Continuous integration setup</li>
<li>GitHub Actions for WordPress testing</li>
<li>Travis CI configuration</li>
<li>GitLab CI/CD pipelines</li>
<li>Automated testing on pull requests</li>
<li>Testing multiple PHP versions</li>
<li>Testing multiple WordPress versions</li>
<li>Integration testing best practices</li>
<li>Mocking external API calls</li>
<li>Performance testing</li>
<li>Debugging failing tests</li>
<li>Common testing pitfalls</li>
<li>Real-world testing examples</li>
</ul>
<p>Includes complete test examples, CI/CD configurations, and best practices for building reliable, well-tested WordPress plugins with comprehensive test coverage.</p>
<h2 id="external-links">External Links</h2>
<ol type="1">
<li><a href="https://phpunit.de/documentation.html">PHPUnit Documentation</a></li>
<li><a href="https://make.wordpress.org/core/handbook/testing/automated-testing/phpunit/">WordPress PHPUnit Test Suite</a></li>
<li><a href="https://developer.wordpress.org/cli/commands/scaffold/plugin-tests/">WP-CLI Testing Commands</a></li>
<li><a href="https://github.com/marketplace?type=actions&amp;query=wordpress">GitHub Actions for WordPress</a></li>
<li><a href="https://develop.svn.wordpress.org/trunk/tests/phpunit/includes/">WordPress Test Library</a></li>
</ol>
<h2 id="call-to-action">Call to Action</h2>
<p>Supercharge your development! <a href="https://acfcopilotplugin.com/">ACF Copilot Pro</a> generates ACF field groups with AI, exports to PHP, and accelerates custom field workflows—try it free!</p>
<p>The post <a href="https://developryplugins.com/wordpress-plugin-testing-phpunit-and-automated-testing-guide/">WordPress Plugin Testing: PHPUnit and Automated Testing Guide</a> appeared first on <a href="https://developryplugins.com">Developry Plugins</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
