// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= 使用 PHPUnit 和 Selenium 进行测试
:jbake-type: tutorial
:jbake-tags: tutorials 
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: 使用 PHPUnit 和 Selenium 进行测试 - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, 使用 PHPUnit 和 Selenium 进行测试

适用于 PHP 的 NetBeans IDE 支持 link:http://www.phpunit.de[+PHPUnit+] 自动测试。通过 PHPUnit，NetBeans IDE 可为 PHP 提供代码覆盖率，这与 IDE 为 Python 提供的代码覆盖率类似。测试输出将显示在功能丰富的输出窗口中，该窗口与 IDE 的 JUnit 和 Python 测试运行器所使用的输出窗口相同。

NetBeans IDE 还支持将 Selenium 可移植测试框架与 PHPUnit 结合使用。Selenium 插件可以从更新中心获取。安装此插件会将 Selenium 服务器添加到 IDE 的已注册服务器中，并将 Selenium 测试选项添加到 PHP 菜单。


*要学习本教程，您需要具备以下软件和资源。*

|===
|软件或资源 |要求的版本 

|link:https://netbeans.org/downloads/index.html[+NetBeans IDE+] |PHP 下载包 

|PHP 引擎，包括 PEAR |版本 5。 

|Web 服务器 |推荐使用 Apache HTTP Server 2.2。
 

|link:http://www.phpunit.de[+PHPUnit+] |版本 3.4.0 或更高版本。 

|link:http://www.phpunit.de/manual/current/en/skeleton-generator.html[+PHPUnit 的框架生成器+] |作为 PHPUnit 的版本。 
|===


[[installing-phpunit]]
== 安装 PHPUnit

使用 PEAR 安装 PHPUnit（如 link:http://www.phpunit.de/manual/current/en/installation.html[+PHPUnit 文档+]中所述）和 PHPUnit 的框架生成器（如link:http://www.phpunit.de/manual/current/en/skeleton-generator.html[+框架生成器文档+]中所述）。应安装 PHPUnit 版本 3.4.0 或更高版本。无需任何特殊设置。安装 PHPUnit 之后，NetBeans 便可识别它。请注意，您需要将 PEAR 随 PHP 引擎一起安装。另请注意，PHPUnit 文档中指出 PHPUnit 通常会安装到本地 PEAR 目录。该文档还给出了具体的路径： ``/usr/lib/php/PHPUnit`` ；但在适用于 Windows 的 XAMPP 上，此路径为  ``XAMPP_HOME\php\PEAR\PHPUnit`` 。

要检查 NetBeans IDE 是否可以识别您的 PHPUnit 安装，请打开 "Tools"（工具）> "Options"（选项）（在 Mac 上，请打开 "NetBeans Preferences"（NetBeans 首选项））并查看 "PHP" 窗口。打开 "Unit Testing"（单元测试）标签。此时应显示您的 PHPUnit 和框架生成器脚本的路径。如果没有显示脚本，请单击空字段旁边的 "Search"（搜索）。IDE 将在您的本地系统中搜索该脚本。或者，单击 "Browse"（浏览）浏览查找脚本。

image::images/unittesting-options.png[]


[[create-test]]
== 创建并运行 PHPUnit 测试

NetBeans IDE 可以对某个文件中的所有 PHP 类创建并运行 PHPUnit 测试。为确保测试生成器可以正常运行，请为 PHP 文件指定与该文件中的第一类相同的名称。

*为某个类创建并运行 PHPUnit 测试：*

1. 创建一个名为 Calculator 的 PHP 项目。在此项目中，创建一个名为  ``Calculator.php``  的文件。在此文件中，键入或粘贴 link:http://www.phpunit.de/manual/current/en/skeleton-generator.html[+PHPUnit 文档的 "Skeleton Generator"（框架生成器）一章+]中所提供的 Calculator 类。

[source,php]
----

<?php
class Calculator
{
    public function add($a, $b)
    {
        return $a + $b;
    }
}
?>
----

[start=2]
. 添加一个包含 link:http://sebastian-bergmann.de/archives/628-Improved-Skeleton-Generator-in-PHPUnit-3.html[+@assert 标注+]以及一些样例输入和输出的注释块。请注意，本示例中包括一个错误的断言。

