Support for Drupal 7 is ending on 5 January 2025—it’s time to migrate to Drupal 10! Learn about the many benefits of Drupal 10 and find migration tools in our resource center.
Problem/Motivation
\Drupal\book\Tests\BookTest::testBookOrdering()
is simulating Javascript behavior by manipulating hidden fields on the form. #2809161: Convert Javascript/AJAX testing to use JavascriptTestBase suggests to convert them to JavascriptTestBase
.
Proposed resolution
Create a BookJavascriptTest::testBookOrdering()
and remove the current test from \Drupal\book\Tests\BookTest
.
Remaining tasks
None.
User interface changes
None.
API changes
None.
Data model changes
None.
Comment | File | Size | Author |
---|---|---|---|
#30 | 2820079-30.patch | 7.66 KB | michielnugter |
#30 | interdiff-26-30.txt | 1.88 KB | michielnugter |
#26 | 2820079-26.patch | 7.71 KB | michielnugter |
#26 | interdiff-22-26.txt | 1.26 KB | michielnugter |
#22 | 2820079-22.patch | 7.78 KB | michielnugter |
Comments
Comment #2
claudiu.cristea.
Comment #3
claudiu.cristeaPatch copied from #2757007: Convert all book web tests to BrowserTestBase.
Comment #4
dawehnerIt is super nice to expand the test coverage here!
Super nice!
Comment #5
droplet CreditAttribution: droplet commentedShould we document it better what is it testing? Or split it into few test cases.
Reading the title, I just expected this is testing re-order with dragging
Until I read Line 8x, I don't know it's also tested "Show Weight" feature.
Missing?
- test Parent-Child
Comment #6
droplet CreditAttribution: droplet commentedDEL
Comment #7
claudiu.cristeaYes, that is not exactly in the scope. It's a bonus :)
Everything is tested in the UI. The backend test is only an extra precaution.
Comment #8
droplet CreditAttribution: droplet commentedThanks. I just read the code again and see it :)
Will another test case for it? If so, should we remove it in the current test? Better Performance :)
Comment #9
claudiu.cristeaWell, it's not 100% out-of-scope. A sortable table can be used either with drag-n-drop or using the weight selectors. I want to test here that the selectors were synced when I'm doing the drag and drop. So, I would keep it here for now.
Comment #10
droplet CreditAttribution: droplet commentedUmm. It looks right.. and not so right.
If we clicked the weight column before saving. How can we tell it's changed by drag-n-drop or changed by "Weight" column JS (maybe there's a `change` event from "Weight" click triggered re-ordering)
Comment #11
claudiu.cristeaI'm not reordering by weight selector. I'm only checking the weights before and after drag-and-drop. But in order to check their values, I need to make them visible because Mink is not able to locate invisible elements on the page. Mink act like an human that is using a real browser.
Comment #12
droplet CreditAttribution: droplet commentedThanks.
I understand it. But any other actions could be the side-effect to the test. Although we know that no changes from the "Show Weight" click in the current code, refactoring code could change the behavior. If we re-run all these testing with Human on refactoring, then unit test is useless.
Mink able to execute JS. But I think it's not necessary in this test case. An human just drag it and click save, and then see correct ordering.
EDITED:
In fact, until I actually reading the JS code carefully. I don't know if it's true or not. My eyes looking at UI, it's not. But it could be work in a way I don't expect.
Comment #13
claudiu.cristeaWell, I wanted to test the values invisibly stored by JS in the selectors. I'm testing here JS drag-and-drop and then i'm checking if everything was correct first in UI, by checking the values of weight selectors and, second, in backend by submitting the form and loading the pages. What's wrong with that?
Comment #14
droplet CreditAttribution: droplet commentedIt's wrong in Browser Acceptance test. Let me try to explain it.
Test is guaranteed the feature works as expected, no matter what we changed the code in other places.
Do we agree with it? If not, I think too much :(
Above test catches the drag-n-drop ordering.
Now, we refactoring the "Weight Column" to RE-SYNC the value to more readability (e.g. From 1 to 10 instead of -15, -9 -6) on clicking.
We'd sure that ABOVE TEST is covered the drag-n-drop. We run the Patch, it's GREEN. It's passed! It committed!
However, we introduced a new bug on refactoring. It broke the drag-n-drop to SYNC THE VALUE.
In this case, above test case still passed!! Because it clicked the "Weight Column" to trigger the event fired and changing the value correctly!
Current:
DRAG -> VALUE changed by DRAG -> click the weight column -> save
Then:
I introduced a new feature to weight click and a bug to drag-n-drop.
CLICK WEIGHT COLUMN -> VALUE change by NEW Feature -> save
(We know that drag-n-drop has test covered, we won't spend time on testing with HUMAN.)
After this bad refactoring
DRAG -> (NO CHANGE TO VALUE) -> CLICK WEIGHT COLUMN -> CHANGED VALUE FROM WEIGHT -> SAVE
Is the drag-n-drop really working? No!
Comment #15
claudiu.cristeaSorry, you lost me. Instead of all big explanation, please point out what additional test do we need here, but strictly in the scope of this issue which is book reordering or what's wrong with this test. Till you provide me with that, I'll set back this to RTBC as it has been RTBCed several times in #2757007: Convert all book web tests to BrowserTestBase and also here, in #4.
Comment #16
droplet CreditAttribution: droplet commentedNo extra tests but removing the extra `Show rows weight` clicking
I reviewed the patch again. It's only ONE SAVE at the end of tests. I hope I don't miss anything.
This is how above patch does:
Drag -> [Change Value] -> Click `Show rows weight` -> [Change test factors (SIDE-EFFECT)] -> Click Save
We should remove the side-effect in tests.
Best example:
Drag -> [Change Value] -> Click Save -> [Perform checking with `document.querySelectorAll` like selectors, Mink's assertions]
Good example:
Drag -> [Change Value] -> [Checking the result with `document.querySelectorAll` like selectors which will not modify the HTML] -> Click Save
** I will keep it as RTBC. But I hope the committers/maintainers give me one more chance to explain it if you disagree/don't get my point also. Don't think in PHP server-side testing with generated HTML output.
Thanks ALL
Comment #17
pfrenssen@droplet I don't get the reservations you have, I have reviewed the test and it does multiple checks to see whether the reordering was successful.
It first checks to see if the dragging actually results in the items being placed in the right order in the DOM.
Then it checks that the weights have been correctly updated in the DOM. The actual numbers don't matter, but the dragged item should now have a higher weight.
It submits the form and checks again that the correct order is retained, this already proves that the weights have been correctly updated and saved.
Then it does an additional check to see that the weights that are saved in the database are in the correct order. This is not strictly needed, but it *REALLY* proves it now.
For me this looks really sufficient for the current implementation.
If we would implement the weight re-syncing example that you give, then that should have an additional javascript test that proves that the weight re-syncing does not affect previous unsaved reordering by drag-and-drop.
Comment #18
dawehner@droplet
This patch already improves the status a lot. We could though, as you know, always iterate on top of it. Creating issues is easy.
Comment #20
claudiu.cristeaThere was failure on a test that made an external HTTP request:
Looks like is caused by http://thenextweb.com/insider/2016/10/21/massive-ddos-attack-dyn-dns-cau...
Comment #21
droplet CreditAttribution: droplet commentedYou skipped the most important point:
It can check the DOM with test assertions (result, the DOM is snapshoted). But it should not modify the DOM and then check it.
What it should be tested is a single action: Drag => GREEN result
Above test is testing a combined action:Drag + Weight Click => GREEN result
It's lucky! The DOM changes do not make any differences to test assertions above.
@pfrenssen comment about re-syncing example isn't true all time. Any new test on weight is testing weight features or a drag + weight combination. But tests will not test drag-n-drop alone again.
@dawehner,
OK.
Somehow, I agreed my suggestions is silly. We almost never make an extra change to `Weight` link in CORE.
Thanks All. Have A Nice Weekend!
Comment #22
michielnugter CreditAttribution: michielnugter as a volunteer and at Synetic commented@droplet
If I understand correctly:
The test now tests the following:
The problem is that the server check relies on the drag-n-drop AND the switch to the manual input. Drag-n-drop is not checked isolated from the weight fields.
I changed the patch to submit the page directly after the drag-n-drop action and then validate on the server. After that, I use the weight fields directly and submit the page. Again I check the values on the server. This way the drag-n-drop is tested separately from the weight fields.
Other small change: assertTrue / assertFalse is deprecated in 9.x (should a patch be posted to mark each method deprecated to make the IDE pick it up?). I changed them to assertEquals.
Comment #23
droplet CreditAttribution: droplet commented@michielnugter,
Step 1-7 in your comment #22 is how above patch is tested.
But with this test scope, this is only test drag-n-drop. Correct order should be:
1. Use drag-n-drop to change the order
2. Validate the UI (checks if reordering works)
3. Validate the Value in Hidden Weight field (without interactive click, use getHTML, test assertions)
4. Submit the page
5. Validate the order on the server
Point #3 is important. "An action interacts with UI to validate the result" vs "Validate with snapshotted result (->getHTML)"
Ideally, a strict test should validate with getHTML before interact with UI `->click` again. (Good test won't make assumptions)
Comment #24
droplet CreditAttribution: droplet commentedI read the full #22 patch again. Yes. it's improved.
It performed `submitForm & validate` the order before clicking `weight` link.
Comment #25
claudiu.cristeaPlease drop the message. We don't use messages anymore and the function doesn't have a message argument in signature.
Please use quotes around '1st page'.
When were assertTrue() and assertFalse() deprecated? Can you point me there? If not, please revert these changes.
Comment #26
michielnugter CreditAttribution: michielnugter as a volunteer and at Synetic commentedDidn't know about the messages, I removed them. Also put quotes around the 1st page text.
As for assertTrue, the method is defined in the 'AssertLegacyTrait' trait. This was deprecated in #2304461.
@droplet: The hidden field value is now tested implicitly by posting it to the server and validating in there, is that enough?
Comment #27
droplet CreditAttribution: droplet commented@michielnugter #26,
That's fine. I was read the interdiff and doesn't realize that in my first response. Thanks!
Comment #28
claudiu.cristea@michielnugter,
No, sorry, it was not deprecated. Please check again. Even AssertLegacyTrait will be removed, JavascriptTestBase has its own assertTrue()/assertFalse() method.
Comment #29
droplet CreditAttribution: droplet commentedNow the assertTrue extend from:
https://github.com/drupal/drupal/blob/b33af7a964ee34171e3328c3276d63551a...
When it removed, it will be used function from PHPUnit directly (if I read the source correctly. JavascriptTestBase doesn't involve TestBase)
(I don't know the preferred method anyway)
Comment #30
michielnugter CreditAttribution: michielnugter as a volunteer and at Synetic commented@claudiu.cristea
JavascriptTestBase doesn't implement the assertTrue but the PHPUnit_Framework_Assert class does define a (static?) assertTrue, this class is extended via-via. As to why the Trait is still included is not clear to me then.
Sorry about the mixup, I reverted the method calls back.
Edit:
... Now it's clear:
$this->assertTrue() is deprecated, it actually does call the method in AssertLegacyTrait. The documentation states we should use the following:
self::assertTrue()
Which conforms to the static definition of the assertTrue method in PHPUnit_Framework_Assert. It seems the recommended way is self:: for every assert?
Comment #31
claudiu.cristeaSure, it's not implemented directly but it's inherited from ancestors.
The trait method is deprecated, not explicitly, but together with the trait. So when the trait will be removed there will still be a valid $this->assertTrue() inherited from class ancestors.
@droplet, if everything is OK, please set the issue back to RTBC.
Comment #32
droplet CreditAttribution: droplet commentedComment #33
michielnugter CreditAttribution: michielnugter as a volunteer and at Synetic commented@claudiu.cristea
JavascriptTestBase extends via-via PHPUnit_Framework_Assert method. This is the only ancestor that defines the assertTrue method, statically.
So without the deprecated Trait, the method is only callable statically. $this->assertTrue() is really deprecated in favor of self::assertTrue().
As the $this->assertTrue() style is still used all over the place, even in the BrowserTestBase class I don't think it should stop this patch. I however do think we should try to avoid deprecated methods when writing new patches.
Comment #34
dawehnerWell, this is kinda wrong ... static means it can be also called statically, but it is still a normal method.
That change for itself should be discussed in its issue, please create one. Note: Sebastian Bergmann though wrote an response there: https://github.com/sebastianbergmann/phpunit/issues/1914#issuecomment-14...
Comment #35
michielnugter CreditAttribution: michielnugter as a volunteer and at Synetic commented@dawehner
Thanks for explaining. It feels really weird to not call a static method statically but if it's the way to go I'll follow.
Sorry about the confusion and setting the issue back unnecessarily.
Comment #36
alexpottI think the test is a bit heavy on testing tabledrag functionality rather than the book ordering but we can refactor that once a tabledrag test exists. Nice to see proper JS testing happening.
Committed and pushed 7522a3d to 8.3.x and dc329cc to 8.2.x. Thanks!
Committed to 8.2.x to keep test coverage the same.
Comment #39
dawehnerNo worries. Its always good to talk about stuff.