chrispenny / silverstripe-data-object-to-fixture
为DataObjects生成YAML测试用例
Requires
- php: ^8.1
- silverstripe/cms: ^5
- silverstripe/framework: ^5
Requires (Dev)
README
从DataObjects生成YAML测试用例
安装
composer require chrispenny/silverstripe-data-object-to-fixture
目的(初期阶段)
此模块(在初期阶段)的目的不是保证每次生成的测试用例都完美,而是提供一个关于测试用例应该是什么样子的坚实指导。
例如:编写单元测试用例可能很困难,特别是当你需要可视化许多不同的DataObjects的结构和关系(如果你使用Fluent等,还需要额外一层)。
我还希望这个模块能与Populate模块很好地配合工作。请注意,但你需要运行版本2.1或更高,因为在此之前的版本不支持循环关系。
目的(未来开发)
我对这个模块的梦想是,我希望达到一个阶段,我们可以有信心地说生成的测试用例每次都是完美的。
从那里,我可以看到这个模块(例如)将被用于测试人员能够通过CMS在他们的测试环境中导出页面,这样那些页面就可以在任何时候通过(可能是)Populate恢复。具体如何操作,以及是否使用Populate,还有待确定。
警告
这仍然处于初期开发阶段。请注意
- 类可能会改变
- 返回类型可能会改变
- 我生成测试用例的方法的整个范式可能会改变
不会改变的内容
- 公共API将不会改变。仍然有一个具有3个主要方法的服务。
我目前不建议您将此模块用于任何关键功能的应用程序,但我强烈建议您将其用作开发工具(例如,帮助您编写自己的测试用例,无论是用于测试还是与Populate一起使用)。
通用用法
开发任务
开发任务可以在/dev/tasks/generate-fixture-from-dataobject
中找到。
此任务允许您为项目中的任何DataObject生成测试用例(输出到屏幕上供您复制粘贴)。
代码使用
// Instantiate the Service. $service = new FixtureService(); // Fetch the DataObject that you wish to generate a fixture for. /** @var Page $page */ $page = Page::get()->byID(1); // Add the DataObject to the Service. $service->addDataObject($dataObject); // Generating the fixture can also generate new warnings $output = $service->outputFixture(); // Check for warnings? This is somewhat important, because if you have looping relationships (which we have no way of // creating fixtures for at the moment) this is how you'll know about it. if (count($service->getWarnings()) > 0) { Debug::dump($service->getWarnings()); } // Do something with the fixture output. highlight_string($output); // Or maybe save the output to a file? $fixture = Director::baseFolder() . '/app/resources/fixture.yml'; file_put_contents($fixture, $service->outputFixture());
从导出中排除类
可能有一些类(如Members?)您不想包含在测试用例中。清单将检查类是否存在(以及真实性)配置变量exclude_from_fixture_relationships
。
您可以在yml文件中设置此变量
SilverStripe\Security\Member: exclude_from_fixture_relationships: 1 SilverStripe\Security\Group: exclude_from_fixture_relationships: 1 SilverStripe\Security\MemberPassword: exclude_from_fixture_relationships: 1 SilverStripe\Security\RememberLoginHash: exclude_from_fixture_relationships: 1
上述示例已在_config/model.yml中设置。如果您想覆盖它们,也可以通过添加自己的yml配置“After”dataobjecttofixturemodel
来实现。例如:
Name: my_dataobjecttofixturemodel After: dataobjecttofixturemodel --- SilverStripe\Security\Member: exclude_from_fixture_relationships: 0
从导出中排除关系
与排除类类似,可能存在一些特定类之间的特定关系需要排除。也许您已经识别出循环关系,并希望排除其中之一以使事物更可预测,或者这可能只是您在固定装置中不需要的关系。
您可以通过将 excluded_fixture_relationships
添加到所需类中,来排除特定关系。
excluded_fixture_relationships
接受一个包含 关系名称 的数组。
例如
class MyModel extends DataObject { private static $has_one = [ 'FeatureImage' => Image::class, ]; }
App\Models\MyModel: excluded_fixture_relationships: - FeatureImage
常见问题
包含在导出中的父页面
当您导出页面时,如果该页面有 父级
,则该 父级
被视为有效关系,因此它将随您选择的页面一起导出。
我仍在考虑如何处理这个问题,但到目前为止,我可能会建议您将 父级
添加到 SiteTree
的排除关系列表中
SilverStripe\CMS\Model\SiteTree: excluded_fixture_relationships: - Parent
节点 [YourClass]
有 [x]
个剩余依赖项,因此无法排序
这通常发生在您有循环关系时。例如:页面
has_one
链接
,而 链接
has_one
回到 页面
。排序器无法确定哪个类应该优先于另一个。
这并不意味着事物会出错,但值得审查。您可能会发现,您可以通过排除其中一个关系来使事物更加一致。
一个好的例子是 Elemental。Elemental 提供了一个名为 TopPage
的扩展,它提供从每个 BaseElement
到它所属的 页面
的直接关系(就像一个“索引”,这样您就可以从 BaseElement
中以更少的数据库查询回溯 页面
)。这对于开发人员来说很方便,但对于 YAML 固定装置来说则不那么方便。我们实际上更希望排除这种关系,并遵循从 页面
到 ElementalArea
到 BaseElement
的正确关系流程。
我可以通过以下配置来排除这种关系
DNADesign\Elemental\Models\BaseElement: excluded_fixture_relationships: - TopPage
生成测试用例时请求超时
以上是两种可以用来尝试减少这种情况的选项。
我建议您首先排除不需要导出的类,然后转向排除可能导致深层嵌套关系的特定关系。
DataObject::get() 不能直接查询非子类DataObject
如果您有多态关系(关系定义为简单的 DataObject::class
),您可能会看到此错误
private static $has_one = [ 'Parent' => DataObject::class, ];
此模块需要知道它正在查询哪个 DataObject
。像 Userforms 这样的模块会这样做,因为您可以技术上用任何模型作为父级。然而,这些模块确实将此关系的类名称存储在单独的字段中,以便我们能够适当地查询父级。对于 Userforms,此关系的类名称存储在名为 ParentClass
的字段中。但是,此模块不知道这一点。
您可以使用以下配置来告诉此模块任何关系的类名称信息所在位置(这里以 Userforms 为例)
SilverStripe\UserForms\Model\EditableFormField: field_classname_map: ParentID: ParentClass
field_classname_map
是我们要填充的配置,它期望一个数组,其中关系字段名称作为 key
,对应的类名称字段作为 value
。
模块使用 relField()
与 value
,因此您可以通过数据字段或方法呈现此信息。
支持的关联关系
has_one
has_many
many_many
(带有和没有through
定义)
流畅支持
我打算在未来支持 Fluent 和导出本地化字段,但目前还没有提供支持。
未来功能
- 添加选项/能力以存储二进制文件,以便可以使用固定装置恢复。
- 告诉我您还需要什么!
此模块目前不执行的事情
- 导出
_Live
表。我希望很快(不久)添加_Live
表导出功能。 - 尚未添加导出/保存资产二进制文件的支持。这意味着在当前状态下,您只能生成资产数据库记录。