[source,php]
----

<?php
class Calculator
{
    /**
     * @assert (0, 0) == 0
     * @assert (0, 1) == 1
     * @assert (1, 0) == 1
     * @assert (1, 1) == 2
     * @assert (1, 2) == 4
     */
    public function add($a, $b)
    {
        return $a + $b;
    }
}
?>
----

*注：*您可以使用标注代码完成来添加 `@assert` 标注。使用 Tab 键在参数之间导航，或者在填写参数值后单击 Enter。

image::images/assert-cc.png[]

image::images/assert-cc-complete.png[]


[start=3]
. 在 "Projects"（项目）窗口中，右键单击 "Calculator.php" 节点，然后选择 "Tools"（工具）> "Create PHPUnit Tests"（创建 PHPUnit 测试）。请注意，您可以在 "Source Files"（源文件）节点的上下文菜单中为项目中的所有文件创建测试。

image::images/create-tests.png[]


[start=4]
. 第一次创建测试时，将会打开一个对话框，询问您要存储测试文件的目录。在本示例中，使用“浏览”功能创建了  ``tests``  目录。 

image::images/test-directory.png[]

*注：*您可以手动为一个项目编写多个测试。如果编写多个测试，可以将它们分类到测试文件目录的子文件夹中，例如 "important" 或 "quick"。然后，可以通过右键单击某个子文件夹并选择 "Run Tests"（运行测试），来运行该文件夹中的测试。

image::images/test-in-folder.png[]


[start=5]
. IDE 在一个名为 CalculatorTest.php 的文件中生成框架测试类，在 "Projects"（项目）窗口中会显示该文件，并在编辑器中将其打开。 

image::images/test-class-in-project.png[]

请注意，将为每个  ``@assert``  标注创建一个测试。


[source,php]
----

    /**
     * Generated from @assert (1, 1) == 2.
     */
    public function testAdd4()
    {
        $this->assertEquals(
          2,
          $this->object->add(1, 1)
        );
    }
----

[start=6]
. 您既可以测试单个文件，也可以测试整个项目。要测试项目，请右键单击项目的父节点，然后选择 "Test"（测试）或按 Alt-F6 组合键。要测试 Calculator.php 文件，请右键单击该文件的节点，然后选择 "Test"（测试），或者按 Ctrl-F6/⌘-F6 组合键。本示例只有一个文件，且该文件中只有一个类，因此两种测试结果相同。IDE 会运行测试并在 "Test Results"（测试结果）窗口中显示结果。 

image::images/test-results-narrow.png[]

测试结果的更详细文本版本会显示在 "Output"（输出）窗口中。

image::images/test-result-output.png[]


== 使用测试组

您可以选择要在测试套件运行期间执行的测试组。例如，可能有一些测试您希望只在生产环境中运行，而另一些测试在生产和开发环境中同时运行。您可以将前一种测试放在  ``production``  组中，而将后一种测试同时放在  ``production``  和  ``development``  组中。在开发环境中运行测试套件时，可以选择只执行  ``development``  测试组。

必须首先对 PHP 项目启用测试组，然后才能对该项目中的所有文件使用测试组。

要将测试标记为测试组的一部分，请使用  ``@group [group name]``  来标注测试方法。

*创建和运行测试组：*

1. 在 "Projects"（项目）窗口中，右键单击 "Calculator" 节点，然后选择 "Properties"（属性）。"Project Properties"（项目属性）打开。
2. 在 "Project Properties"（项目属性）中，选择 "PhpUnit" 类别。选择 "Ask for Test Groups Before Running Tests"（在运行测试之前询问测试组）。单击 "OK"（确定）。

image::images/test-group-properties.png[]


[start=3]
. 在编辑器中打开  ``CalculatorTest.php`` 。

[start=4]
. 为  ``testAdd`` 、 ``testAdd3``  和  ``testAdd5``  方法添加标注  ``@group production`` 。

image::images/production-group-annotation.png[]


[start=5]
. 对于方法  ``testAdd2``  和  ``testAdd4`` ，添加标注  ``@group production``  和  ``@group development`` 。image:images/production-development-group-code.png[]

