New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added Behat Tests for WebService #24162
Conversation
Just what I needed to start with testing Webservice, thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi !
Whao ! that is a great improvement 😊
May I suggest 2 things? I would like to know what you think about it
- Use Behat to introduce reader-friendly assertion steps
For example we could wrap
self::assertEquals(1, $output->filter('prestashop > errors > error')->count());
inside a nice Behat step
THEN I expect 1 error
or
self::assertEquals(
'No permission for this authentication key',
$output->filter('prestashop > errors > error')->first()->filter('message')->text()
);
by
THEN I expect the error message 'No permission for this authentication key' to be returned
- I think webservice can return XML or JSON. You use the DOMCrawler to navigate into the output XML if I understand correctly.
If using the DOMCrawler makes the writing of the tests harder, maybe using JSON output will be easier? However I am not sure Webservice allows JSON input.
We could also think about enabling Webservice to return something else than JSON and XML such as a serialized PHP object. It would then become a lot easier to assert and you would not need to parse the output. But that requires changing the implementation of the webservice and this could be complex and risky.
); | ||
|
||
// Add an object in database | ||
$data = '<prestashop xmlns:xlink="http://www.w3.org/1999/xlink"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In order to avoid repeating these custom XML document when you add more tests, maybe a function generateInputXMLForAddress()
could be used?
@matks Prestashop currently supports output as XML OR JSON, and both of the outputs are being generated by different classes. So there should be one test for XML output (using DOMcrawler) and second test for JSON output (not done yet). Webservice definitely doesnt allow JSON input, it takes only XML. Would be nice to have this feature in the future, as JSON is currently considered as standard for API. About Webservice returning serialized object. You already have Webservice, capable of returning JSON or XML output. I really wouldn't recommend adding another output type, such as serialized object, since those two are more than enough to cover all customers needs. You would have just more code to maintain, not mentioning that JSON output is a standard nowadays and its super easy to decode /encode it into any structure of basically any language. |
You can workaround this issue by splitting the Webservice in component. Consider that the Webservice is a system that outputs data in a dedicated format. We could say it's built on 3 components
When you send a HTTP request to webservice
If you are able to test very well each component, you do not need a full test coverage of all possible outputs for JSON and XML. If you can use tests to validate that component 2 works very well alone, then the tests for component 3 only need to verify "when I give it a data structure like A it should output format B". Component 3 is an encoder (see https://developer.apple.com/documentation/foundation/jsonencoder for example) and could actually be replaced by available encoders for PHP. Nevertheless it would be important to have a few tests that run components 1, 2 and 3 together to make sure they are plugged to one another correctly 😄 . But you do not need to be exhaustive with this last set of tests. So when I suggest to output PHP serialized objects, the idea behind (sorry if I did not explain it correctly) is "let's isolate components 2 and components 3, use a PHP object structure between the 2 of them as their way to communicate, and when we want to test component 2 we just need to serialize whatever comes out of it instead of performing encoding". That, however, is a big work. I was just curious to see if @Progi1984 is interested in this for the future. |
@matks Idea of splitting the Webservice into components is very good. That is actually exactly what I developed in my awaiting PR #23100 . There I am composing component 2 using PHP class ApiNode. After I compose all the structure in the ApiNode tree, I use either WebServiceOutputJSON or WebServiceOutputXML components to transform that tree structure into wanted format. However, during autotesting, you should simulate real usage as much as you can. Process is, that user sends request, where he specifies wanted output format (using IO-Format header, json/xml). Output that Webservice gives to him is already in wanted format. In my opinion, you should simulate this principle as much as you can, thats why you need to create two test, where you give as input some data and test if the XML answer is proper. Afterwards, you should test the same operation goes identically, also with JSON output (these two tests can share the same initial phase, no redundant code needed). I dont actually think, as you stated, that you are able to test very well each component. You can test the whole process at once. And I believe thats how you should test this. |
Each type of test brings value, but usually the low-level tests
You can see the great article The Test Pyramid
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice Job @Progi1984
+1 for merge, I am ready to create additional tests over WebService afterwards |
Is there any progress in merging this so far? |
ee0213b
to
7659af0
Compare
tests/Integration/Behaviour/Features/Context/WebserviceEndpointFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/WebserviceEndpointFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/WebserviceEndpointFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/WebserviceEndpointFeatureContext.php
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/WebserviceEndpointFeatureContext.php
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the contribution @Progi1984
It's really good that we start testing this part! However I see some flows in the previous implementation, that you used as a base for the new context I guess
basically relying on stateful stored data in behat tests is a bad practice, we already have lots of pain to test our code because of our steaful contexts, if we start adding some in the tests themselves we will soon start fighting with a three headed hydra 😅
It's not always easy for complex cases I know that, but I made a few suggestions which, I believe, will allow us to get rid of stateful test contexts
tests/Integration/Behaviour/Features/Context/Domain/WebserviceKeyFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/WebserviceEndpointFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/WebserviceEndpointFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/WebserviceEndpointFeatureContext.php
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/WebserviceEndpointFeatureContext.php
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @Progi1984
It's much better now, I added a few comments and questions because I didn't fully understand everything
tests/Integration/Behaviour/Features/Context/Domain/WebserviceKeyFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/Domain/WebserviceKeyFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/Util/StreamWrapperPHP.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/WebserviceEndpointFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/WebserviceEndpointFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Context/WebserviceEndpointFeatureContext.php
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Scenario/Webservice/Endpoints/addresses.feature
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Scenario/Webservice/Endpoints/addresses.feature
Outdated
Show resolved
Hide resolved
tests/Integration/Behaviour/Features/Scenario/Webservice/Endpoints/addresses.feature
Outdated
Show resolved
Hide resolved
@PierreRambaud Need review :)
tests/Integration/Behaviour/Features/Context/Util/StreamWrapperPHP.php
Outdated
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @Progi1984 all good for me too
Sorry for being such a pain on this 😅. I still think it is now more readable, usable, and stable I hope you share this feeling ^^
Scenario: Test if Bad WS Key | ||
When I use Webservice with key "ABCDEINVALIDDDDDDDD" to list "addresses" | ||
Then I should get 1 error | ||
And I should get an error with code 18 and message "Invalid authentication key format" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I could be picky on this one and suggest using some humans readable strings instead of hard coded int code here
But I've already been enough of a PITA for you on this PR so I will stop here 😅
@KminekMatej 🎉 It's a good news :) |
@Progi1984 Such a great job! That completely unlocks my PR with API core refactoring. Thanks! |
@KminekMatej Thank you for waiting. |
This change is