The PyTest Automation Boilerplate contains reusable content, which will enable you to test Web, API, Visual and Mobile native apps on web and mobile platforms.
- UI Web Test Automation with Pytest Selenium & Pytest BDD
- API Test Automation with Pytest & Requests
- Mobile Test Automation with Pytest & Appium
- Cross Browser Testing with BrowserStack
- Test Case Management with TestRail
- Notifications with Slack & MS Teams
- Reporting with Allure & Custom HTML
- Parallel Execution with Pytest-xdist
This document assumes that user has:
- A valid github account & access in github.
- Access to
pytest-automation-boilerplaterepository, and/or additional test repositories. - Have installed your favourite IDEs (Pycharm or VSCode - it's recommended) and/or set up your terminal for development environment.
-
Homebrew
Make sure that
homebrewis successfully installed. Check if it is already installed by typingbrew --versionin your terminal. You should see output similar to below lines, if it is already installedHomebrew 4.2.12
If not installed, please follow below instructions to install. Detailed Instructions here: HomeBrew Installation
-
Xcode Command-line Tools
Ensure to have Xcode CLI tools installed. Check if it is already installed using command
xcode-select --version. If it is successfully installed, you would see output similar to this:xcode-select version 2384.If not already installed, install by typing commandxcode-select --installin terminal. -
Android Studio for Local Android Native App
Ensure to have Android Studio tool installed. and Install Virtual Device Simulator ("deviceName": "emulator-5554").
-
Git
Most Mac Machines come with latest version of Git pre-installed. Check if you have git installed in your system by typing below command in your terminal
git --version # you should see output similar to below if installed. git version 2.44.0If not already installed, execute command
brew install gitto install latest git version. After successful installation, check for the git version number using commandgit --version. -
Python
Recommended Version of Python: 3.9.12
Though Mac comes pre-installed with Python 2.7 and Python 3 (mostly 3.6+), we would not want to 'disturb' the system python versions. Its best to leave it undisturbed. We would use
pyenvto install latest version of Python by following below instructions. Detailed Instructions here: pyenvFor any issues faced during installation, please refer pyenv GitHub here
brew update brew install openssl readline sqlite3 xz zlib # Any issues encountered during execution of above command, please refer here: `https://github.com/pyenv/pyenv/wiki/Common-build-problems` for possible solutions/workarounds # pyenv-installer curl https://pyenv.run | bash # Restart Shell exec $SHELL # Verify pyenv is installed successfully pyenv --version # If you get issues with running above command, ensure the paths are properly set. Run below commands # Note: If you source bashrc in profile, then first two lines should come before the line which sources, `source ~/.bashrc` and last line should be at the bottom of the file. # If you are using `zsh`, replace .profile with .zprofile, and .bashrc with .zshrc echo 'export PYENV_ROOT="$HOME/.pyenv"' >> ~/.profile echo 'export PATH="$PYENV_ROOT/bin:$PATH"' >> ~/.profile echo 'eval "$(pyenv init --path)"' >> ~/.profile echo 'eval "$(pyenv virtualenv-init --path)"' >> ~/.profile # Also add following lines to .zshrc (if your shell is zsh) eval "$(pyenv init -)" eval "$(pyenv virtualenv-init -)" # Close the file and source it source ~/.zshrc # Verify Installation username@hostname ~ % exec $SHELL username@hostname ~ % pyenv --version # Install latest available version of python username@hostname ~ % pyenv install 3.9.12 username@hostname ~ % pyenv global 3.9.12
Manual Python 3.9.12 installer: here
-
Clone Boilerplate Project Clone the Boilerplate
masterbranch from Github to your local machine by following below instructions.mkdir workspaces && cd workspaces git clone https://github.com/tweag/pytest-automation-boilerplate.git # alternatively, you could use ssh link if you have setup ssh in your work machine.
-
source setup_install.sh After successful cloning, execute below commands to install BoilerPlate (for local, If would like to pypass this script then follow the manual installation through (pip install -r requirements.txt)
cd pytest-automation-boilerplate/ source setup_install.sh
-
Activate your Virtual Environment In the above step using source setup_install.sh automatically activates the virtual environment. For eg: After installation you will see the following.Yet another Important Note: Please activate virtual environment using command ". /Users/username/.bp-venv/bin/activate" while running test cases from new shell. Need not activate now, since it is already activated.
(.bp-venv) username@hostname python-test-automation-boilerplate %
If Virtual Environment has to be activated without the installation step i.e once initial installation is completed then following command is used
#Command Line for MAC source /Users/username/.bp-venv/bin/activate #Command Line for Windows source /Users/username/.bp-venv/Scripts/activate
-
Setup Environment Variables in
.local.env&pytest.inifiles After successful installation, check and updateenv_configs/.local.envandpytest.inifiles with relevant details. -
Appium setup for Mobile apps If you are planning to run mobile tests, you need to install Appium server and start it before running the tests. Detailed instructions can be found here
-
Local Setup for BrowserStack If you are planning to run tests on BrowserStack, you need to install BrowserStack Local binary and start it before running the tests. Detailed instructions can be found here
-
Local Setup for Docker you need to install Docker desktop before running the docker-compose.yml file. Detailed instructions can be found here
Users can invoke pytest command to run test cases locally, with required arguments, as appropriate. Applicable
command line arguments to be passed to pytest command:
--driver=<test-browser-name>This should be passed mandatorily while running UI/selenium test cases. Test Browser name would bechrome,firefoxoredgeorsafarias per the test needs for local testing. UseRemotefor testing using Docker/BrowserStack andAppiumfor mobile tests.--language=<en|fr|etc.>Application Language, used in context of UI testing (selenium)--capability <individual-capability-value>Additional individual capabilities can be set using the --capability command line arguments. As an example, for setting the run in a headless mode you will have '--capability headless True'--variables <capabilities.json>To specify multiple capabilities, you can provide a JSON file on the command line using the pytest-variables plugin.--tags=<tag name>This is the gherkin tag name mentioned in the feature file, to filter the tests. Some of the pre-defined sample tags that can be used for testing are:web-testsvisual-testsapi-testsandroid-testsiOS-tests
--gherkin-terminal-reporterTo be used to override the default pytest terminal report, and display in gherkin format (frompytest-bddplugin). (Please note, we can't use -n with this argument (*--gherkin-terminal-reporter) due to a restriction. so just remove this console printing before parallel execution)--html=<path-to-html-output> --self-contained-htmlTo generate html report (frompytest-htmlplugin). To see full log output in the html report avoid-sargument in the same time.-n <number-of-threads>To run tests with multiple number of threads in parallel (frompytest-xdistplugin).
Sample pytest invocation to run all sample ui tests in Chrome browser with 3 threads in parallel:
pytest -v --driver=Chrome --capability headless True --tags=web-tests -n=1Boilerplate framework is using built-in driver manager to handle the driver binaries for each browser.
There is no need to provide --driver-path argument anymore. Selenium lib. will automatically detect the browser version and download required binary driver.
All the drivers will be stored in the $HOME/.cache/selenium/ folder.
More info: here
.
├── / # root directory with project-wide env_configs and folders
├── /app files # directory with all android and ios app files/builds
├── /webdriver # directory contains all the driver binaries / Browserstack local binary
├── /main # directory contains all the base code (utils, plugins, common steps...) for the framework
├── /env_configs/ # Configurations related to framework & browser specific
├── /frontend/ # Project specific files (locators, page objects, step definitions, feature files... etc)
├── /frontend/features/* # Test cases written in Gherkin language
├── /frontend/locators/* # Web locators for the project
├── /output/ # Reports, downloads.... etc)
├── /test_data/ # All project test data for API, WEB, Mobile tests)
│ ├── /conftest.py # Step up and tear down for the tests
│ ├── /setup_install.sh # Local Setup script
│ ├── /**.sh # Shell scripts for local/CI runs
│ ├── /pytest.ini # Project init file
│ ├── /docker-compose.yml # To build the docker image
│ ├── /README.md # Instructions for the project
│ ├── /requirements.txt # Dependencies
Ensure to set/update following details in env_configs/.local.env file before interacting with testrail.
IMPORTANT_NOTE: If you are updating to project v3.10 or newer make sure to store your TestRail related env_configs in '.local.env' file. The reason for that is BoilerPlate releases up to v3.8, all TestRail related env_configs were stored in 'pytest.ini' file. With current release all TestRail data are stored in the file mentioned below:
.local.env
TESTRAIL_EMAIL=[email of user to be used for communication]
TESTRAIL_KEY=[key of user to be used for communication]
TESTRAIL_URL=[URL of TestRail instance]
TESTRAIL_PROJECT_ID=[project id to which the data is sent]
JIRA_PROJECT_KEY=[Jira project key for integration with Jira]
-
Export Test Cases
To import/update test Scenarios for ALL feature files
python -m pytest -v --pytest-testrail-export-test-cases --pytest-testrail-feature-files-relative-path "[path-to-features-dir]"To import/update test Scenarios for INDIVIDUAL .feature file
python -m pytest -v --pytest-testrail-export-test-cases --pytest-testrail-feature-files-relative-path "[DIR_NAME]/[FILE_NAME].feature" -
Export Test Results
- You have to manually create the test plan in TestRail
- Naming convention: [JIRA_PROJECT_NAME][SPRINT_NAME][MARKET] - MARKET only if applied
- eg: JIRA_Sprint-1_us or JIRA_Regression_us
- Naming convention: [JIRA_PROJECT_NAME][SPRINT_NAME][MARKET] - MARKET only if applied
- Then add the Test Suite to the test plan (While exporting tests, it automatically creates a testsuite)
- Add a configuration to the test suite and then run below command
# Mandatory Parameters # pytest-testrail-test-plan-id : Testrail Plan ID # pytest-testrail-test-configuration-name: Testrail Configuration Name
Run tests on different browsers using the below command:
# Usage example for Windows 11 - Chrome
username@hostname python-test-automation-boilerplate % python -m pytest -v --reruns 1 --reruns-delay 1 --gherkin-terminal-reporter --driver Remote --selenium-host '[BS_USERNAME]:[BS_KEY]@hub-cloud.browserstack.com' --capability browserName 'Chrome' --capability os 'Windows' --capability osVersion '11' --capability build 'eucrisahcpcom-qa' --capability browserstack 'True' --tags="p1"For more details on usage, please read through these pages:
- BS - Test Local Host Websites
- BS - Test Websites Hosted on Private Internal Servers
- BS usage with Python
Please read BS documentation for more details on configurations:
- https://www.browserstack.com/automate/python
- https://www.browserstack.com/app-automate/appium-python
- For running parallel test from local in the browserstack you can add -n [parallel threads value] -> e.g.: "-n '2'"] to your command. -n represents the number of processes to execute the test cases in parallel mode. We can also pass "auto" to use as many processes as your computer has CPU cores. This can lead to considerable speed ups, especially if your test suite takes a noticeable amount of time.
Reference Link - https://pypi.org/project/pytest-xdist/
- Upload your Android app (.apk or .aab file) or iOS app (.ipa file) to BrowserStack servers using our REST API. Here is an example cURL request to upload the app :
curl -u "YOUR_USERNAME:YOUR_ACCESS_KEY" \
-X POST "https://api-cloud.browserstack.com/app-automate/upload" \
-F "file=@/path/to/app/file/Application-debug.apk"- We will receive below sample response which we need to add it in the env_configs/ios_mobile_BS.json and env_configs/android_mobile_BS.json file
{
"app":"bs://j3c874f21852ba57957a3fdc33f47514288c4ba4"
}Command for local run on chrome (also ./local_run_web.sh)
-v -s --gherkin-terminal-reporter --driver=Chrome --html="./output/reports/" --self-contained-html --capability headless True --tags="web_tests" --reruns 1 --reruns-delay 2 -n=2Command for local run on firefox
-v -s --gherkin-terminal-reporter --driver=Firefox --capability headless True --html="./output/reports/" --tags="web_tests" --self-contained-html --reruns 1 --reruns-delay 2 -n=1Command for local run on BS with Chrome:
-v -s --gherkin-terminal-reporter --driver=Remote --selenium-host '[BS_USERNAME]:[BS_KEY]@hub-cloud.browserstack.com' --variables="env_configs/mac_chrome.json" --html="./output/reports/" --tags="web_tests" --reruns 1 --reruns-delay 2 --self-contained-htmlCommand for local run on local appium server:
-v -s --gherkin-terminal-reporter --driver=Appium --html="./output/reports/" --tags="mobile_test and android" --variables="env_configs/android_mobile_local.json" --self-contained-html --reruns 1 --reruns-delay 2Command for local run on BS with IOS:
-v -s --gherkin-terminal-reporter --disable-warnings --driver=Appium --html="./output/reports/" --selenium-host '[BS_USERNAME]:[BS_KEY]@hub-cloud.browserstack.com' --variables="env_configs/ios_mobile_BS.json" --self-contained-html --tags="mobile_test and ios" --reruns 1 --reruns-delay 2There is a param in .local.env file to set the integration:
# BROWSERSTACK , SAUCELABS, DOCKER
USING_ENV=SAUCELABSTo generate a html report please add following arguments to your command:
--html=<path_to_report> and --self-contained-html<path_to_report> - Project path where the html report will be created.
For example:
--html=./output/reports/
Example of full command to generate html reports:
python -m pytest -v --tags="sample-ui-tests" -n=3 --variables=./env_configs/web_local.json --driver=chrome --html=./output/reports/ --self-contained-htmlPlease avoid adding -s in the CLI since it will not include any logs in the html report.
For GitHub actions please update .yaml including .html file and ./assets folder as in this example.
- name: Upload pytest test results
uses: actions/upload-artifact@v2ł
with:
name: pytest-results
path: |
./*.html
./assets/
./output/
if: ${{ always() }}
by default allure report generates at output/allure/reports at the end of test execution, results are inside /output/allure/results folder.
A list of workflows are added in the .github/workflows folder. e.g Docker execution, Browserstack execution, Local execution, Mobile execution, Testrail execution, etc. ** about billing of github actions, please check the github documentation. (https://docs.github.com/en/billing/managing-billing-for-github-actions/about-billing-for-github-actions)
Use proper wait predefined step to handle the time needed between action steps
Avoid using static wait between steps and use instead the predefined step to wait for a specific web element. In this way we do not hardcode the amount of time needed for an element to appear, we are specifically waiting for it to be displayed.
Therefore, instead of having:
When I click on 'login > sign-in'
And I pause for 5 seconds
And I set text 'username' to field 'login > email'
The right approach is:
When I click on 'login > sign-in'
And The element 'login > email' is displayed
And I set text 'username' to field 'login > email'
Always use these common points:
-
Write clear & concise features using Gherkin, to define behaviour of the system. Scenario Structure
-
Organize scenarios into meaningful groups.
-
Use scenarios to describe test cases / user stories, keeping them focused & atomic Reusable Steps
-
Identify common steps that can be reused across multiple scenarios & abstract them into reusable step definitions. Test Data Management
-
Manage test data effectively.
-
Ensure each scenario has necessary data inputs to execute successfully.
Slack and MS Teams notifications support is available, we can set webhooks in pytest.ini file
--slack-webhook-url=https://hooks.slack.com/services/....
--slack-channel=pytest-test-automation
--slack-failure-only=true
--slack-results-url=http://localhost:63342/pytest-automation-boilerplate/output/allure/reports/index.html
--teams-webhook-url=https://moduscreate.webhook.office.com/...
--teams-failure-only=true
--teams-results-url=http://localhost:63342/pytest-automation-boilerplate/output/allure/reports/index.html
** Local web driver warnings (if any) resolution for Safari browser on mac**
/usr/bin/safaridriver --enableFor chrome webdriver warning (if any):
xattr -d com.apple.quarantine $(which chromedriver)To be decided soon...