[start=6]
. 右键单击  ``Calculator.php``  节点，然后选择 "Test"（测试）。此时将会打开一个对话框，询问您要运行哪些测试组。选择 "development"，然后单击 "OK"（确定）。IDE 只运行使用  ``@group development``  标注的测试。

image::images/select-test-group.png[]

有关 NetBeans IDE 中 PhpUnit 测试组的详细信息，请参见 "NetBeans IDE for PHP" 博客帖子：link:http://blogs.oracle.com/netbeansphp/entry/using_phpunit_test_groups[+Using PHP Unit Test Groups+]（使用 PHP 单元测试组）。


[[result-windows]]
== 测试结果和 IDE 输出

PHPUnit 测试的结果会显示在 IDE 的 "Test Results"（测试结果）和 "Output"（输出）两个窗口中。"Test Results"（测试结果）窗口包含一个图形窗格和一个简短文本窗格。“"Output"（输出）窗口提供了输出的更详细文本版本。在此部分，您将详细了解 "Test Results"（测试结果）窗口和 "Output"（输出）窗口。

在 "Test Results"（测试结果）窗口中，您可以从下列位置获取有关失败的测试的信息：

* UI 窗格中失败测试的树条目所附带的消息
* 右侧窗格中的文本，其中包括指向失败的测试代码行的链接
* 将光标悬停在 UI 窗格中失败的测试上时显示的工具提示文本

image::images/test-results-tooltip.png[]

"Test Results"（测试结果）窗口在左侧包括以下按钮：

* 重新运行测试按钮 image:images/rerun-button.png[]
* 显示失败的测试 image:images/show-failed.png[]
* 显示通过的测试 image:images/show-passed.png[]
* 显示通过但出错的测试 image:images/show-error.png[]
* 导航至下一个测试结果的按钮 image:images/next-test-button.png[]，以及导航至上一个测试结果的按钮 image:images/previous-test-button.png[]

"Output"（输出）窗口显示 PHPUnit 脚本的完整输出。当您无法通过 "Test Results"（测试结果）窗口中的信息找出错误原因时，该窗口会非常有用。与 "Test Results"（测试结果）窗口类似，"Output"（输出）窗口包括指向失败的测试类行的链接。它还在左侧包括用于重新运行测试和用于打开 "PHP Options"（PHP 选项）窗口的按钮。image:images/options-link-button.png[]

image::images/test-result-output.png[]


[[code-coverage]]
== 代码覆盖率

适用于 PHP 的 NetBeans IDE 提供了代码覆盖率以及 PHPUnit 支持。（IDE 也为 Python 提供了代码覆盖率）。代码覆盖率检查 PHPUnit 测试是否覆盖了所有方法。在此部分，您将了解如何通过现有 Calculator 类来使用代码覆盖率。

*使用代码覆盖率：*

1. 打开 Calculator.php，然后添加内容与  ``add``  函数相同的  ``add2``  函数。现在， ``Calculator``  类将如下所示：

[source,php]
----

<?php
class Calculator {
    /**
     * @assert (0, 0) == 0
     * @assert (0, 1) == 1
     * @assert (1, 0) == 1
     * @assert (1, 1) == 2
     * @assert (1, 2) == 4
     */
    public function add($a, $b) {
        return $a + $b;
    }

    public function add2($a, $b) {
        return $a + $b;
    }

}    
?>

----

[start=2]
. 右键单击项目节点。从上下文菜单中，选择 "Code Coverage"（代码覆盖率）> "Collect and Display Code Coverage"（收集并显示代码覆盖率）。默认情况下，"Show Editor Bar"（显示编辑器栏）也会处于选定状态。 

image::images/turn-on-code-coverage.png[]


[start=3]
. 现在，编辑器会在底部显示代码覆盖率编辑器栏。由于尚未测试代码覆盖率，因此编辑器栏报告覆盖率为 0%。（在单击 "Clear"（清除）以清除测试结果后，编辑器栏也会显示覆盖率为 0%。） 

image::images/editor-bar-before.png[]


