Using Robot to verify web app security

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.

Getting ready

  1. We first need to activate our virtualenv setup.
  2. For this recipe, we are using the satchmo shopping cart web application. To start it, switch to the store directory and type python manage.py runserver. You can explore it by visiting http://localhost:8000.
  3. Next, install the Robot Framework and the third-party Selenium plugin, as shown in the recipe Installing the Robot Framework.

How to do it...

The following steps will highlight how to capture login steps and then encapsulate them in a single custom keyword.

  1. Create a new file called 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.
  2. Add a section for test cases, and write a test case that exercises the login page.
    ***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
  3. Add another test case that inspects the product catalog and verifies a particular row of the table.
    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
  4. Create a keyword section that captures the login procedure as a single keyword.
    ***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

    Note

    For your own testing, put in the username and password you used when installing satchmo. Start Selenium Server is another keyword to launch the selenium server.

  5. Finally, add a settings section that imports the SeleniumLibrary and also starts and stops the Selenium server at the beginning and end of the test suite.
    ***Settings***
    Library         SeleniumLibrary
    Suite Setup     Startup
    Suite Teardown  Stop Selenium Server
  6. Run the test suite by typing pybot recipe43.txt.
    How to do it...

How it works...

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.

There's more...

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.

Why not use a 'remember me' option?

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.

Shouldn't we refactor the first test scenario to use the keyword?

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.

Would arguments make the login keyword more flexible?

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.

See also

  • Installing the Robot Framework
  • Using Pyccuracy to verify web app security
  • Creating a data-driven test suite with Robot
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.188.137.58