Robot Framework provides a comprehensive way to capture test scenarios using table-driven structures. This includes the ability to add metadata in the form of tagging as well as documentation.
Tagging allows including or excluding tags for testing. Documentation appears on the command line and also in the outcome reports. This recipe will demonstrate both of these keen features.
Finally, HTML tables aren't the only way to define data tables with Robot Framework. In this recipe, we will explore using double-space-separated entries. While this isn't the only non-HTML way to write stories, it is the easiest non-HTML way to demonstrate that still fits within the font size limits of this book in printed form.
virtualenv
setup.cart41.py
to contain an alternate version of the shopping cart application.class ShoppingCart(object): def __init__(self): self.items = [] def add(self, item, price): for cart_item in self.items: # Since we found the item, we increment # instead of append if cart_item.item == item: cart_item.q += 1 return self # If we didn't find, then we append self.items.append(Item(item, price)) return self def item(self, index): return self.items[index-1].item def price(self, index): return self.items[index-1].price * self.items[index-1].q def total(self, sales_tax): sum_price = sum([item.price*item.q for item in self.items]) return sum_price*(1.0 + sales_tax/100.0) def store(self): # This simulates a DB being created. f = open("cart.db", "w") f.close() def retrieve(self, id): # This simulates a DB being read. f = open("cart.db") f.close() def __len__(self): return sum([item.q for item in self.items]) class Item(object): def __init__(self, item, price, q=1): self.item = item self.price = price self.q = q
This version of the shopping cart has two extra methods: store
and retrieve
. They don't actually talk to a database, but instead create an empty file cart.db
. Why? The purpose is to simulate interaction with a database. Later in the recipe, we will show how to tag test cases that involve this operation and easily exclude them from test runs.
The following steps will show how to write scenarios in a format other than HTML tables, and also how to tag tests to allow picking and choosing which tests are run on the command line.
recipe41.txt
using plain text and space separated entries that has a couple of test cases—one simple one and another more complex one with documentation and tags.***Test Cases*** Simple check of adding one item Given an empty cart When I add a carton of milk for 2.50 Then the total with 0 % tax is 2.50 And the total with 10 % tax is 2.75 More complex by storing cart to database [Documentation] This test case has special tagging, so it can be excluded. This is in case the developer doesn't have the right database system installed to interact properly.cart.db [Tags] database Given an empty cart When I add a carton of milk for 2.50 And I add a frozen pizza for 3.50 And I store the cart And I retrieve the cart Then there are 2 items
It's important to note that two spaces are the minimum required to identify breaks between one cell and the next. The line with When
I
add
a
carton
of
milk
for
2.50
actually has four cells of information: |
When
I
add
a
|
carton
of
milk
|
for
|
2.50
|
. There is actually a fifth, empty cell that prefixes this row indicated by the two-space indentation. It is necessary to mark this row as a step in test case Simple
check
of
adding
one
item
rather than another test case.
***Keywords*** Given an empty cart create empty cart When I add a [Arguments] ${description} ${noop} ${price} add item ${description} ${price} And I add a [Arguments] ${description} ${noop} ${price} add item ${description} ${price} Then the total with [Arguments] ${tax} ${noop} ${total} ${calc total}= total ${tax} Should Be Equal ${calc total} ${total} And the total with [Arguments] ${tax} ${noop} ${total} Then the total with ${tax} ${noop} ${total} And I store the cart Set Test Variable ${cart id} store cart And I retrieve the cart retrieve cart ${cart id} Then there are [Arguments] ${size} ${noop} ${calc size}= Size of cart Should Be Equal As Numbers ${calc size} ${size}
recipe41.py
that contains Python code that bridges some of the keywords with the shopping cart application.from cart41 import * class recipe41: def __init__(self): self.cart = None def create_empty_cart(self): self.cart = ShoppingCart() def lookup_item(self, index): try: return self.cart.item(int(index)) except IndexError: return "ERROR" def lookup_price(self, index): try: return format(self.cart.price(int(index)), ".2f") except IndexError: return "ERROR" def add_item(self, description, price): self.cart.add(description, float(price)) def size_of_cart(self): return len(self.cart) def total(self, tax): return format(self.cart.total(float(tax)), ".2f") def store_cart(self): return self.cart.store() def retrieve_cart(self, id): self.cart.retrieve(id) def size_of_cart(self): return len(self.cart)
recipe41.txt
that imports our Python code as a library to provide the last set of needed keywords.***Settings*** Library recipe41.py
pybot recipe41.txt
.database
by typing pybot –exclude database recipe41.txt
.database
by typing pybot –include
database
recipe41.txt
.report.html
, and observe where the extra [Documentation]
text appears, as well as our database
tag.In this recipe, we added an extra section to the second test case, including both documentation and a tag.
More complex by storing cart to database [Documentation] This test case has special tagging, so it can be excluded. This is in case the developer doesn't have the right database system installed to interact properly.cart.db [Tags] database Given an empty cart When I add a carton of milk for 2.50 And I add a frozen pizza for 3.50 And I store the cart And I retrieve the cart Then there are 2 items
Tags are usable on the command line, as shown in the previous example. They provide a useful way to organize test cases. Test cases can have as many tags as needed.
We showed earlier that this provides a convenient command-line option to include or exclude based on tags. Tags also provide useful documentation, and the previous screenshot of report.html
shows that test results are also subtotaled by tag:
This recipe demonstrates plain text formatting. Triple asterisks are used to surround header cells and two spaces are used to designate a break between two cells.
It is debatable whether this is harder to read than HTML. It may not be as crisp as reading the HTML markup, but I personally preferred this to angle tax of reading HTML. It's possible to add more spaces, so the table's cells are clearer, but I didn't because the font sizes of this book don't work very well with it.
3.140.197.136