[start=4]
. 单击 "Test"（测试）以测试打开的文件，或单击 "All Tests"（所有测试）以运行项目的所有测试。此时显示 "Test Results"（测试结果）。此外，"Code Coverage"（代码覆盖率）栏会告知您测试所覆盖的可执行代码语句百分比。在编辑器窗口中，覆盖的代码将以绿色突出显示，未覆盖的代码将以红色突出显示。

*警告：*如果在添加 add2 函数之后重新生成测试文件，则不会运行 PHPUnit 测试。这是因为 PHPUnit 创建了两个冲突的 testAdd2 函数。如果您计划对多个此类函数使用 PHPUnit，则不要通过在末尾附加数字的方式来区分函数。请参见 link:http://www.phpunit.de/ticket/701[+PHPUnit 文档+]。

image::images/editor-bar-after.png[]


[start=5]
. 在编辑器栏中，单击 "Report..."（报告...）。代码覆盖率报告打开，其中显示了对项目运行的所有测试的结果。使用报告中的按钮，您可以清除结果，再次运行所有测试或取消激活代码覆盖率（单击 "Done"（完成））。 

image::images/code-coverage-report.png[]


[start=6]
. 您可以在项目中添加其他类；删除测试文件，然后重新创建测试文件；接下来，再次查看代码覆盖率报告。此时将会列出新类。在下面的报告中， ``Calculator``  类又有一个函数未包括在测试中。 

image::images/code-coverage-report2.png[]


[[project-specific-configurations]]
== 使用项目特定的配置

在 IDE 中，可以为项目选择以下定制配置：

* 引导文件
* XML 配置文件
* 测试套件
* 定制 PHPUnit 脚本

*要设置项目特定的配置，请执行以下操作：*

1. 右键单击项目节点或项目的 "Test Files"（测试文件）节点，然后选择 "Properties"（属性）。这会打开 "Properties"（属性）对话框。

image::images/project-ctxmenu.png[]


[start=2]
. 选择 PHPUnit 类别。此时将打开一个对话框，可以在其中选择定制引导、XML 配置、PHPUnit 脚本或测试套件文件。

image::images/proj-properties.png[]


[start=3]
. 如果您不熟悉引导或 XML 配置文件的结构，可以使用 NetBeans IDE 生成框架。您还可以通过单击 "Help"（帮助）查找有关使用该对话框的说明。

image::images/proj-properties-selected.png[]

使用定制类加载器的项目需要_引导选项_，例如，通过实现 Magic 函数  ``__autoload()`` 。如果需要预先包含一个文件（如定义项目中的多个类所使用的全局常量的文件），则也需要使用引导选项。

可通过 _XML 配置文件_定义命令行调用中使用的选项。link:http://www.phpunit.de/manual/3.3/en/appendixes.configuration.html[+PHPUnit 手册+]中进行了完整介绍。还可以使用 XML 配置文件为测试用例定义  ``php.ini``  设置和全局变量。也可以在 XML 配置文件中设置引导选项。

如果设置_定制测试套件_，每次选择 "Run"（运行）> "Test Project"（测试项目）时，都会运行该套件。如果要仅运行一部分测试，或者要使用最近添加（必须手动添加）的 PHPUnit 功能（如数据提供器），该功能特别有用。请注意，您可以根据需要定义多个测试套件，并通过在项目资源管理器中右键单击文件并选择 "run"（运行）来分别运行这些套件。为防止造成混乱，NetBeans 会通知您是否使用定制测试套件。可以在 "Test Results"（测试结果）和 "Output"（输出）窗口中找到通知。

可以将_定制 PHPUnit 脚本_（而非 "Tools"（工具）> "Options"（选项）中所选的默认脚本）用于项目。定制 PHPUnit 脚本可以包含 link:http://www.phpunit.de/manual/3.7/en/textui.html[+PHPUnit 手册+]中描述的任何命令行开关。

 


[[selenium]]
== 在 Selenium 框架上运行测试

Selenium 是一种测试 Web 应用程序框架的可移植软件。这些测试可以编写为 HTML 表，或以各种常用的编程语言进行编码，并且可以直接在目前的多数 Web 浏览器中运行。Selenium 可以部署在 Windows、Linux 和 Macintosh 上。有关更多详细信息，请参见 link:http://docs.seleniumhq.org[+Selenium Web 站点+]。

