User tests: Successful: Unsuccessful:
This pull is created by for the works of the Automated Testing Working Group
Sometimes we need to write a very complex xpath to locate a element in the page, for example:
$I->click(['xpath' => "//*[@id=\"menuList\"]/tbody/tr/td[2]/a[contains(text(), 'weblink')"])
Instead of challenging the location abilities of the tester, is much easier to modify the output of the template by adding attributes that ease the location:
$I->fillField(['css' => 'input[data-tests="username"]'], $username);
note that is important that our tests are readable, and that has to do with using readable locators.
We came to the conclusion that using data-
html5 attribute we will not affect the accessibility nor the functionality.
This element locators will allow us to make our tests not fail when the name of a button or a title changes like it happened in the past with: joomla-extensions/weblinks#75.
I'm opening this pull request being a small example of the changes that we plan to do in the Joomla templates. We would like to get community feedback to ensure we will not affect anyone with them.
We have had experiences in the past that this kind of changes can also improve the current output, see for example this issue: #7207.
Note for Automated Testing Working Group: we originally planned to use css classes for this as we specified at https://docs.joomla.org/Testing_Joomla_Extensions_with_Codeception#Write_complex_locator_VS._modifying_the_output_of_the_tested_website, but after a small performance tests done by me, @yvesh and @810 we have concluded that the tests performance is not affected:
As a class: ✔ administrator login: Successful login (34.3448s) <= test repeated 10 times
As an attribute: ✔ administrator login: Successful login (32.3201s) <= test repeated 10 times
And using a data-tests attribute
make our tests more readable than using css classes
. Therefore we plan to change the best practice from css classes into data- html5 attributes.
Status | New | ⇒ | Pending |
Labels |
Added:
?
|
Not to mention that at least in this case the form element and username and password inputs already have HTML id attributes which should be unique (otherwise invalid HTML is being shipped).
Personally, I don't think littering Joomla's markup with data-
attributes only used for automated tests is a good idea by any means. I do support making things easier to do in the long run but I don't think this is the right way to go about it.
Category | ⇒ | Unit Tests |
I agree with Michael as well. Use id's - this is what their purpose is to me...
Id's are more performant definitely but from our performance checks the difference is not significant.
Against IDs the locator do not contain the type of element that we are interacting with: input, link, textarea... in that sense the data-* alternative improves readability of the tests, and the output, easying to debug an issue.
Anyway we could do ['xpath' => 'input[@id="passwd"]'] but then we would not use the performant Selenium strict id locator but the XPath search.
Having the QA team adding IDs to the joomla template is risky, because we could end up adding more than one same id per page. In that case data-* could not cause issue. And, in addition, I'm not sure but I guess it would go against the web semantics.
Also for readability, the IDs do not allow spaces, while in a data-test attribute we can describe the element. For example: data-test=toolbar button Save & Close
.
Login is not a good example, because it already has IDs in place, so it was not necessary to add the data-*. For cases like Login we can reuse the existing locators. We are working on a way to use readable names in test that replaces the locator.
I'm closing and I'll prepare a more clear example and I will reopen.
Status | Pending | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2016-05-26 12:08:06 |
Closed_By | ⇒ | javigomez |
My main issue with the data attributes as you've suggested here is it
starts down a path of littering markup with stuff that isn't even intended
for production use. If we were using them for something it'd be another
argument but "improves readability of automated tests" is somewhat weak.
IMO the suggestion I had with the $I->submitForm() syntax is a lot more
readable than either xpaths or CSS selector chains anyway; it tells the
action you're performing on a specific form element with a given dataset
and it's not very verbose at all, to me that was much clearer than what you
have now in the admin login function with all the separate calls to
fillField and click and whatnot.
On Thursday, May 26, 2016, javier gomez notifications@github.com wrote:
Id's are more performant definitely but from our performance checks the
difference is not significant.Against IDs the locator do not contain the type of element that we are
interacting with: input, link, textarea... in that sense the data-*
alternative improves readability of the tests, and the output, easying to
debug an issue.
Anyway we could do ['xpath' => 'input[@id https://github.com/id="passwd"]']
but then we would not use the performant Selenium strict id locator but the
XPath search.Having the QA team adding IDs to the joomla template is risky, because we
could end up adding more than one same id per page. In that case data-*
could not cause issue. And, in addition, I'm not sure but I guess it would
go against the web semantics.Also for readability, the IDs do not allow spaces, while in a data-test
attribute we can describe the element. For example: data-test=toolbar
button Save & Close.Login is not a good example, because it already has IDs in place, so it
was not necessary to add the data-*. For cases like Login we can reuse the
existing locators. So we are working on a way to use readable names in test
that replaces the locator.I'm closing and I'll prepare a more clear example and I will reopen.
—
You are receiving this because you commented.
Reply to this email directly or view it on GitHub
#10589 (comment)
Doesn't happen often, but I have to second Michael. Additional markup that is useless for production has to be avoided.
The problem with $I->submitForm()
is that it doesn't really emulates an real user, it sends a Post. A user do not send a complete POST. Instead, the user interacts with the form. And the $I->submitForm() would work for the login form, but what will happen when you have a Select? Will you be sending the select value? What if you have a Multiselect?...
Based on the docs you can use $I->submitForm()
to set the values on all fields in a form as long as it's not a hidden field.
I guess it begs to question what exactly you want to test and how you want to test it. AFAIK $I->submitForm()
emulates filling in the fields of the form and triggering the form submit action the same as if you're spelling out each step of that explicitly like in JoomlaBrowser::doAdministratorLogin(). I guess the explicit way would also emulate user behaviors in the browser (like if you needed to scroll the page for some reason, I've had to fight with that on a couple test cases).
Most of our selects are hidden elements because Chosen hide them and creates their own _chzn selects.
From the submitForm at the docs:
The submitForm is not emulating a user’s actions, but it’s quite useful in situations when the form is not formatted properly, for example to discover that labels aren’t set or that fields have unclean names or badly written ids, or the form is sent by a javascript call.
Still I don't see any problem in the tests to have:
$I->fillField('Username');
$I->fillField('Password');
$I->click('Log in);
I think covers more the real user interaction than:
$I->submitForm('#adminForm', array(
'username' => 'Miles',
'email' => 'Davis',
)), 'submitButton');
So again I'd say it boils down to what you want to test and how. Maybe you have an explicit test case validating the admin login page using what you have now in doAdministratorLogin()
since that is more explicitly testing the page markup/structure but as a re-usable action you could just do it the $I->submitForm()
way since at that point you're less interested in validating the page's markup and more interested in performing the action so you can continue on with the test case. I don't think there's a single right way here in the long run.
$I->fillField('Username');
$I->fillField('Password');
$I->click('Log in);
should be
$page->enterCredentials('Username', 'Password');
$page = $page->submit();
Maybe I am being thick and stupid but if the field name and the new
data-tests values are absolutely identical isnt the logical thing to do to
use the existing attribute without having to rewrite every existing view
with a new attribute with a duplicated and identical value. It seems to be
just creating extra work for the sake of it.