简体   繁体   English

如何使用NetBeans IDE组织PHPUnit测试和自动加载

[英]How to organize PHPUnit tests and autoloading with NetBeans IDE

There are rules for autoloading ( http://www.php-fig.org/psr/psr-0/ ) and PHPunit testing ( https://phpunit.de/manual/current/en/organizing-tests.html ). 有自动加载规则( http://www.php-fig.org/psr/psr-0/ )和PHPunit测试( https://phpunit.de/manual/current/en/organizing-tests.html )。 Separetely they are easy to implement but combining them is not. 它们很容易实现,但结合它们并不容易。

I have also read topic a PHPUnit best practices to organize tests but applying the answer is not obvious for me. 我还阅读了一个PHPUnit组织测试的最佳实践主题,但应用答案对我来说并不明显。 Writing my own project I have had several problems that probably have the same origins in code organization. 编写我自己的项目我遇到了几个可能在代码组织中起源相同的问题。 I wish I could have recipes for a real simple example. 我希望我能得到一个真实简单例子的食谱。 Therefore I make my question quite big. 所以我的问题很大。

Example project 示例项目

I use NetBeans IDE 7.4 because it supports PHPUnit, SVN and Doxygen (but I lack experience of using that IDE). 我使用NetBeans IDE 7.4,因为它支持PHPUnit,SVN和Doxygen(但我缺乏使用该IDE的经验)。

Project Properties are 项目属性

  • Project Folder : C:\\xampp\\htdocs\\myapps\\PhpProject1 项目文件夹 :C:\\ xampp \\ htdocs \\ myapps \\ PhpProject1
  • Source Folder : C:\\xampp\\htdocs\\myapps\\PhpProject1 源文件夹 :C:\\ xampp \\ htdocs \\ myapps \\ PhpProject1
  • Test Folder : C:\\xampp\\htdocs\\myapps\\PhpProject1\\tests 测试文件夹 :C:\\ xampp \\ htdocs \\ myapps \\ PhpProject1 \\ tests

There is the first problem. 有第一个问题。 NetBeans blocks the mirror src/tests structure from the beginning. NetBeans从一开始就阻止镜像src / tests结构。 There is no Browse button for Source Folder . 源文件夹没有“ 浏览”按钮。 The Test folder must be different from Source folder . Test文件夹必须与Source文件夹不同。

I use PHPUnit and skelgen from PHAR files located outside the project. 我使用位于项目外部的PHAR文件中的PHPUnit和skelgen。 ( Tools->Options->PHP/PHPUnit ) 工具 - >选项 - > PHP / PHPUnit

  • PHPUnit Script : C:\\xampp\\phar\\phpunit.phar PHPUnit脚本 :C:\\ xampp \\ phar \\ phpunit.phar
  • Skeleton Generator Script : C:\\xampp\\phar\\phpunit-skelgen-1.2.1.phar Skeleton Generator脚本 :C:\\ xampp \\ phar \\ phpunit-skelgen-1.2.1.phar

I have the following file structure in the project directory 我在项目目录中有以下文件结构

index.php
src/
    Client.php
    srcAutoload.php
    MyPack/
        Foo/
            Bar.php
        Quu/
            Baz.php

Where src is not a namespace since 其中src不是命名空间

  • file src/MyPack/Foo/Bar.php contains class MyPack\\Foo\\Bar file src/MyPack/Foo/Bar.php包含MyPack\\Foo\\Bar
  • file src/MyPack/Quu/Baz.php contains class MyPack\\Qoo\\Baz 文件src/MyPack/Quu/Baz.php包含类MyPack\\Qoo\\Baz
  • file src/Client.php contains class Client file src/Client.php包含类Client

srcAutoload.php contains the modified PSR-0 autoload implementation from https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md . srcAutoload.php包含来自https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md的修改后的PSR-0自动加载实现。 The difference is that before doing require() the PSR-0 filename is prefixed with src/ 不同之处在于,在执行require()之前,PSR-0文件名以src/为前缀

$fileName = 'src' . DIRECTORY_SEPARATOR . $fileName;

Test Generation and Autoloading Trouble 测试生成和自动加载问题

I used Tools/Create Tests (from context menu) for the Bar and Baz classes and I end up with following structure 我使用了工具/创建测试 (来自上下文菜单)为BarBaz类,我最终得到了以下结构

index.php
src/
    Client.php
    srcAutoload.php
    MyPack/
        Foo/
            Bar.php
        Quu/
            Baz.php
tests/
    src/
        BarTest.php
        BazTest.php
        MyPack/
           Foo/
           Quu/

That definitely is not mirror symmetric. 这绝对不是镜像对称的。 Moreover, generated tests don't know how to load the classes they are testing. 而且,生成的测试不知道如何加载他们正在测试的类。

Fatal error: Class 'MyPack\Foo\Bar' not found in C:\xampp\htdocs\myapps\PhpProject1\tests\src\BarTest.php on line 20

My Workaround for Autoloading 我自动加载的解决方法

As stated before, the test runner has different working directory than the project. 如前所述,测试运行器具有与项目不同的工作目录。 So the autoloader for testing should create different full filename. 因此,用于测试的自动加载器应该创建不同的完整文件名。 I have duplicated PSR-0 autoloader, save it as tests/srcAutoloadFromTests.php and added another prefix 我有重复的PSR-0自动加载器,将其保存为tests/srcAutoloadFromTests.php并添加了另一个前缀

/// after PSR-0 implementation code 
/// I have PSR-0 $fileName

/* Escaping from tests subfolder by "../" prefix*/ 
$fromTests = '..' . DIRECTORY_SEPARATOR;

/* Prefixing full filename with "src/" */ 
$fileName = $fromTests . 'src' . DIRECTORY_SEPARATOR . $fileName;

if (is_file($fileName)) {
    require $fileName;
}

Afterwards, I have added Use Bootstrap (Project Properties->Testing/PHPUnit ). 之后,我添加了Use Bootstrap (Project Properties-> Testing / PHPUnit )。 File tests/bootstrap.php contains: 文件tests/bootstrap.php包含:

require_once 'srcAutoloadFromTests.php';

This solution makes PHPUnit executing tests but looks ugly to me. 这个解决方案让PHPUnit执行测试但看起来很难看。

More specific questions 更具体的问题

Why the mirroring src/ in tests/ is not helping for autoloading? 为什么镜像src/ in tests/没有帮助自动加载?

I have manually created mirrored structure by creating correct folders and moving files: 我通过创建正确的文件夹和移动文件手动创建了镜像结构:

index.php
src/
    Client.php
    srcAutoload.php
    MyPack/
        Foo/
            Bar.php
        Quu/
            Baz.php
tests/
    bootstrap.php
    srcAutoloadFromTests.php
    MyPack/
        Foo/
            BarTest.php
        Quu/
            BazTest.php

According to https://phpunit.de/manual/current/en/organizing-tests.html PHPUnit can automatically discover and run the tests by recursively traversing the test directory . 根据https://phpunit.de/manual/current/en/organizing-tests.html,PHPUnit 可以通过递归遍历测试目录自动发现并运行测试 It does not work for me. 它对我不起作用。 Without my srcAutoloadFromTests.php I get the same error as for the former non-mirrored structure. 如果没有我的srcAutoloadFromTests.php我会得到与之前的非镜像结构相同的错误。

Fatal error: Class 'MyPack\Foo\Bar' not found in C:\xampp\htdocs\myapps\PhpProject1_1\tests\MyPack\Foo\BarTest.php on line 20

What about the duplication of autoloading code 如何重复自动加载代码

Because NetBeans does not allow use Source Folder as a Test Folder, I must have two autoloaders for the same class. 由于NetBeans不允许将源文件夹用作测试文件夹,因此我必须为同一个类使用两个自动加载器。 I'm not sure if it is a good practice. 我不确定这是不是一个好习惯。

Autoloading should not bother other programmers working same project. 自动加载不应该打扰其他程序员工作相同的项目。 I look for something more generic . 我寻找更通用的东西。

Besides in the future I could use third-party code. 除了将来我还可以使用第三方代码。 Would their autoloaders also need duplication? 他们的自动装载机是否也需要复制?

Should the src/ and tests/ folders be top-level as vendor/ src/tests/文件夹应该是顶级的vendor/

I have been learning the autoloading rules some time ago. 我不久前一直在学习自动加载规则。 Now I find out that PSR-0 is marked as deprecated According to PSR-4 src/ and tests/ should be placed somewhere in the middle of the path. 现在我发现PSR-0被标记为已弃用根据PSR-4 src/tests/应该放在路径中间的某个位置。

But there is a practice to put the third-party code inside the top-level vendor/ folder. 但是有一种做法是将第三方代码放在顶级vendor/文件夹中。 Shouldn't the src/ and tests/ folders be placed on the same level. 不应该将src/tests/文件夹放在同一级别上。

src/
   … my code
tests/
   … my tests 
vendor/
   … third-party code

that makes the entire structure more PSR-0 style . 这使整个结构更加PSR-0风格

No Hinting PHPUnit in NetBeans 没有在NetBeans中提示PHPUnit

While writing BazTest and BarTest code the NetBeans IDE does not hint PHPUnit methods although both class extend \\PHPUnit_Framework_TestCase 在编写BazTest和BarTest代码时,NetBeans IDE不会提示PHPUnit方法,尽管这两个类都扩展了\\PHPUnit_Framework_TestCase

namespace MyPack\Foo;

class BarTest extends \PHPUnit_Framework_TestCase { /* ... */ }

Is it because I use PHPUnit from PHAR? 是因为我使用PHAR的PHPUnit吗?

I hope citing the example made my questions more clear. 我希望引用这个例子让我的问题更清楚。 Thank you for reading and I look for good advices 感谢您阅读,我寻求好的建议

Man, what a big question. 伙计,这是个大问题。 :) Ok, let's address some of the issues. :)好的,我们来解决一些问题。

  1. PHPUnit Skelgen tests in wrong path PHPUnit Skelgen在错误的路径上测试

    That definitely is not mirror symmetric 这绝对不是镜像对称的

    True. 真正。 It's an odd (and i think unresolved) path issue with skelgen. skelgen是一个奇怪的(我认为尚未解决的)路径问题。

    Just move the generated *Test files into their correct folders. 只需将生成的* Test文件移动到正确的文件夹中即可。

    Same question over here: PHPUnit, Netbeans and Symfony2 and wrong tests location 同样的问题在这里: PHPUnit,Netbeans和Symfony2以及错误的测试位置

  2. Folder structure for your project 项目的文件夹结构

    Yes, this is the folder structure to work with: 是的,这是要使用的文件夹结构:

     src/ … my code tests/ … my tests vendor/ … third-party code 
  3. The autoloading issue: 自动加载问题:

    (Without Composer): your autoloader lives somewhere in src . (没有Composer):你的自动加载器住在src某个地方。 During your application bootstrap your require it, after that autoloading is setup for the src folder. 在您的应用程序引导期间,您需要它,然后为src文件夹设置自动加载。 All classes in the src folder are from now on autoloaded. src文件夹中的所有类从现在开始自动加载。

    Now over to tests: during the test bootstrap you include the autoloader from src and add src and test . 现在进行测试:在测试引导期间,你包括来自src的自动加载器并添加srctest This makes all classes in src and tests autoloadable. 这使得srctests所有类都tests自动加载。

    (with Composer): This whole issue gets a non-issue, if you work with Composer. (使用Composer):如果您使用Composer,则整个问题都不会出现问题。 Composer has require and require-dev sections to define the vendor dependencies. Composer有require和require-dev部分来定义供应商依赖关系。 The autoloading is generated automatically, you simply include the Composer autoload file and done (one inclusion during src bootstrap and one inclusion during test boostrap). 自动生成自动加载,您只需包含Composer自动加载文件并完成(在src bootstrap期间包含一个包含,在测试boostrap期间包含一个包含)。 If the project is installed with development dependencies then those will be part of the autoloading, if not, they will not appear. 如果项目安装了开发依赖项,那么这些将成为自动加载的一部分,如果没有,它们将不会出现。

  4. No Hinting PHPUnit in NetBeans 没有在NetBeans中提示PHPUnit

    Yes, the PHAR is not introspected or extracted, so Netbeans will not know the Class names of PHPUnit. 是的,PHAR没有被内省或提取,因此Netbeans不会知道PHPUnit的类名。

    Solution 1: Extract the PHAR. 解决方案1:提取PHAR。

    Solution 2: Add a PHP with classnames as aliases to guide Netbeans. 解决方案2:添加带有类名作为别名的PHP来指导Netbeans。 I don't know if one is around. 我不知道是否有人。 But it's a pretty common issue, chances are high that someone created it already. 但这是一个非常普遍的问题,有人创造它的可能性很高。

    Solution 3: Let me suggest Composer again: just pull phpunit as require-dev dependency into your project. 解决方案3:让我再次建议Composer:只需将phpunit作为require-dev依赖项添加到您的项目中。 The vendor path is scanned by Netbeans and the classnames will resolve. Netbeans扫描供应商路径,类名将解析。

