[英]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.
所以我的问题很大。
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 项目属性是
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 )
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
不是命名空间
src/MyPack/Foo/Bar.php
contains class MyPack\\Foo\\Bar
src/MyPack/Foo/Bar.php
包含MyPack\\Foo\\Bar
src/MyPack/Quu/Baz.php
contains class MyPack\\Qoo\\Baz
src/MyPack/Quu/Baz.php
包含类MyPack\\Qoo\\Baz
src/Client.php
contains class Client
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;
I used Tools/Create Tests (from context menu) for the Bar
and Baz
classes and I end up with following structure 我使用了工具/创建测试 (来自上下文菜单)为
Bar
和Baz
类,我最终得到了以下结构
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
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执行测试但看起来很难看。
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
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?
他们的自动装载机是否也需要复制?
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风格 。
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.
:)好的,我们来解决一些问题。
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以及错误的测试位置
Folder structure for your project 项目的文件夹结构
Yes, this is the folder structure to work with: 是的,这是要使用的文件夹结构:
src/ … my code tests/ … my tests vendor/ … third-party code
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
的自动加载器并添加src
和test
。 This makes all classes in src
and tests
autoloadable. 这使得
src
和tests
所有类都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.
如果项目安装了开发依赖项,那么这些将成为自动加载的一部分,如果没有,它们将不会出现。
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.
但我想写下它对我有用的方式。
Write and run PHPUnit tests for PHP project with NetBeans IDE 7.4. 使用NetBeans IDE 7.4编写和运行PHP项目的PHPUnit测试。
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"
}
}
Tell NetBeans where the PHPUnit is contained. 告诉NetBeans包含PHPUnit的位置。 I use PHAR files downloaded from https://phar.phpunit.de/
我使用从https://phar.phpunit.de/下载的PHAR文件
tests
directory inside the project directory and use it as Test Folder tests
目录,并将其用作测试文件夹 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库添加到项目中以用于提示目的
Bootstrap file is executed before tests. Bootstrap文件在测试之前执行。 For this project vendor/autoload.php is enough.
对于这个项目vendor / autoload.php就足够了。
The test classes are put in wrong path 测试类放在错误的路径上
I can move them manually 我可以手动移动它们
The tests are run either way. 测试以任何一种方式运行。
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 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.