Reputation: 1459
I'm using Selenium (python bindings, with Django) for automated web app testing. My page has a form with a button, and the button has a .click()
handler that captures the click (i.e. the form is not immediately submitted). The handler runs function2()
, and when function2()
is done, it submits the form.
In my test with Selenium, I fill in the form, then click the Submit button. I want to verify that the form is eventually submitted (resulting in a POST request). The form POSTs and then redirects with GET to the same url, so I can't check for a new url. I think I need to check that the POST request occurs. How do I check for successful form submission?
Alternatively I could check at the database level to see that some new object is created, but that would make for a bad "unit" test.
Upvotes: 3
Views: 2519
Reputation: 2891
I guess it depends on how deep down the rabbit hole you want to go.
If you're building a test for the functional side from the user's perspective, and your GET action results in changes on the webpage, then trigger the submit with selenium, then wait for the changes to propagate to the webpage (like waiting for one/more elements to change value or waiting for an element to appear)
If you want to build an unit test, then all you should be testing is the ability to Submit the data, not also the ability of the javascript code to do a POST request, then a GET then display the data.
If you want to build an integration test, then you will need to check that each individual action in the sequence you described is performed correctly in whatever scenario you deem appropriate and then check that the total result of those actions is as expected. The tricky part will be chaining all those checks together.
If you want to build an end to end test, then you need to check for all of the above, plus changes to any permanent storage locations that the code you test changes (like databases or in-memory structures) plus whatever stress/security/usability/performance checks your software needs to pass in your specific context.
Upvotes: 0
Reputation: 151411
Ok, so your test suite needs to check something which is not visible to the user. Here's some methods that come to mind.
Use a server that will record POST requests made to it, and record such POSTs so that the testing code can check that the POSTs are performed.
This is the approach I've used for one of my applications. I've created a very small and stupid server based on the Express framework of Node.js. It just records POST requests.
The small and stupid server may not work in all cases. If I had to do this with my actual Django codebase, here's what I'd do. I already use a variable named TESTING
in my global project settings, which is true when the code is being run by a test suite. When TESTING
is true, I'd make it so that the views that are supposed to receive the POST log what they've received in a place where my test framework can check for it. (It could be a file.)
Modify your JavaScript code to keep a record of what POSTs it makes. Then you could use driver.execute_script
to retrieve this information and check for what you'd expect to find if your code ran correctly. Generally, I would make it so that this kind of recording is done only when the code is being tested. No such recording would happen in production.
Make the browser started by Selenium connect through a proxy that can records interactions and save them to a file. Then the test suite can check what was recorded. This has the advantage of not needing any changes to your application's codebase. The only tool I can recommend if you decide to go this way is mitmproxy. I've had good success using it to record interactions with the Zotero server so as to avoid hitting it each time I run my test suite.
Upvotes: 1