Creating a data-driven test suite with Robot

Robot Framework uses keywords to define tests, test steps, variables, and other testing components. Keywords are short-hand commands that are provided by various libraries and can also be custom defined. This allows many different ways of writing and organizing tests.

In this recipe, we'll explore how to run the same test procedure with varying inputs and outputs. These can be described as data-driven tests.

Getting ready

  1. We first need to activate our virtualenv setup.
  2. For this recipe, we will use the shopping cart application.
  3. Next, we need to install Robot Framework, as shown in the previous recipe.

How to do it...

The following steps will show us how to write a simple acceptance test using HTML tables.

  1. Create a new file called recipe39.html to capture the tests and configurations.
  2. Add an HTML paragraph and table that contains a set of data-driven test cases, as shown in the following browser screenshot.
    How to do it...
  3. Add another HTML paragraph and table defining the custom keywords Adding items to cart and Add item.
    How to do it...
  4. Create a new file called recipe39.py to contain Python code that is wired into our custom keywords.
  5. Create an old style Python class that implements the custom keywords needed for the scenarios.
    from cart import *
    
    class recipe39:
        def __init__(self):
            self.cart = ShoppingCart()
    
        def add_item_to_cart(self, description, price):
            self.cart.add(description, float(price))
    
        def get_total(self, tax):
            return format(self.cart.total(float(tax)), ".2f")

    Tip

    It's important to define the class old style. If we define it as new style by subclassing object, Robot Framework's runner, pybot, won't find the methods and associate them with our HTML keywords.

  6. Add a third HTML paragraph and table that loads our Python code to implement Add item to cart and Get total.
    How to do it...
  7. View the HTML file in your favorite browser.
    How to do it...
  8. Run the HTML file through pybot to exercise the tests by typing pybot recipe39.html.
    How to do it...
  9. You can inspect report.html and log.html using your favorite browser for more details about the results.

How it works...

Robot Framework uses HTML tables to define test components. The header row of the table identifies what type of component the table defines.

The first table we created was a set of test cases. Robot Framework spots this by seeing Test Case in the first cell of the header row. The rest of the header cells aren't parsed, which leaves us free to put in descriptive text. In this recipe, each of our test cases is defined with one-line. The second column has Adding items to cart on every row, which is a custom keyword defined in the second table. The rest of the columns are arguments for this custom keyword.

The second table we wrote is used to define custom keywords. Robot Framework figures this out by seeing Keyword in the first cell of the header row. Our table defines two keywords.

  • Adding items to cart:
    • The first line defines the arguments by starting with [Arguments] and six input variables: ${item1}, ${price1}, ${item2}, ${price2}, ${tax}, and ${total}.
    • The next set of lines are actions.
    • Lines two and three use another custom keyword: Add item with two arguments.
    • Line four defines a new variable, ${calculated total}, which is assigned the results of another keyword, Get total with one argument, ${tax} that is defined in our Python module.
    • The last line uses a built-in keyword, Should Be Equal, to confirm the output of Get total matches the original ${total}.
  • Add item:
    • The first line defines arguments by starting with [Arguments] and two input variables: ${description} and ${price}.
    • The second line uses another keyword, Add item to cart, that is defined in our Python module, with two named arguments, ${description} and ${price}.

The third table we made contains settings. This is identified by seeing Setting in the first cell of the header row. This table is used to import Python code that contains the final keywords by using the built-in keyword Library.

There's more...

Robot Framework maps our keywords to our Python code by a very simple convention:

  • Get total ${tax} maps to get_total(self, tax).
  • Add item to cart ${description} ${price} maps to add_item_to_cart(self, description, price).

    Note

    The reason we need add_item_to_cart, and couldn't have just written add_item to tie in to keyword Add item is because Robot Framework uses named arguments when connecting to Python code. Since each usage of Add item in our tables had a different variable name, we needed a separate keyword with distinct arguments.

Do I have to write HTML tables?

Robot Framework is driven by HTML tables, but it doesn't matter how the tables are generated. Many projects use tools like reStructuredText (http://docutils.sourceforge.net/rst.html) to write tables in a less verbose way, and then have a parser that converts it into HTML. A useful tool for converting .rst to HTML is docutils (http://docutils.sourceforge.net/). It provides a convenient rst2html.py script that will convert all the .rst tables into HTML.

Unfortunately, the format of this book makes it hard to present .rst as either code or with a screenshot. To see a good example, visit http://robotframework.googlecode.com/svn/tags/robotframework-2.5.4/doc/quickstart/quickstart.rst, the source for the online Quick Start HTML guide.

What are the best ways to write the code that implements our custom keywords?

We wrote a chunk of Python code to tie in our custom keywords with the ShoppingCart application. It is important to make this as light as possible. Why? Because when we deploy the actual application, this bridge shouldn't be a part of it. It may be tempting to use this bridge as an opportunity to bundle things up, or to transform things, but this should be avoided.

Instead, it is better to include these functions in the software application itself. Then this extra functionality becomes a part of the tested, deployed software functionality.

If we don't invest too heavily in the bridging code, it helps us to avoid making the software dependent on the test framework. For some reason, if we ever decided to switch to something other than Robot Framework, we wouldn't be tied into that particular tool due to having too much invested in the bridging code.

Robot Framework variables are unicode

Another critical factor in making our Python code work is recognizing that the input values are Unicode strings. Since the ShoppingCart is based on floating point values, we had to use Python's float(input) function to convert inputs, and format(output, ".2f") to convert outputs.

Does this contradict the previous section where we discussed keeping this bridge as light as possible? It doesn't. By using pure, built-in Python functions that have no side effects, we aren't getting in deep and instead are only messaging the formats to line things up. If we started manipulating containers, or converting strings to lists, and vice versa, or even defining new classes, then that would definitely be getting too heavy for this bridge.

See also

Installing the Robot Framework

..................Content has been hidden....................

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