NetBeans IDE 具有包含 Selenium 服务器的插件。通过此插件，您可以对 PHP、Web 应用程序或 Maven 项目运行 Selenium 测试。要对 PHP 运行 Selenium 测试，需要将 Testing Selenium 软件包安装到 PHP 引擎。

*对 PHP 运行 Selenium 测试：*

1. 打开命令提示符，然后运行  ``pear install Testing_Selenium-beta``  命令。您需要在 Path 变量中包含  ``PHP_HOME/php/PEAR`` 。如果成功运行该命令，则将显示以下提示： ``install ok: channel://pear.php.net/Testing_Selenium-0.4.3`` 。

[start=2]
. 在 IDE 中，打开 "Tools"（工具）> "Plugins"（插件），然后安装 "Selenium Module for PHP"。

[start=3]
. 在 "Projects"（项目）窗口中，右键单击 Calculator 项目的节点。选择 "New"（新建）> "Other"（其他）。此时将打开新建文件向导。选择 "Selenium"，然后单击 "Next"（下一步）。 

image::images/new-selenium.png[]


[start=4]
. 第一次创建 Selenium 测试时，将会打开一个对话框，要求您设置 Selenium 测试文件的目录。此目录应不同于 PHPUnit 测试文件的目录。否则，每次运行单元测试时，Selenium 测试都会运行。运行 Selenium 之类的功能测试通常比运行单元测试所花费的时间长，因此在每次运行单元测试时，您可能不会希望运行这些测试。

[start=5]
. 接受 "Name and Location"（名称和位置）页中的默认设置，然后单击 "Finish"（完成）。新 Selenium 测试文件在编辑器中打开，并在 "Projects"（项目）窗口中显示。 

image::images/selenium-test-in-project.png[]


[start=6]
. 现在，"Run Selenium Tests"（运行 Selenium 测试）项已添加到项目的上下文菜单中。单击此项，Selenium 测试结果随即显示在与 PHPUnit 测试相同的 "Test Results"（测试结果）窗口中。


[[more-exercises]]
== 更多练习

下面是供您探讨的更多思路：

* 向 Calculator.php 中添加第二个类，例如将 $a 和 $b 相乘的  ``Calculator2``  类。删除并重新生成测试。
* 如果尝试学习包含多个部分的link:./wish-list-tutorial-main-page.html[+创建 CRUD 应用程序教程+]，请为最终项目创建 Selenium 测试。
link:/about/contact_form.html?to=3&subject=Feedback:PHPUnit and Selenium on NB 6.7[+发送有关此教程的反馈意见+]


要发送意见和建议、获得支持以及随时了解 NetBeans IDE PHP 开发功能的最新开发情况，请link:../../../community/lists/top.html[+加入 users@php.netbeans.org 邮件列表+]。link:http://forums.netbeans.org/[+NetBeans IDE 论坛+]上提供了此列表的镜像。


== 另请参见

有关在 NetBeans IDE 中测试 PHP 的更多信息，请参见下面的资源：

* link:http://blogs.oracle.com/netbeansphp/entry/phpunit_support_added[+"NetBeans for PHP" 博客：添加的 PHPUnit 支持+]
* link:http://blogs.oracle.com/netbeansphp/entry/ui_for_phpunit_support[+"NetBeans for PHP" 博客：PHPUnit 支持的 UI+]
* link:http://blogs.oracle.com/netbeansphp/entry/code_coverage_for_php_why[+"NetBeans for PHP" 博客：PHP 的代码覆盖率 - 为何不使用？+]
* link:http://blogs.oracle.com/netbeansphp/entry/recent_improvements_in_phpunit_support[+"NetBeans for PHP" 博客：最近在 PHPUnit 支持方面所做的改进+]
* link:http://wiki.netbeans.org/SeleniumPluginPHP[+NetBeans IDE Wiki：适用于 PHP 的 Selenium 插件+]
* link:./debugging.html[+在 NetBeans IDE 中调试 PHP 源代码+]

link:../../trails/php.html[+返回至 PHP 学习资源+]

