I used Developer experience issue template from magento/magento2 repository
Summary (*)
MFTF tests are trying to be similar to BDD-way of writing tests, known from younger e-commerce projects like https://github.com/Sylius/Sylius
https://github.com/Sylius/Sylius/blob/48729b86334ba78d8f2011b9743389024c334d56/features/checkout/paying_for_order/paying_with_paypal_during_checkout.feature#L1-L13
The real value of such tests is possibility to confront the Business Requirements with test results without any extra interpretation. The content is completely obvious:
@ui
Scenario: Successfully authorize payment
Given I added product "PHP T-Shirt" to the cart
And I have proceeded selecting "PayPal" payment method
And the payment method "PayPal" requires authorization before capturing
When I confirm my order with paypal payment
And I sign in to PayPal and authorize successfully
Then I should be notified that my payment has been completed
And I should see the thank you page
And the latest order should have a payment with state "completed"
Let's take a look at the easiest test in Magento Functional Tesitng Framework - AdminLoginTest
:
--------------------------------------------------------------------------------
AdminLoginTestCest: Admin login test
Signature: Magento\AcceptanceTest\_default\Backend\AdminLoginTestCest:AdminLoginTest
Test: tests/functional/Magento/FunctionalTest/_generated/default/AdminLoginTestCest.php:AdminLoginTest
Scenario --
I am on page "/strix/admin"
I fill field "#username","strix"
I fill field "#login","79XedTOBjPiHFtLt"
I click ".actions .action-primary"
I wait for page load 30
I close admin notification
I see in current url "/strix/admin"
PASSED
Even there we can see too much "magic":
- What are the #username and #login fields? What is the difference between?
- Do we want to put our secrets in test results?
- What the heck is
.actions .action-primary
?!
- What is the literal of
30
in I wait for page load
?
- Does it really matter if we close Admin Notification or not?
- What does it mean that I see
/strix/admin
in URL?
Proposed solution
In my humble opinion, that would be much more readable if we use friendly names for DOM elements. Example (parenthesis are grayed out, not visible when not in -vv
mode):
I am on Admin URL (Admin URL: "/strix/admin")
I fill username field with "strix" (xpath: "#username")
I fill password field with "79XedTOBjPiHFtLt" (xpath: "#login")
I click Login button (xpath: ".actions .action-primary")
I wait for page load (timeout: 30)
I see Admin URL in current url (Admin URL: "/strix/admin")
PASSED
Such Friendly Label would be defined inside Section
:
<sections xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:mftf:Page/etc/SectionObject.xsd">
<section name="AdminLoginFormSection">
<element name="username" type="input" selector="#username" label="Username Input"/>
<element name="password" type="input" selector="#login" label="Password Input"/>
<element name="signIn" type="button" selector=".actions .action-primary" timeout="30" label="[Sign In] button"/>
</section>
</sections>
By design - Magento Functional Testing Framework should use as much Action Groups as it's possible - each time when we need to log in as Administrator:
<amOnPage url="{{_ENV.MAGENTO_BACKEND_NAME}}" stepKey="navigateToAdmin"/>
<fillField userInput="{{_ENV.MAGENTO_ADMIN_USERNAME}}" selector="{{AdminLoginFormSection.username}}" stepKey="fillUsername"/>
<fillField userInput="{{_ENV.MAGENTO_ADMIN_PASSWORD}}" selector="{{AdminLoginFormSection.password}}" stepKey="fillPassword"/>
<click selector="{{AdminLoginFormSection.signIn}}" stepKey="clickLogin"/>
should be replaced with:
<actionGroup ref="LoginActionGroup" stepKey="login"/>
Amazing! 🎆
However ⚠️
What if we have more complicated action groups like... creating products:
<actionGroup ref="CreateCustomVariableActionGroup" stepKey="createCustomVariable" />
Sounds like... no business value for review.
What if instead of current implementation
<actionGroup name="CreateCustomVariableActionGroup">
<amOnPage url="admin/admin/system_variable/new/" stepKey="goToNewCustomVarialePage" />
<waitForPageLoad stepKey="waitForPageLoad" />
<fillField selector="{{CustomVariableSection.variableCode}}" userInput="{{customVariable.code}}" stepKey="fillVariableCode" />
<fillField selector="{{CustomVariableSection.variableName}}" userInput="{{customVariable.name}}" stepKey="fillVariableName" />
<fillField selector="{{CustomVariableSection.variableHTML}}" userInput="{{customVariable.html}}" stepKey="fillVariableHtml" />
<fillField selector="{{CustomVariableSection.variablePlain}}" userInput="{{customVariable.plain}}" stepKey="fillVariablePlain" />
<click selector="{{CustomVariableSection.saveCustomVariable}}" stepKey="clickSaveVariable"/>
</actionGroup>
We use friendly label:
<actionGroup name="CreateCustomVariableActionGroup" label="Create Custom Variable with {{CustomVariableSection.variableCode}} code and {{CustomVariableSection.variableName}} as a name">
Everytime when you include Action Group - the steps included wouldn't be displayed directly, but we will show the Action Group label to user. Instead of having extra 5 steps each time when we log in as Administrator:
AdminCreateProductDuplicateUrlkeyTestCest: Admin create product duplicate urlkey test
Signature: Magento\AcceptanceTest\_default\Backend\AdminCreateProductDuplicateUrlkeyTestCest:AdminCreateProductDuplicateUrlkeyTest
Test: tests/functional/Magento/FunctionalTest/_generated/default/AdminCreateProductDuplicateUrlkeyTestCest.php:AdminCreateProductDuplicateUrlkeyTest
Scenario --
I am going to create entity that has the stepKey: simpleProduct
I am on page "/strix/admin"
I wait for page load
I fill field "#username","strix"
I fill field "#login","79XedTOBjPiHFtLt"
I click ".actions .action-primary"
I wait for page load 30
I close admin notification
I am on page "/strix/catalog/product/index"
I click ".action-toggle.primary.add"
I save screenshot
FAIL
I am on page "admin/admin/auth/logout/"
I am going to delete entity that has the createDataKey: simpleProduct
we would have only one:
I am going to create entity that has the stepKey: simpleProduct
I am logged in as Administrator (login: "strix", password: "xyz123")
I am on page "/strix/catalog/product/index"
I click ".action-toggle.primary.add"
I save screenshot
Isn't that better?