Grégoire
Posted on February 14, 2020
Read the original article on GKDV
For my custom needs, I was looking for puppeteer functional testing suite. As a php developer, I ordinary use behat to write and play my functional tests. But the project I want to test is python written, and I don’t want to install and configure PHP just to run tests. And what about puppeteer and chrome headless engine? Hey, I had an idea: implement the cool gherkin syntax with puppeteer in pyhton.
About Gherkin
Gherkin is a syntax which looks like:
Feature: Use the rest test suite
Scenario: We can fetch data from an api
Given I add these headers:
| accept | application/json |
Given I prepare a "GET" request to "/todos/1"
When I send the request
Then print the last json response
And the json node "anythng" should not exist
And the json node "userId" should exist
And the json node "id" should be equal to "1"
It’s readable by human, (I mean, by non-developer human :)) and it’s really easy to write.
About Puppeteer
Puppeteer is a Node library which provides a high-level API to control Chrome or Chromium over the DevTools Protocol, and allows to execute actions in a headless (without visible UI) version of chrome. In nodejs, these tests look like:
const puppeteer = require('puppeteer');
(async() => {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setRequestInterception(true);
page.on('request', request => {
if (request.resourceType() === 'image')
request.abort();
else
request.continue();
});
await page.goto('https://news.google.com/news/');
await page.screenshot({path: 'news.png', fullPage: true});
await browser.close();
})();
Understandable by developers, but a bit ugly (and boring to write)… However, using a real browser as chrome to play functional tests has a lot of advantages:
- javascript testing
- speed
- easy to use
Let’s play with pyppettheater
Pyppettheater is one of my amaziiing idea (and it’s what this article is about). In python, the puppether engine can be used thanks to Pyppeteer. And to parse the gherkin features files, we’ll use gherkin-parser.
Install pyppetheater
First, you have to install the chrome headless engine (under ubuntu):
$ wget -q -O - https://dl-ssl.google.com/linux/linux_signing_key.pub | apt-key add -
$ sh -c 'echo "deb [arch=amd64] http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google-chrome.list'
$ apt-get -y update
$ apt-get install -yqq unzip sudo python3-pip mysql-client google-chrome-stable
$ wget -O /tmp/chromedriver.zip http://chromedriver.storage.googleapis.com/`curl -sS chromedriver.storage.googleapis.com/LATEST_RELEASE`/chromedriver_linux64.zip
$ unzip /tmp/chromedriver.zip chromedriver -d /usr/local/bin/
$ pyppeteer-install
And install pyppettheater:
$ pip3 install Pyppetheater
You can now run the pyppet_theater
binary:
$ pyppet_theater /path/to/your/yml/or/feature/file
Some example of test
Each test suite is a yml file which contains some parameters (if needed):
parameters:
rest:
base_endpoint: https://jsonplaceholder.typicode.com
scenarios:
0: rest/rest-suite.feature
For a REST API:
For example in the rest/rest-suite.feature:
Feature: Use the rest test suite
Scenario: We can fetch data from an api
Given I add these headers:
| accept | application/json |
Given I prepare a "GET" request to "/todos/1"
When I send the request
Then print the last json response
And the json node "anythng" should not exist
And the json node "userId" should exist
And the json node "id" should be equal to "1"
$ pyppet_theater rest.yml
For a frontend test:
For example, in a game/registration.feature file:
Feature: Create an account on a website
Scenario: As a visitor, I register on the website
Given I go on "http://my-website.com"
And I click on "\#signup-link"
And I type "player6" in field "\#id_username"
And I type "somepassword" in field "\#id_password1"
And I type "somepassword" in field "\#id_password2"
When I click on "\#register"
Then I should be on "http://my-website.com"
And run it:
$ pyppet_theater game/registration.feature
For mysql tests:
With a mysql.yml
file
parameters:
mysql:
db_host: 127.0.0.1
db_user: root
db_password: root
db_name: test
scenarios:
0: "mysql/mysql-suite.feature"
And, in a mysql/mysql-suite.feature:
Feature: Use the mysql test suite
Scenario: We can select, update and check existence
Given the row with "id" equal to "1" in table "some_table" should exist
And the row with "id" equal to "1" in table "some_table" has "some_key" equal to "some_value"
Then the row with "id" equal to "1" in table "some_table" should have "some_key" equal to "some_value"
And the row with "some_key" equal to "some_value" in table "some_table" should exist
Scenario: We can delete and check existence
Given the row with "id" equal to "1" in table "some_table" does not exist
Then the row with "id" equal to "1" in table "some_table" should not exist
And run it:
$ pyppet_theater mysql.yml
You can also use the docker image.
To know more about Pyppettheater, go to the repo!
Posted on February 14, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.