The answer of Jens A. Koch was very helpful. Jens A. Koch的答案非常有帮助。 But I'd like to write they way it worked for me. 但我想写下它对我有用的方式。

Task 任务

Write and run PHPUnit tests for PHP project with NetBeans IDE 7.4. 使用NetBeans IDE 7.4编写和运行PHP项目的PHPUnit测试。

Project 项目

The structure of the project 项目的结构

composer.json
index.php
src/
   Client.php
   MyPack/
      Foo/
         Bar.php

where 哪里

  • src/Client.php contains class defined in the global namespace src/Client.php包含在全局命名空间中定义的类
  • src/MyPack/Foo/Bar.php contains class defined in the MyPack\\Foo namespace src/MyPack/Foo/Bar.php包含MyPack\\Foo命名空间中定义的类
  • composer.json declares requirements, ie PHPUnit, PHPUnit Skeleton Generator and autoladers for classes defined in the src/ and tests/ directories composer.json声明了需求,即PHPUnit,PHPUnit Skeleton Generator和src/tests/目录中定义的类的自动装配器

composer.json

{
    "name": "vendor/php-project-with-tests",
    "autoload": {
        "psr-4": { 
            "": ["src/", "tests/"]
        }
    },
    "require": {},
    "require-dev": {
        "phpunit/phpunit": "4.7.7",
        "phpunit/phpunit-skeleton-generator": "2.0.1"
    }
}

