沙尘暴 / e2etesttools
Requires
- guzzlehttp/psr7: *
- neos/utility-files: *
- symfony/css-selector: ^5.2 || ^6.0
- symfony/dom-crawler: ^5.2 || ^6.0
Suggests
- neos/behat: ^6.1 || dev-master
- neos/flow: *
- dev-main
- 8.3.1
- 8.3.0
- 8.2.0
- 1.2.0
- 1.1.0
- 1.0.3
- 1.0.2
- 1.0.1
- 1.0.0
- dev-24-bug-i-click-the-document-tree-entry-documenttitle-not-working-with-neos-83
- dev-bugfix/remove-policy-yaml-for-acl-add-readme
- dev-feature/12-persistent-resource-fixtures
- dev-feature/feedback-from-retreat-2022
- dev-bugfix/add-tags-to-be-ignored-during-reflection
- dev-feature/playwright-tracing
- dev-feature/add-more-steps-for-neos-be-and-general-requests
This package is auto-updated.
Last update: 2024-09-23 14:14:31 UTC
README
... 用于 Neos 和 Flow 项目。
对于 SYMFONY 项目,请参阅 README.Symfony.md。
我们使用 Playwright 作为测试涉及真实浏览器的浏览器调度器。我们使用 Behat 作为编写所有类型 BDD 测试的测试框架。
-
使用 Behat 测试 Fusion 代码的方法
-
用于集成 Playwright 浏览器调度器和 Behat 测试框架的实用工具
架构
我们建议您大致浏览这部分内容,以了解整体架构的概述。只要您不进行深入修改,您不需要详细阅读。
运行行为测试的架构如下
╔╦══════════════════╦╗ 1 ┌────────────────────┐
║│Behat Test Runner ├╬──────▶ E2E-Testrunner │
║└──────────────────┘║ │(Playwright Server -│
║ Application Docker ║ │ Chrome Browser) │
║ Container (SUT) ║◀─────┤ │
╚══════════╦═════════╝ 2 └────────────────────┘
│
3│
┌──────────▼─────────┐
│other services (DB, │
│ Redis, ...) │
└────────────────────┘
-
我们将 Behat 测试运行器添加到开发或生产 App Docker 容器(SUT - 系统测试对象),这样 Behat 测试运行器就可以访问应用程序的任何代码,并具有与生产应用程序完全相同的环境、数据库和库版本。
-
E2E 测试运行器包装 Playwright(这是一个浏览器调度器)并公开 HTTP API。它作为相关服务运行。Behat 通过 HTTP 与测试运行器通信(1)。
-
然后,测试运行器通过 HTTP 调用未修改的应用程序(2)。
-
然后,应用程序调用其他服务,如 Redis 和数据库 - 就像通常一样。
然而,有一个需要注意的问题,它具有重大影响:端到端测试需要完全控制数据库才能可靠地运行。由于我们不希望在每次运行测试时清除我们的开发数据库,因此我们需要使用两个数据库:一个用于测试,另一个用于开发。
此外,端到端测试需要通过 HTTP 请求到达连接到 测试环境 的系统。这意味着我们还需要两个网络服务器端口:一个用于开发,一个用于测试上下文。
此设置有些复杂;因此以下图像有助于说明在开发时间和生产/CI 期间不同上下文之间的交互
Main Development Web Behat CLI
Server (usually port Web Server used by (bin/behat)
8080) Behat Tests (usually │
Port 9090) │
│ │
│ ┌────────────────┐ │
│ │ │ │
│ ▼ │ ▼
│ ╔═════════════════════════╗ ╔══════════════════════════╗
###### ####### # # │ ║Development/Docker/Behat ║ ║ Testing/Behat Context ║
# # # # # │ ║ Context ║ ║ ║
# # # # # │ ║ ║ ║ behat tests executed as ║
# # ##### # # │ ║ only overrides the ║ ║ this context; so config ║
# # # # # │ ║ database name ║ ║ should match ║
# # # # # │ ╚═════════════════════════╝ ║ Development/Docker/Behat ║
###### ####### # │ ║ ║
▼ ║ ║
╔══════════════════════════════════╗ ║ ║
║ Development/Docker Context ║ ║ ║
║ ║ ║ ║
║ contains the main configuration ║ ║ ║
║ for DEV ║ ║ ║
╚══════════════════════════════════╝ ╚══════════════════════════╝
Main Production Web Behat CLI
Server (usually port Web Server used by (bin/behat)
8080) Behat Tests (usually │
Port 9090) │
│ │
│ ┌────────────────┐ │
│ │ │ │
##### ### │ ▼ │ ▼
# # # │ ╔═════════════════════════╗ ╔══════════════════════════╗
# # │ ║Production/Kubernetes/Beh║ ║ Testing/Behat Context ║
# # │ ║ at Context ║ ║ ║
# # │ ║ ║ ║ behat tests executed as ║
# # # │ ║ only overrides the ║ ║ this context; so config ║
##### ### │ ║ database name ║ ║ should match ║
│ ╚═════════════════════════╝ ║Development/Kubernetes/Beh║
│ ║ at ║
▼ ║ ║
╔══════════════════════════════════╗ ║ ║
║ Development/Kubernetes Context ║ ║ ║
║ ║ ║ ║
║ contains the main configuration ║ ║ ║
║ for PROD ║ ║ ║
╚══════════════════════════════════╝ ╚══════════════════════════╝
安装和设置说明
对于希望将 BDD 集成到项目中的人来说,这是必读的。
composer require sandstorm/e2etesttools @dev
./flow behat:setup
./flow behat:kickstart Your.SitePackageKey http://127.0.0.1:8081
rm bin/selenium-server.jar # we do not need this
-
您可以删除
behat.yml
并只保留behat.yml.dist
-
在
behat.yml.dist
中,完全删除Behat\MinkExtension
部分。Mink 是一个通用的 "浏览器控制器 API",根据我们的经验,它使用起来有些脆弱,并增加了不必要的复杂性。我们建议直接使用 Playwright。
-
您应该配置 Flow/Neos 的
Configuration/Testing/Behat/Settings.yaml
并将生产Settings.yaml
复制到其中;以确保 Behat 访问与生产应用程序相同的数据库。 -
您应该创建一个
Configuration/Development/Docker/Behat/Settings.yaml
,其内容如下
Neos: Flow: persistence: backendOptions: dbname: '%env:DB_NEOS_DATABASE_E2ETEST%'
- 您应该创建一个
Configuration/Production/Kubernetes/Behat/Settings.yaml
,其内容如下
Neos: Flow: persistence: backendOptions: dbname: '%env:DB_NEOS_DATABASE_E2ETEST%'
设置 Playwright
我们建议将此包中的Resources/Private/e2e-testrunner-template
复制到Git仓库的根目录,并将文件夹命名为e2e-testrunner
(在我们的项目中,通常位于Neos根目录的上一个级别)。
此外,您还需要以下.gitlab-ci.yml
文件以进行构建。
package_app: stage: build image: docker-hub.sandstorm.de/docker-infrastructure/php-app/build:7.4-v2 interruptible: true script: - cd app # NOTE: for E2E tests we HAVE also to install DEV dependencies; otherwise we won't be able to run behavioral tests then. - COMPOSER_CACHE_DIR=.composer-cache composer install --dev --ignore-platform-reqs - cd .. # set up Behat - mkdir -p app/Build && cp -R app/Packages/Application/Neos.Behat/Resources/Private/Build/Behat app/Build/Behat - cd app/Build/Behat && COMPOSER_CACHE_DIR=../../.composer-cache composer install && cd ../../../ # build image - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY - docker build -t $CI_REGISTRY_IMAGE:$CI_BUILD_REF_SLUG . - docker push $CI_REGISTRY_IMAGE:$CI_BUILD_REF_SLUG tags: - docker - privileged cache: key: PROJECTNAME__composer paths: - app/.composer-cache build_e2e_testrunner: stage: build image: docker-hub.sandstorm.de/docker-infrastructure/php-app/build:7.4-v2 interruptible: true script: - cd e2e-testrunner - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN $CI_REGISTRY - docker build -t $CI_REGISTRY_IMAGE:$CI_BUILD_REF_SLUG-e2e-testrunner . - docker push $CI_REGISTRY_IMAGE:$CI_BUILD_REF_SLUG-e2e-testrunner - cd .. tags: - docker - privileged
然后,为了运行测试,您需要在.gitlab-ci.yml
中添加类似以下片段。
每个相关服务(如redis、数据库等)都需要使用services
条目启动。确保服务的Docker镜像版本与docker-compose.yml
中的开发和生产镜像相匹配。
作业的环境变量将传递给所有服务 - 因此,所有连接的服务和主作业共享相同的环境变量。因此,您需要将SUT(即主作业)和所有相关服务的环境变量添加到测试作业的variables
部分。
e2e_test: stage: test interruptible: true # we're running this job inside the production image we've just built previously image: name: $CI_REGISTRY_IMAGE:$CI_BUILD_REF_SLUG # we may need to override the entrypoint here entrypoint: [ "" ] dependencies: [ ] # we do not need any artifacts from prior steps variables: # service mariadb MYSQL_USER: 'ci_user' MYSQL_PASSWORD: 'ci_db_password' MYSQL_DATABASE: 'ci_test' # System under Test FLOW_CONTEXT: 'Production/Kubernetes' DB_NEOS_HOST: 'mariadb' DB_NEOS_PORT: '3306' DB_NEOS_USER: '${MYSQL_USER}' DB_NEOS_PASSWORD: '${MYSQL_PASSWORD}' DB_NEOS_DATABASE: '${MYSQL_DATABASE}' services: - name: mariadb:10.5 # here, we make the e2e-testrunner available - name: $CI_REGISTRY_IMAGE:$CI_BUILD_REF_SLUG-e2e-testrunner alias: e2e-testrunner script: # ADJUST: the following lines must be adjusted to match the *entrypoint* - cd /app && ./flow doctrine:migrate # make E2E Test Server available (port 9090) - ln -s /etc/nginx/nginx-e2etest-server-prod.conf /etc/nginx/conf.d/nginx-e2etest-server-prod.conf - /bin/sh /start.sh & # the playwright API URL does not need to be adjusted as long as the service alias for playwright is `e2e-testrunner`. - export PLAYWRIGHT_API_URL=http://e2e-testrunner:3000 # ADJUST: you might need to adjust the SUT URL; and the wait URL below - export SYSTEM_UNDER_TEST_URL_FOR_PLAYWRIGHT=http://$(hostname -i):9090 - | # now wait until system under test is up and running until $(curl --output /dev/null --silent --head --fail http://127.0.0.1:9090); do printf '.' sleep 5 done # actually run the tests # ADJUST: use your pacakge key here - cd /app && rm -Rf e2e-results && mkdir e2e-results && bin/behat --format junit --out e2e-results --format pretty --out std -c Packages/Application/PACKAGEKEY/Tests/Behavior/behat.yml.dist - cp -R /app/e2e-results $CI_PROJECT_DIR/e2e-results - cp -R /app/Web/styleguide $CI_PROJECT_DIR/styleguide artifacts: expire_in: 4 weeks paths: - e2e-results - styleguide reports: junit: e2e-results/behat.xml
创建 FeatureContext
FeatureContext
是包含Behat场景步骤定义的PHP类。我们提供了您应用于各种功能的基本特质。FeatureContext
的骨架应如下所示
<?php use Behat\Behat\Context\Context; use Neos\Behat\Tests\Behat\FlowContextTrait; use Neos\ContentRepository\Tests\Behavior\Features\Bootstrap\NodeOperationsTrait; use Neos\Flow\ObjectManagement\ObjectManagerInterface; use Neos\Flow\Tests\Behavior\Features\Bootstrap\SecurityOperationsTrait; use Sandstorm\E2ETestTools\Tests\Behavior\Bootstrap\FusionRenderingTrait; use Sandstorm\E2ETestTools\Tests\Behavior\Bootstrap\PlaywrightTrait; require_once(__DIR__ . '/../../../../../../Packages/Application/Neos.Behat/Tests/Behat/FlowContextTrait.php'); require_once(__DIR__ . '/../../../../../../Packages/Application/Neos.ContentRepository/Tests/Behavior/Features/Bootstrap/NodeOperationsTrait.php'); require_once(__DIR__ . '/../../../../../../Packages/Framework/Neos.Flow/Tests/Behavior/Features/Bootstrap/SecurityOperationsTrait.php'); require_once(__DIR__ . '/../../../../../../Packages/Application/Sandstorm.E2ETestTools/Tests/Behavior/Bootstrap/FusionRenderingTrait.php'); require_once(__DIR__ . '/../../../../../../Packages/Application/Sandstorm.E2ETestTools/Tests/Behavior/Bootstrap/PlaywrightTrait.php'); class FeatureContext implements Context { // This is for integration with Flow (so you have access to $this->objectManager of Flow). (part of Neos.Behat) use FlowContextTrait; // prerequisite of NodeOperationsTrait (part of Neos.Flow) use SecurityOperationsTrait; // create Nodes etc. in Behat tests (part of Neos.ContentRepository) use NodeOperationsTrait { // take overridden "iHaveTheFollowingNodes" from FusionRenderingTrait FusionRenderingTrait::iHaveTheFollowingNodes insteadof NodeOperationsTrait; } // Render Fusion code and Styleguide (part of Sandstorm.E2ETestTools) use FusionRenderingTrait; // Browser Automation use PlaywrightTrait; /** * @var ObjectManagerInterface */ protected $objectManager; public function __construct() { if (self::$bootstrap === null) { self::$bootstrap = $this->initializeFlow(); } $this->objectManager = self::$bootstrap->getObjectManager(); $this->setupSecurity(); $this->setupPlaywright(); // !!! You need to add the Site Package Key here, so that we are able to load the Fusion code properly. $this->setupFusionRendering('Site.Package.Key.Here'); // !!! Important for usage with Neos: you need to publish resources that are created from fixtures $this->PersistentResourceTrait_registerResourcePersistedHook(function () { // publish resources post persist hook for PersistentResources created by fixtures // execute a: './flow resource:publish' }); } /** * @return ObjectManagerInterface */ public function getObjectManager(): ObjectManagerInterface { return $this->objectManager; } }
加载 Styleguide 的 CSS 和 JavaScript
在您的Fusion代码中,将页面的JavaScript和CSS添加到Sandstorm.E2ETestTools:StyleguideStylesheets
和Sandstorm.E2ETestTools:StyleguideJavascripts
原型中,例如以下方式
prototype(Sandstorm.E2ETestTools:StyleguideStylesheets) {
headerAssets = PACKAGEKEY:Resources.HeaderAssets
}
此外,还需要正确配置基本URL。此包在
Testing/Behat
上下文中将其设置为"/",在大多数情况下会自动工作。
运行 Behat 测试
本部分是每个人必读的。我们建议将此部分复制到您项目的readme中。
首先,您需要在您的开发机上启动Playwright Server。为此,转到Git仓库中的e2e-testrunner
,然后执行以下操作
npm install node index.js # now, the server is running on localhost:3000. # Keep the server running as long as you want to execute Behavioral Tests. You can leave the server # running for a very long time (e.g. a day).
其次,确保Docker容器正在运行;通常通过docker-compose build && docker-compose up -d
。然后,进入neos
容器:docker-compose exec neos /bin/bash
,在容器内运行以下命令
./flow behat:setup bin/behat -c Packages/Sites/[SITEPACKAGE_NAME]/Tests/Behavior/behat.yml.dist
Behat还支持运行单个测试或单个文件 - 它们需要在配置文件之后指定,例如
# run all scenarios in a given folder bin/behat -c Packages/Sites/[SITEPACKAGE_NAME]/Tests/Behavior/behat.yml.dist Packages/Sites/[SITEPACKAGE_NAME]/Tests/Behavior/Features/Fusion/ # run all scenarios in the single feature file bin/behat -c Packages/Sites/[SITEPACKAGE_NAME]/Tests/Behavior/behat.yml.dist Packages/Sites/[SITEPACKAGE_NAME]/Tests/Behavior/Features/WebsiteRendering.feature # run the scenario starting at line 27 bin/behat -c Packages/Sites/[SITEPACKAGE_NAME]/Tests/Behavior/behat.yml.dist Packages/Sites/[SITEPACKAGE_NAME]/Tests/Behavior/Features/WebsiteRendering.feature:27
如果出现异常,使用--stop-on-failure
运行测试可能很有帮助,这将在第一个错误处停止测试用例。然后,您可以检查测试数据库并手动重现错误。
此外,-vvv
是一个有用的CLI标志(额外详细) - 它在出现错误时显示完整的异常堆栈跟踪。
关于如何编写Behat测试的提示,我们建议阅读Sandstorm.E2ETestTools README。
风格指南
如果您使用样式指南功能(例如Then I store the Fusion output in the styleguide as "Button_Component_Basic"
),则测试需要用@playwright
进行注解,并且Playwright开发服务器需要正在运行。
然后,您可以通过127.0.0.1:8080/styleguide/访问样式指南。样式指南包含HTML快照和HTML的渲染图像。
编写 Behat 测试
在这里,我们尝试提供常见Behat场景的示例,以便您可以轻松开始。
Fusion 组件测试用例
您可以使用以下测试用例来测试组件 - 类似于您通常使用Monocle所做的。
一些提示
- 我们需要设置一个最小的节点树,否则我们无法渲染链接。
@fixtures @playwright Feature: Testcase for Button Component Background: Given I have a site for Site Node "site" Given I have the following nodes: | Identifier | Path | Node Type | Properties | Language | | 5cb3a5f7-b501-40b2-b5a8-9de169ef1105 | /sites | unstructured | {} | de | | 5e312d5b-9559-4bd2-8251-0182e11b4950 | /sites/site | PACKAGEKEY:Document.Page | {} | de | | 9cbaa2e2-d779-4936-aa02-0dab324da93e | /sites/site/nested | PACKAGEKEY:Document.Page | {"uriPathSegment": "nested"} | de | Given I get a node by path "/sites/site" with the following context: | Workspace | Dimension: language | | live | de | Scenario: Basic Button (external link) When I render the Fusion object "/testcase" with the current context node: """ testcase = PACKAGEKEY:Component.Button { text = "External Link" link = "https://spiegel.de" isExternalLink = true } """ Then in the fusion output, the inner HTML of CSS selector "a" matches "External Link" Then in the fusion output, the attributes of CSS selector "a" are: | Key | Value | | class | button | | href | https://spiegel.de | | target | _blank | Then I store the Fusion output in the styleguide as "Button_Component_Basic"
Fusion 集成测试用例
特别有价值的是,不仅要测试Fusion组件(这或多或少像是一个纯函数),而是测试给定的节点以某种方式渲染 - 这样就可以正确设置节点与Fusion组件之间的连接。
一个测试用例可以像以下这样
@fixtures @playwright Feature: Testcase for Button Integration Background: Given I have a site for Site Node "site" Given I have the following nodes: | Identifier | Path | Node Type | Properties | Language | | 5cb3a5f7-b501-40b2-b5a8-9de169ef1105 | /sites | unstructured | {} | de | | 5e312d5b-9559-4bd2-8251-0182e11b4950 | /sites/site | PACKAGEKEY:Document.Page | {} | de | | 9cbaa2e2-d779-4936-aa02-0dab324da93e | /sites/site/nested | PACKAGEKEY:Document.Page | {"uriPathSegment": "nested"} | de | Scenario: Secondary Button Given I create the following nodes: | Path | Node Type | Properties | Language | | /sites/site/main/testnode | PACKAGEKEY:Content.Button | {"type": "secondary", "link": "node://9cbaa2e2-d779-4936-aa02-0dab324da93e"} | de | Given I get a node by path "/sites/site/main/testnode" with the following context: | Workspace | Dimension: language | | live | de | When I render the Fusion object "/testcase" with the current context node: """ testcase = PACKAGEKEY:Content.Button """ Then in the fusion output, the attributes of CSS selector "a" are: | Key | Value | | href | /de/nested | Then I store the Fusion output in the styleguide as "Button_Integration_Secondary"
全页快照测试用例
这个测试用例测试的是完整页面的渲染,而不仅仅是单个组件。它主要用于视觉检查;而且,你很可能不会使用特定的断言。
在这种情况下,渲染依赖于更多的节点,因此设置包含所有相关节点的behat fixture可能有点繁琐。幸运的是,这个包中有一些助手可以帮助这个过程。我们建议编写一个像下面的CommandController
<?php namespace PACKAGEKEY\Command; use Neos\ContentRepository\Domain\Model\NodeInterface; use Neos\ContentRepository\Domain\Service\ContextFactoryInterface; use Neos\Flow\Annotations as Flow; use Neos\Flow\Cli\CommandController; use Sandstorm\E2ETestTools\StepGenerator\NodeTableBuilderService; class StepGeneratorCommandController extends CommandController { /** * @Flow\Inject */ protected ContextFactoryInterface $contextFactory; /** * Main API for creating NodeTable instances to print BDD steps. * * @Flow\Inject */ protected NodeTableBuilderService $nodeTableBuilderService; public function homepageCommand() { $nodeTable = $this->nodeTableBuilderService->nodeTable() ->withDefaultNodeProperties(['Language' => 'de']) ->build(); $siteNode = $this->getSiteNode(); $nodeTable->addParents($siteNode); $nodeTable->addNode($siteNode); $nodeTable->addNodesUnderneathExcludingAutoGeneratedChildNodes($siteNode, '!Neos.Neos:Document'); // we recurse into the content of the homepage $nodeTable->addNodesUnderneathExcludingAutoGeneratedChildNodes($siteNode, 'Neos.Neos:Document'); // we render the remaining document nodes so we can have a menu rendered (but without content) $nodeTable->print(); } /** * @return NodeInterface */ public function getSiteNode(): NodeInterface { $context = $this->contextFactory->create([ 'workspaceName' => 'live', 'invisibleContentShown' => true, 'dimensions' => [ 'language' => ['de'] ], 'targetDimensions' => [ 'language' => 'de' ] ]); return $context->getCurrentSiteNode(); } }
现在,当你运行./flow stepGenerator:homepage
时,你会得到一个如下所示的表格
Given I have the following nodes: | Path | Node Type | Properties | HiddenInIndex | Language | | /sites | unstructured | [] | false | de | # ... many more nodes here in this table ...
这可以粘贴到如下所示的测试用例中
@fixtures @playwright Feature: Homepage Rendering Scenario: Full Homepage Rendering Given I have a site for Site Node "site" # to regenerate, use: ./flow stepGenerator:homepage Given I have the following nodes: | Path | Node Type | Properties | HiddenInIndex | Language | | /sites | unstructured | [] | false | de | # ... many more nodes here ... Given I get a node by path "/sites/site" with the following context: | Workspace | Dimension: language | | live | de | Given I accepted the Cookie Consent When I render the page Then I store the Fusion output in the styleguide as "Page_Homepage" Then I store the Fusion output in the styleguide as "Page_Homepage_Mobile" using viewport width "320"
这可以生成不同页面的**响应式、可复制的截图**,并且当占位符数据发生变化时能够重新生成。
BDD测试中的持久资源
如果你的节点fixture指向Neos.Media模块中的某些资产,你也可以为它们生成fixture。创建NodeTable时需要传递第二个参数($fixtureBasePath)。
你可能希望将你的资产fixture存储在功能文件附近。
TODO 解释如何设置fixture基础路径
// ... Step Generator Command Controller public function homepageCommand() { $nodeTable = $this->nodeTableBuilderService->nodeTable() ->withDefaultNodeProperties(['Language' => 'de']) // !!! Here you setup your directory for storing your fixture files. // It will print a path relative to the Flow package directory. // -> most likely: Sites/Your.PackageKey/Tests/Behavior/Features/Homepage/Resources/someSHA1.png (depending on the type of the composer package) ->withFixtureBasePath('Your.PackageKey', 'Tests/Behavior/Features/Homepage/Resources/') ->build(); $siteNode = $this->getSiteNode(); $nodeTable->addParents($siteNode); $nodeTable->addNode($siteNode); $nodeTable->addNodesUnderneathExcludingAutoGeneratedChildNodes($siteNode, '!Neos.Neos:Document'); // we recurse into the content of the homepage $nodeTable->addNodesUnderneathExcludingAutoGeneratedChildNodes($siteNode, 'Neos.Neos:Document'); // we render the remaining document nodes so we can have a menu rendered (but without content) // when the table is printed, it includes other tables containing asset fixtures $nodeTable->print(); } // ...
假设你的节点数据fixture中有三张图片(节点属性类型为ImageInterface
)。你的输出可能看起来像
Given I have the following images: | Image ID | Width | Height | Filename | Collection | Relative Publication Path | Path | | 3a28c97c-58f1-45c5-b1ad-2f491c904467 | | | Map-circle-blue.svg | persistent | | Sites/Your.Package/Tests/Behavior/Features/Homepage/Resources/9600acebed149b1e0178b214a7f3a82bc7a829a4.svg | | 846d085f-091b-4d08-82bb-e5f04150c594 | 615 | 418 | cat_caviar.jpeg | persistent | | Sites/Your.Package/Tests/Behavior/Features/Homepage/Resources/ee53c207588c199b4e5359f5e06d241b0d93b78e.jpeg | | 3ca6e806-182a-4af2-9a60-50d2ff0bcbdb | 4500 | 4500 | mark-man-stock.png | persistent | | Sites/Your.Package/Tests/Behavior/Features/Homepage/Resources/9784f58d2f6810b773807b3cfd56dcbe2b3a1c65.png | Given I have the following nodes: | Path | Node Type | Properties | HiddenInIndex | Language | # ... nodes go here here with reference to Image ID in their serialized properties # a property might look like: { ..., "myImageProperty":{"__flow_object_type":"Neos\\Media\\Domain\\Model\\Image","__identifier":"3a28c97c-58f1-45c5-b1ad-2f491c904467"}, ...
注意,Path
列的值是相对于Flow包目录打印和读取的。这应该使你的测试更加或更少地与环境独立。通常,这些文件存储在DistributionPackages/*包中,该包是链接到Flow包目录的(因此可以从你的测试中读取,并从你的命令控制器中进行写入)。此外,这些文件应该添加到git中,因为它们是测试用例的一部分。
通过步骤动态修改SUT URL
默认情况下,SUT URL是通过环境变量静态配置的。在某些情况下,这并不足够。
用例
基于主机信息自定义内容维度解析
假设,你的Neos项目有一个自定义内容维度值解析器,例如,通过主机名或子域。SUT基本URL是通过环境变量静态配置的。但在提到特殊情况时,你需要通过你自己的自定义步骤修改动态基本URL。
多站设置
当你的Neos应用程序有多个站点时,主机名也需要通过自定义步骤定义。
PlaywrightConnector
为此目的提供了一个API
公开API:PlaywrightTrait#setSystemUnderTestUrlModifier(\Closure $urlModifier): void
委托给内部:PlaywrightConnector#setSystemUnderTestUrlModifier(\Closure $urlModifier): void
注意,修改器在每个场景后都会重置。
你需要从你的自定义步骤调用该setter,自定义步骤可能看起来像
... /** * @Given my base URL is :baseUrl */ public function myBaseUrlIs($baseUrl) { $this->setSystemUnderTestUrlModifier(function (string $staticBaseUrl) use ($baseUrl) { return $baseUrl; }); } /** * @Given my subdomain is :subdomain */ public function mySubdomainIs($subdomain) { $this->setSystemUnderTestUrlModifier(function (string $baseUrl) use ($subdomain) { return sprintf("%s://%s.%s.nip.io:%s/%s", parse_url($baseUrl, PHP_URL_SCHEME), $subdomain, parse_url($baseUrl, PHP_URL_HOST), parse_url($baseUrl, PHP_URL_PORT), parse_url($baseUrl, PHP_URL_PATH), ); }); } ...
和behat调用
Given my subdomain is "de"
用于使用Sandstorm.NeosAcl的Site Packages的使用方法
将此添加到你的Testing/Behat
上下文中的Policy.yaml中
roles: # this is necessary to allow the test runner to create fixtures when neos # acl package is installed 'Neos.Flow:Everybody': privileges: - privilegeTarget: 'Sandstorm.NeosAcl:EditAllNodes' permission: GRANT - privilegeTarget: 'Sandstorm.NeosAcl:CreateAllNodes' permission: GRANT - privilegeTarget: 'Sandstorm.NeosAcl:RemoveAllNodes' permission: GRANT