Automate Testing with Lettuce
There are many different tools available to automate QA testing, they offer different functionality and have different capabilities.
Lettuce is a Python testing tool that provides a high-level API for writing tests. It provides a clean and simple API for testing with features such as automatic editing, test templates, and more. Lettuce is also built on top of the Behavior Driven Development (BDD) framework, which helps simplify test development by providing clients with common BDD assertions such as @given or @when.
In general, Behavior-driven development (BDD) is an agile software development tool in which an application is documented and designed with the behavior that the user expects to experience when interacting with it in mind. By encouraging developers to focus only on the desired behavior of an application or program, BDD helps avoid code redundancy, unnecessary features, or distraction.
Getting back to Lettuce, it supports many popular testing frameworks such as pytest, nose, and unittest2, but can be easily integrated with any workflow you prefer using plugins such as pytest-plugin-lint, pylint, tox, or cProfile.
Basic concept
BDD methodology, which is mainly used in Agile development, is based on the same principle as TDD (Test Driven Development) – writing a test before writing code.
The key is not only testing with unit tests, but also testing the application comprehensively with acceptance tests. The process can be simply defined as:
Writing tests that fail
Writing a TDD cycle (Test fails, pass, refactor code).
The acceptance test must be successful.
Acceptance tests use an English (or possibly alternative) language format called Gherkin syntax in a feature file that describes what the test covers and the individual tests themselves.
Gherkin is a human-readable language for describing system behavior that uses indents to define the document structure (spaces or tabs). Each line begins with one of the keywords and describes one of the steps. The test file is in turn divided into functions, scenarios, and the steps included in them.
A function is a short but comprehensive description of the required functionality. A scenario, in turn, is a specific business situation that starts it and contains a description.
Let's look at an example.
In the first line we give the test function:
Feature: Google Search
As a web surfer, I want to search Google, so that I can learn new things.
And here we provide the scenario itself, in which we indicate what exactly we are going to do, what tests to perform.
Scenario: Simple Google search
Given a web browser is on the Google page
When the search phrase “panda” is entered
Then results for “panda” are shown
Moreover, each scenario consists of a list of steps, each of which must begin with one of the keywords (we will give Russian-language terms):
Given
When
That
But
AND
The “But” and “And” steps exist solely for readability and repeat the keyword that began the previous line in their functionality. A functional description may contain one or more scenarios, and each scenario consists of one or more steps.
Having dealt with the Gherkin syntax, let's move on directly to writing tests.
Lettuce Installation
To install Lettuce, we just need to use the pip package manager:
pip install lettuce lettuce_webdriver nose
To run tests, simply execute the command:
lettuce
Writing tests
Once all the necessary components are deployed, we can start writing tests. As an example, we will write a test that will go to a web page, enter user credentials, and log in with them. We will call this file login.feature.
Feature: Test the features of our Login Form
Scenario: Test Login Form
Given I go to "http://crossbrowsertesting.github.io/login-form.html"
The title of the page should become "Login Form - CrossBrowserTesting.com"
And when I fill in "username" with "tester@crossbrowsertesting.com"
And when I fill in "password" with "test123"
When I press "Login"
I should see "You are now logged in!" within 10 seconds
Then the browser should close
In the line starting with Given we record the address of the web resource that needs to be visited. We specify the action in the line starting with When. And the result appears in the Then line.
This was the description file. Now we need to add a file with the code that will be executed. This file should be called steps.py
from lettuce import *
from lettuce_webdriver.util import assert_true
from lettuce_webdriver.util import AssertContextManager
from lettuce import step
@step(u'The title of the page should become "([^"]*)"')
def the_title_of_the_page_should_become(step, result):
title = world.browser.title
try:
assert_true(step, title == result)
except AssertionError as e:
world.browser.quit()
@step(u'when I fill in "([^"]*)" with "([^"]*)"')
def when_i_fill_in(step, locator, username):
try:
world.browser.find_element_by_name(locator).sendkeys(username)
except AssertionError as e:
world.browser.quit()
@step(u'When I click "([^"]*)"')
def when_i_press(step, locator):
try:
world.browser.find_element_by_link_text(locator).click()
except AssertionError as e:
world.browser.quit()
@step(u'the browser should close')
def browser_should_close(step):
world.browser.quit()
We've written handlers for each line of our script and are now almost ready to test, but we still need to specify the various parameters that should be used when connecting. Lettuce uses python to instantiate the RemoteWebDriver, and we need to make sure it uses our API names to select the OS/browser configuration.
To do this, let's create a terrain.py file.
from lettuce import *
from selenium import webdriver
import lettuce_webdriver.webdriver
username = ‘you@yourdomain.com' # make sure to change this to your username
authkey = ‘12345' # make sure to change this to your authkey
@before.all
def setUp():
caps = {}
caps['name'] = 'First Lettuce Test'
caps['build'] = '1.0'
caps['browserName'] = 'Firefox' # request the latest version of firefox by default
caps['platform'] = 'Windows 7' # To specify a version, add caps['version'] = 'desired version'
caps['screen_resolution'] = '1024x768'
caps['record_video'] = 'true'
caps['record_network'] = 'false'
world.browser = webdriver.Remote(
desired_capabilities = caps,
command_executor="http://%s:%s@hub.crossbrowsertesting.com:80/wd/hub"%(username, authkey)
)
def tearDown():
world.browser.quit()
Now everything is ready to run the tests. In the directory where we created our files, run the lettuce command:
![](https://habrastorage.org/getpro/habr/upload_files/e93/08e/c8b/e9308ec8b925e45fbcc1864417e766f2.png)
Conclusion
As you can see in this article, automating testing with Lettuce is not an overly complex task. A competent combination of test task descriptions and Python code allows you to significantly automate the testing process.
You can get more practical skills and testing tools within the framework practical online courses from industry experts.