Set up Running Automated UI tests on your First day at work: Part 4

For Mocha, PyTest and Cucumber tests

Courtney Zhan
6 min readApr 3, 2022

--

The previous three articles in this series showed Selenium WebDriver (Ruby binding) tests in RSpec. There are other frameworks such as Cucumber, Mocha and PyTest, which I have used as well. But I prefer using RSpec as it is simple and easy to read.

TestWise (the functional testing IDE used in Part 1 and Part 3 of this series) supports several test frameworks besides RSpec. This article will show how to get set up with a few other popular test frameworks (Mocha, PyTest and Cucumber) in TestWise on your first day.

Before you begin

I recommend that you follow the steps in Part 3 to install TestWise standard Edition, with executable environments set up for your test scripts, such as Python for Pytest, Ruby for Cucumber, Node.js for Mocha.

You can verify the setup (being able to run tests from the command line) in TestWise.

TestWise setting dialog

MochaJS

Mocha is one of the most popular JavaScript test frameworks. Here, I will focus on Selenium WebDriver’s JavaScript binding of Mocha. Below is a sample Mocha test.

describe('User Authentication', function() {before(async function() {
this.timeout(timeOut);
driver = new webdriver.Builder().forBrowser('chrome').setChromeOptions(helper.chromeOptions()).build();
driver.manage().window().setRect({width: 1027, height: 700, x: 30, y: 78})
});
beforeEach(async function() {
this.timeout(timeOut);
await driver.get(helper.site_url());
});
after(function() {
if (!helper.is_debugging()) {
driver.quit();
}
});
it ('[1,2] Invalid user', async function() {
this.timeout(timeOut);
await driver.findElement(webdriver.By.name('username')).sendKeys('agileway');
await driver.findElement(webdriver.By.name('password')).sendKeys('whenwise');
await driver.findElement(webdriver.By.name('commit')).click();
await driver.getPageSource().then(function(page_source) {
assert(page_source.contains("Invalid email or password"))
});
});
it('User can login successfully', async function() {
this.timeout(timeOut);
await driver.findElement(webdriver.By.name('username')).sendKeys('agileway');
await driver.findElement(webdriver.By.name('password')).sendKeys('testwise');
await driver.findElement(webdriver.By.name('commit')).click();
await driver.getPageSource().then(function(page_source) {
assert(page_source.contains("Welcome"))
});
await driver.findElement(By.linkText("Sign off")).click();
});
});

To create a new Mocha project in TestWise, select ‘Mocha’ for the Test Script Syntax.

TestWise will help you set up a project skeleton with a helper method. From here, you can begin writing your tests and running them!

Using Mocha

As one of the long-standing and most popular JavaScript test syntax frameworks, I recommend Mocha over other JavaScript alternatives.

Generally, I don’t find JavaScript tests as readable as RSpec tests. There are many asyncand await calls, plus an abundance of semicolons. To readers with a non-JavaScript background, it can be not very clear. Tests should be readable and usable for everyone in a team (including non-technical members like Business Analysts), and JavaScript can be a blocker.

An important note is that in RSpec, all the page object models in the/pages folder will be imported. In JavaScript, you will need to import each page manually (if you know a better and simpler way, please let me know). For example:

var FlightPage = require('../pages/flight_page.js');

Reimporting pages at the top of every spec can easily slip your mind, so it is something to remember.

PyTest

PyTest is a test syntax framework in Python. PyTest is compatible with the standard unittest (for unit testing), it can be used for functional test scripts as well.

To ensure you installed PyTest correctly, use TestWise’s sample project, open the pytest folder and run a file.

Here is the first test in the sample file 1_login_test.py:

import unittest
import xmlrunner
import time
import datetime
import sys
import os
from selenium import webdriver
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + "/../")
from test_helper import TestHelper
from pages.login_page import LoginPage
class LoginTestCase(unittest.TestCase, TestHelper):@classmethod
def setUpClass(cls):
if os.environ.get('BROWSER') == "firefox":
cls.driver = webdriver.Firefox()
else:
cls.driver = webdriver.Chrome()
cls.save_driver_session()
cls.driver.set_window_size(1280, 720)
cls.driver.set_window_position(30, 78)
@classmethod
def tearDownClass(cls):
if not cls.is_debugging():
cls.driver.quit()
def setUp(self):
self.driver.get(self.site_url())
def test_sign_in_failed(self):
self.driver.find_element(By.ID, "username").send_keys("agileway")
self.driver.find_element(By.ID, "password").send_keys("badpass")
self.driver.find_element(By.XPATH, "//input[@value='Sign in']").click()
self.assertIn("Demo Fail this test case",
self.driver.find_element(By.TAG_NAME, "body").text)

To create a new PyTest project in TestWise, select ‘Pytest’ for the Test Script Syntax.

Again, TestWise will helpfully create the project structure and helper files.

Using PyTest

PyTest is a robust Python test framework that extends beyond automated functional UI testing. As such, some Python programmers may already have experience in PyTest.

I have found that the self can be frustrating to remember. This is because, without it, it is incredibly similar to RSpec. It looks better when page object models are used and self won’t be used much within a test method.

Something to note for Python tests is to look out for indenting, especially for non-python programmers. Sometimes TestWise’s autoformatter (or human error) can affect the indenting, so be careful when refactoring.

Cucumber

Cucumber is a specialised Behaviour-Driven Development (BDD)-based testing framework written in Ruby. Here is a sample Cucumber test.

@feature
Feature: User Authentication
As a reigstered user
I can log in
Scenario: Deny access due to invalid password
Given I am on the home page
When enter user "agileway" and password "badpass"
And click "Sign in" button
Then I should see an log in error message

Warning: this syntax (Gherkin) looks readable, however, it comes with a huge maintainace cost, the cost that has failed many test automation attempts. For more, please read this article: Why Gherkin (Cucumber, SpecFlow,…) Always Failed with UI Test Automation?

To create a new Cucumber project in TestWise, select ‘Cucumber’ for the Test Script Syntax.

Again, TestWise will helpfully create the project structure and helper files.

Using Cucumber

As Cucumber is Ruby-based, I recommend writing the test cases in RSpec first before converting them to Cucumber. For instance, in the above Cucumber test excerpt, the line “When enter user X and password Y” is defined as:

When('enter user {string} and password {string}') do |user, pass|
driver.find_element(:id, "username").send_keys(user)
driver.find_element(:id, "password").send_keys(pass)
end

You may notice that the content of the method is the same as in RSpec. Hence, if you are required to use Cucumber, my recommendation is to write in RSpec first, then refactor it out to a Cucumber script.

TestWise can run all these frameworks in one test project.

TestWise is mostly a generic functional testing IDE, which means it can support multiple test syntax frameworks in various scripting languages. You can even include different test scripts within one test project, such as RSpec, Cucumber, PyTest and Mocha.

Below is a video (animated GIF) of TestWise executing MochaJS, PyTest and Cucumber tests, all in the same project.

Run Cucumber, Mocha and PyTest tests in TestWise

Recommendation

I use TestWise for developing/debugging automated tests for API, Web apps and Desktop apps.

API: raw Ruby with RSpec

Web app: raw Selenium WebDriver with RSpec

Desktop app: raw Appium with RSpec

After reaching a dozen tests, I don’t run the whole suite in TestWise or any other testing tools, instead, you should (actually must) run all tests in a Continuous Testing server such as BuildWise, which will be the topic for the next one.

--

--