Tagging Robot tests and running a subset

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.

Getting ready

  1. We first need to activate our virtualenv setup.
  2. Create a new file called cart41.py to contain an alternate version of the shopping cart application.
  3. Type in the following code that stores the cart to a database.
    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

    Note

    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.

  4. Next, we need to install Robot Framework, as shown in the earlier sections of this chapter.

How to do it...

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.

  1. Create a new file called 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

    Note

    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.

  2. Add a table for custom keyword definitions using plain text and space separated values.
    ***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}
  3. Create a new file called 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)
  4. Add a last table to recipe41.txt that imports our Python code as a library to provide the last set of needed keywords.
    ***Settings***
    Library  recipe41.py
  5. Run the test scenario as if we were on a machine that had database support by typing pybot recipe41.txt.
    How to do it...
  6. Run the test scenario, excluding tests that were tagged database by typing pybot –exclude database recipe41.txt.
    How to do it...
  7. Run the test scenario, including tests that were tagged database by typing pybot –include database recipe41.txt.
    How to do it...
  8. Look at report.html, and observe where the extra [Documentation] text appears, as well as our database tag.
    How to do it...

How it works...

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:

  • Tags can be used to identify different layers of testing like smoke, integration, customer-facing, and so on
  • Tags can also be used to mark subsystems like database, invoicing, customer service, billing, and so on

There's more...

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.

Note

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.

What about documentation?

We also added a little bit of documentation for demonstration purposes. A piece of the text appears when pybot runs, and it also appears in the resulting artifacts.

See also

  • Installing the Robot Framework
  • Creating a data-driven test suite with Robot
  • Writing a testable story using Robot
..................Content has been hidden....................

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