Steps 脚步

1. Set Tools 1.设置工具

Tell NetBeans where the PHPUnit is contained. 告诉NetBeans包含PHPUnit的位置。 I use PHAR files downloaded from https://phar.phpunit.de/ 我使用从https://phar.phpunit.de/下载的PHAR文件

  1. Select menu option Tools -> Options , 选择菜单选项工具 - >选项
  2. Choose PHP , and choose PHPUnit tab 选择PHP ,然后选择PHPUnit选项卡
  3. Set scripts: 设置脚本:
    • PHPUnit Script: MY_PATH\\phpunit-4.7.7.phar PHPUnit脚本:MY_PATH \\ phpunit-4.7.7.phar
    • Skeleton Generator Script: MY_PATH\\phpunit-skelgen-1.2.1.phar Skeleton Generator脚本:MY_PATH \\ phpunit-skelgen-1.2.1.phar

2. Set the directory for tests 2.设置测试目录

  1. Right-click on the project name, choose Properties from context menu 右键单击项目名称,从上下文菜单中选择“ 属性”
  2. Categories: Sources 分类:来源
    • Test Folder is initially empty 测试文件夹最初为空
    • Browse Button 浏览按钮
    • Create tests directory inside the project directory and use it as Test Folder 在项目目录中创建tests目录,并将其用作测试文件夹

