在本系列的前兩篇文章中,我們從高層次上了解了單元測試是什麼以及如何在插件開發環境中應用它。當然,WordPress 不僅僅是編寫插件,不是嗎? WordPress 開發人員工作的一個重要部分 - 對某些人來說,這是最最重要的部分 - 是主題開發。
因此,在本文中,我們將了解如何開發可測試的主題。具體來說,我們將看看主題與外掛程式有何不同,然後我們將編寫一個極其簡單的主題,用於演示單元測試的原則並可在未來的開發中應用。
在我們開始創建主題或檢查任何程式碼之前,了解主題和外掛程式開發的差異非常重要。首先,外掛程式可以透過兩種方式編寫:
這兩種方法都做同樣的事情:也就是說,它們使用函數和篩選器的集合來為 WordPress 引入新功能。主要區別在於函數的封裝方式。
但是當涉及主題開發時,實際上只有一種方法來開發主題,那就是使用 functions.php 中定義的函數集合。這為編寫主題單元測試帶來了以下兩個挑戰:
因為好的主題使用過濾器和操作的集合,所以我們將創建一個遵循這些最佳實踐的主題,並且因為這篇特定文章的重點在於單元測試主題,所以更多的重點將放在編寫測試而不是創造一個美觀、功能強大的主題。
在編碼之前,讓我們初始化我們的專案目錄。我們需要設定主題的框架,以便在您的 WordPress 主題目錄中為主題建立一個新目錄。我的叫做基本主題。新增以下文件(我們稍後會填寫):
#讓我們繼續刪除樣式表,以便 WordPress 識別主題並允許我們從儀表板中啟動它。為此,請添加以下程式碼:
/* Theme Name: Basic Theme Theme URI: TODO Version: 1.0 Description: A basic theme used to demonstrate how to write unit tests for themes. Author: Tom McFarlin Author URI: https://tommcfarlin.com License: GNU General Public License v2.0 License URI: http://www.gnu.org/licenses/gpl-2.0.html */
為了完整,請繼續將 PHP 開始和結束標記新增到函數檔案的開頭和結尾。這將確保我們在本文後面開始編寫主題函數時奠定基礎。
並新增一個名為tests的新目錄。在這裡,我們需要進行 WordPress 測試。
在本系列的前面,我提供了位於 GitHub 上的 WordPress 測試的連結。儘管這些測試很好用,但最新的、Automattic 維護的 WordPress 測試位於此 Subversion 儲存庫中。
如果您是高級開發人員,那麼我建議您查看這些測試;但是,如果您剛開始進行單元測試 – 沒問題!我在 GitHub 儲存庫中提供了所有原始程式碼(包括 WordPress 測試),您可以下載、引用並將其用於您自己的專案。
安裝測試後,您的主題目錄應如下所示:
#由於PHPUnit 必須從命令列執行,因此您需要開啟終端會話(或命令提示字元),導航至tests 目錄,然後您應該能夠執行它們使用以下命令(作為範例):
phpunit tests/test_user_capabilities.php
你的終端應該輸出如下內容:
此时,让我们继续激活仪表板中的主题。主题应该激活(如果没有激活,请确保模板文件中没有任何杂散字符)。如果您尝试查看主题,它自然会显示白屏。
在编写任何测试之前,让我们继续使用一些内容填充我们的模板文件,以便我们可以在前端显示一些内容。
在header.php中,添加以下代码:
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <link rel="profile" href="http://gmpg.org/xfn/11" /> <link rel="pingback" href="<?php bloginfo( 'pingback_url' ); ?>" /> <title><?php wp_title( '' ); ?></title> <?php wp_head(); ?> </head> <body <?php body_class(); ?>> <div id="header"> This is the header. </div><!-- /#header -->
在index.php中,添加以下代码:
<?php get_header(); ?> <div id="content"> This is the content. </div><!-- /#content --> <?php get_footer(); ?>
并在footer.php中添加以下代码:
<div id="footer"> This is the footer. </div><!-- /#footer --> </body> </html>
很简单,我知道,但这足以让我们在开始编写测试时使用。保存您的工作,在浏览器中查看主题,您应该会看到以下内容:
在您的 tests 目录中,创建一个名为 test_basic_theme.php 的文件,并对该文件进行存根处理,如下所示:
// Include the functions for the theme include_once('../functions.php'); class Test_Basic_Theme extends WP_UnitTestCase { } // end class
上面,我们定义了一个类,用于包装所有主题的单元测试。
首先,我们定义 setUp
方法。 setUp
方法是 WordPress 测试框架提供的函数,我们可以使用它在测试运行之前触发某些函数。例如,当 WordPress 测试运行时,它们会针对默认主题(即“211”)运行。在我们的例子中,我们希望针对我们自己的主题运行测试。
为此,我们需要告诉 WordPress 在运行其余测试之前实际切换主题。由于这需要在测试运行之前发生,因此需要在 setUp
方法中定义。有道理吗?
所以让我们编写 setUp
方法:
function setUp() { parent::setUp(); switch_theme( 'Basic Theme', 'Basic Theme' ); } // end setup
再次执行我们的测试。我们可以通过运行与最初设置测试时相同的命令来完成此操作:
phpunit tests/test_basic_theme.php
如果您已正确完成所有操作,那么在测试运行时您实际上应该会看到失败:
但错误消息很明确:“在类“Test_Basic_Theme”
”中找不到测试。因此,让我们减轻这种情况并为主题编写第一个测试。它可以是非常简单的事情,但请记住上一篇文章中我们不想只测试最佳路径,而是还要测试失败路径。
因此,我们需要测试基本主题是否处于活动状态以及“211”是否处于活动状态。为此,我们将使用assertTrue 方法和assertFalse 方法,并且我们将在两个函数的上下文中执行此操作。查看下面的代码并相应地更新您的测试文件:
function testActiveTheme() { $this->assertTrue( 'Basic Theme' == get_current_theme() ); } // end testThemeInitialization function testInactiveTheme() { $this->assertFalse( 'Twenty Eleven' == get_current_theme() ); } // end testInactiveTheme
再次执行测试,您应该看到它们运行绿色。不错,对吧?
这是一个相对简单的功能,因此让我们考虑一下我们的主题可以具有的一些高级功能。
开箱即用的基本主题不包含 jQuery,因此我们将其包含在我们的主题中。如果您还记得之前的帖子,正确的单元测试方法如下:
那么,让我们对 jQuery 执行此操作。
首先,我们需要编写一个测试来确定 jQuery 是否已加载。我们将使用 WordPress 函数 wp_script_is。由于主题在浏览器中经历正常的页面生命周期,因此我们需要使用 do_action 函数手动告诉 WordPress 加载 jQuery。
function testjQueryIsLoaded() { $this->assertFalse( wp_script_is( 'jquery' ) ); do_action( 'wp_enqueue_scripts' ); $this->assertTrue( wp_script_is( 'jquery' ) ); } // end testjQueryIsLoaded
在我们进一步讨论之前,这里有一些重要的事情需要注意:我不喜欢在一个函数中放置多个断言,因为我认为每个函数应该用于测试一个目的;然而,也有例外。在这里,我们需要确保在调用 do_action
之前未加载 jQuery。
无论如何,运行测试都会失败。因此,我们需要将代码添加到 functions.php 中,以确保将 jQuery 添加到我们的主题中。为此,请在函数文件中包含以下函数:
function basic_add_jquery() { wp_enqueue_script( 'jquery' ); } // end basic_remove_jquery add_action( 'wp_enqueue_scripts', 'basic_add_jquery' );
最后,运行测试,它应该是绿色的。很简单,不是吗?
假设我们想要在主页上包含默认元描述。在最简单的情况下,它只不过是博客的描述。因此,按照上面概述的方法,我们引入一个函数来测试添加到 head 元素的元描述字符串是否符合我们的预期:
function testBasicMetaDescription() { $meta_description = '<meta name="description" content="' . get_bloginfo( 'description' ) . '" />'; $this->expectOutputString( $meta_description, basic_meta_description() ); } // end testBasicMetaDescription
运行它——它会失败。请注意,我没有使用标准 assertTrue
、assertFalse
函数 - 稍后会有更多详细信息。现在,我们将以下函数引入到functions.php中:
function basic_meta_description() { echo '<meta name="description" content="' . get_bloginfo( 'description' ) . '" />'; } // end basic_meta_description add_action( 'wp_head', 'basic_meta_description' );
请注意,此函数挂钩到 wp_head
操作。为了将元描述写入 head 元素,我们必须回显字符串,而不是返回字符串。
现在,请注意,在上面的测试中,我们使用的是 expectOutputString
。当我们需要评估一个回显一个字符串(而不是返回一个字符串)的函数时,这非常有用。由于 wp_head
操作将返回大量数据(即整个 head 元素),因此我们实际上只需要评估返回的元描述。这就是为什么我不调用 do_action( 'wp_head' )
,而是简单地调用函数本身并根据我期望的结果评估输出。
再次运行 PHPUnit,您的测试应该全部通过。
显然,我们只是触及了单元测试对主题开发的表面作用。还有很多东西可以测试 - 我们甚至还没有考虑过测试 The Loop、评估帖子格式的各种方法,甚至还没有考虑如何检查评论。
请记住,这是一本初学者指南,这三篇文章涵盖了很多内容。
无论如何,原则是相同的:问题是确保以编程方式触发适当的函数或操作,并在预期和意外情况下评估其输出。
最后,您可以在此 GitHub 存储库中找到整个项目以及记录的函数。
以下是本文中使用的资源的摘要:
assertTrue
assertFalse
wp_script_is
do_action
wp_head
expectOutputString
以上是建立可測試主題:單元測試初學者指南的詳細內容。更多資訊請關注PHP中文網其他相關文章!