Web applications often have some sort of security in place. This is often in the form of a login page. A well written test case should start a new browser session at the beginning and close it at the end. This results in the user logging in repeatedly for every test case.
In this recipe, we will explore writing code to login in satchmo's admin page, as provided by Django. Then we will show how to capture this entire login procedure into a single keyword, allowing us to smoothly write a test that visits the product catalog without getting encumbered by logging in.
virtualenv
setup.python
manage.py runserver
. You can explore it by visiting http://localhost:8000
.The following steps will highlight how to capture login steps and then encapsulate them in a single custom keyword.
recipe43.txt
, and write a test story for exercising Django's admin interface.As a system administrator I want to login to Django's admin page So that I can check the product catalog.
***Test Cases*** Logging in to the admin page Open Browser http://localhost:8000/admin Input text username gturnquist Input text password password Submit form Page Should Contain Link Products Close All Browsers
Check product catalog Given that I am logged in Click link Products Capture Page Screenshot recipe43-scenario2-1.png Table Should Contain result_list Robots Attack! Table Row Should Contain result_list 4 Robots Attack! Table Row Should Contain result_list 4 7.99 Close All Browsers
***Keywords*** Given that I am logged in Open Browser http://localhost:8000/admin/ Input text username gturnquist Input text password password Submit form Startup Start Selenium Server Sleep 3s
***Settings*** Library SeleniumLibrary Suite Setup Startup Suite Teardown Stop Selenium Server
pybot
recipe43.txt
.The first test case shows how we input username and password data and then submit the form. SeleniumLibrary allows us to pick a form by name, but in the event we don't identify it, it picks the first HTML form it finds. Since there is only one form on the login page, this works fine for us.
With the second test case, we want to navigate to the product catalog. Since it runs with a clean browser session, we are forced to deal with the login screen again. This means we need to include the same steps to login again. For more comprehensive testing, we would probably write lots of test cases. Why should we avoid copying and pasting the same login steps for every test case? Because it violates the DRY (Don't Repeat Yourself) principle. If the login page is modified, we might have to alter every instance.
Instead, we captured the login steps with keyword Given
that
I
am
logged
in
. This gives us a useful clause for many test cases, and lets us focus on the admin page.
In this recipe, we are using some of SeleniumLibrary's table testing operations. We verified that a particular book exists both at the table level as well as the row level. We also verified the price of the book in that row.
Finally, we captured a screenshot of the product catalog. This screenshot gives us a quick, visual glance which we can use to either manually confirm the product catalog, or use to plan our next test step.
Lots of websites include a 'remember me' checkbox in order to save login credentials in a client-side cookie. The Django admin page doesn't have one, so why is this relevant? Because many websites do and we may be tempted to incorporate it into our tests to avoid logging in every time. Even if this option existed for the web app we want to test, it is not a good idea to use it. It creates a persistent state that can propagate from one test to the next. Different user accounts may have different roles, impacting what is visible. We may not know in what order test cases run, and therefore, have to add extra code to identify what user we are logged in as.
Instead, it is much easier and cleaner to not keep this information. Instead, explicitly logging in through a single keyword provides a clearer intent. This doesn't mean we shouldn't test and confirm the remember checkbox of our particular web application. On the contrary, we should actually test both good and bad accounts to make sure the login screen works as expected. But beyond that, it is best to not confuse future test cases with the stored results of the current test case.
To uphold the DRY principle, we should have the login procedure in only one place inside our test story. But for demonstration purposes, we coded it at the top, and then later copied the same code into a keyword. The best solution would be to encapsulate it into a single keyword that can be reused in either a test case or to define other custom keywords like Given
I
am
logged
in
.
Absolutely. In this test story, we hardcoded the username as well as the password. But good testing of the login page would involve a data-driven table with lots of combinations of good and bad accounts, along with valid and invalid passwords. This drives the need for some sort of login keyword that would accept username and password as arguments.
3.141.197.251