3. Set tests provider 3.设置测试提供者

  1. Right-click the project name, choose Properties from context menu 右键单击项目名称,从上下文菜单中选择“ 属性”
  2. Categories: Testing 分类:测试
    • Testing Providers: check PHPUnit 测试提供商:检查PHPUnit

4. Generate test classes 4.生成测试类

  1. Right-click the class file (eg Bar.php), choose Tools -> Create Tests from the context menu 右键单击类文件(例如Bar.php),从上下文菜单中选择“ 工具” - >“创建测试

5. Install dependencies 5.安装依赖项

  1. Right-click the project name, choose Composer -> Install (dev) from context menu 右键单击项目名称,从上下文菜单中选择Composer - > Install(dev)

That achieves two goals: - generate autoloader, to allow test classes use the src classes - add PHPUnit library to the project for hinting purposes 这实现了两个目标: - 生成自动加载器,允许测试类使用src类 - 将PHPUnit库添加到项目中以用于提示目的

6. Set bootstrap file 6.设置引导程序文件

Bootstrap file is executed before tests. Bootstrap文件在测试之前执行。 For this project vendor/autoload.php is enough. 对于这个项目vendor / autoload.php就足够了。

  1. Right-click the project name, choose Properties from context menu 右键单击项目名称,从上下文菜单中选择“ 属性”
  2. Categories: Testing/PHPUnit 分类:测试/ PHPUnit
    • check Use Bootstrap 选中使用Bootstrap
    • Bootstrap: PROJECT_MAIN_DIR\\vendor\\autoload.php Bootstrap:PROJECT_MAIN_DIR \\ vendor \\ autoload.php

Project structure 项目结构

The test classes are put in wrong path 测试类放在错误的路径上

在此输入图像描述

I can move them manually 我可以手动移动它们

在此输入图像描述

The tests are run either way. 测试以任何一种方式运行。

Troubles 故障

PHPUnit 4.8 is not working PHPUnit 4.8不起作用

The PHPUnit of version 4.8.0 and 4.8.6 dont' work. 版本4.8.0和4.8.6的PHPUnit不起作用。 I get message unrecognized option --run 我收到消息unrecognized option --run

So I must use PHPUnit 4.7.7 所以我必须使用PHPUnit 4.7.7

PHPUnit Skeleton Generator 2.0.1 is not working PHPUnit Skeleton Generator 2.0.1不能正常工作

PHPUnit Skeleton Generator 2.0.1 cannot generate tests. PHPUnit Skeleton Generator 2.0.1无法生成测试。 I get message [InvalidArgumentException] Commans "MyPack\\Foo\\Bar" is not defined 我收到消息[InvalidArgumentException] Commans“MyPack \\ Foo \\ Bar”未定义

So i must use PHPUnit Skeleton Generator 1.2.1 所以我必须使用PHPUnit Skeleton Generator 1.2.1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM