gpt4 book ai didi

php - 在命名空间中组织 PHPUnit 测试

转载 作者:IT王子 更新时间:2023-10-29 01:04:10 24 4
gpt4 key购买 nike

我看到了将 PHPUnit 单元测试组织到命名空间层次结构中的两个选项。这两种方法的优点/缺点是什么?是否有任何我没有考虑到的明显缺陷会使一个明显更好的选择?

考虑像 \SomeFramework\Utilities\AwesomeClass 这样的示例类:

  • 方法 1:将每个 TestCase 类放入与被覆盖类相同的命名空间中。

    \SomeFramework\Utilities\AwesomeClassTest
    • 优势
      • 与编写 PHPUnit 测试的传统方法一致。
    • 缺点
      • 灵 active 较低。
      • 似乎打破了使用命名空间背后的原则——不相关的测试被分组到同一个命名空间中。

  • 方法 2: 将每个 TestCase 放置在以覆盖类命名的命名空间中。

    \SomeFramework\Utilities\AwesomeClass\Test
    • 优势
      • 提供一种非常简单/明显的方式将多个相关的 TestCase 类组合在一起,例如针对不同的测试套件。
    • 缺点
      • 可能会导致更深、更复杂的层次结构。

最佳答案

我提出的解决方案及其背后的原因:

文件夹布局:

.
├── src
│   ├── bar
│   │   └── BarAwesomeClass.php
│   └── foo
│   └── FooAwesomeClass.php
└── tests
├── helpers
│   └── ProjectBaseTestClassWithHelperMethods.php
├── integration
│   ├── BarModuleTest.php
│   └── FooModuleTest.php
└── unit
├── bar
│   └── BarAwesomeClassTest.php
└── foo
└── FooAwesomeClassTest.php

helpers/ 文件夹包含不是测试但仅在测试上下文中使用的类。通常该文件夹包含一个 BaseTestClass,可能包含项目特定的辅助方法和几个易于重用的 stub 类,因此您不需要那么多模拟。

integration/ 文件夹包含跨越更多类并测试系统“更大”部分的测试。您没有那么多,但没有 1:1 映射到生产类。

unit/ 文件夹将 1:1 映射到 src/。因此,对于每个生产类,都有一个类包含该类的所有单元测试。

命名空间

Approach 1: Place each TestCase class into the same namespace as the covered class.

这种文件夹方法应该可以解决您使用方法 1 的缺点之一。与纯 1:1 映射相比,您仍然可以灵活地进行更多测试,但一切都已有序且就位。

Seems to break the principle behind using namespaces - unrelated tests are grouped into the same namespace.

如果测试感觉“无关”,可能生产代码有同样的问题?

测试确实不相互依赖,但它们可能会使用它们的“关闭”类作为模拟,或者在 DTO 或值对象的情况下使用真实的类。所以我会说有联系。

Approach 2: Place each TestCase in a namespace named after the covered class.

有几个项目可以做到这一点,但通常它们的结构略有不同:

它不是 \SomeFramework\Utilities\AwesomeClass\Test,而是 \SomeFramework\Tests\Utilities\AwesomeClassTest,它们仍然保持 1:1 映射,但随着添加了额外的测试命名空间。

额外的测试命名空间

我个人的看法是我不喜欢有单独的测试命名空间,我会尝试找到一些支持和反对该选择的论据:

测试应该作为如何使用类的文档

当真正的类在另一个命名空间中时,测试展示了如何在它自己的模块之外使用该类。

当真正的类在同一个命名空间中时,测试会显示如何从该模块内部使用该类。

差异非常小(通常是几个“use”语句或完全限定的路径)

当我们有可能在 PHP 5.5 中使用 $this->getMock(AwesomeClass::CLASS) 而不是 $this->getMock('\SomeFramework\Utilities\AwesomeClass' ) 每个 mock 都需要一个 use 语句。

对我来说,模块内的用法对大多数类来说更有值(value)

污染“生产”命名空间

当你说 new\SomeFramework\Utilities\A 时,自动完成可能会向你显示 AwesomeClassAwesomeClassTest 而有些人不想要那。对于外部使用,或者在运送您的源时,这当然不是问题,因为测试不会运送,但可能需要考虑。

关于php - 在命名空间中组织 PHPUnit 测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12117254/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com