Building Reusable Components in Test Automation

Arun Sarode
TestVagrant
Published in
4 min readAug 24, 2021

When we work on big projects they usually are divided into sub-projects based on features/modules etc…

In this situation, our automation code also is divided based on multiple sub-projects and our automation tests will be in sync with the respective project's feature testing.

There will be some features in common for both sub-projects example login flow, logout flow, Navigation, Driver related activity(Closing driver, Getting cookie, Util methods, etc…)

We might end-up up writing different implementation/code for the same feature/function on different sub-projects.

Approach:

To avoid duplicate code and redundant effort, we can maintain common reusable code(common git repository) across projects.

For Example, Report Integration, Email Notification, Loggers, etc…
are common for all automation projects. we can keep these in a single repository and reuse them across all other internal sub-projects.

Advantages:
* Write once reuse across (Dry Principle).
* Save time and effort.
* One point control for common utilities of all the sub-projects.
* Easy to integrate with new sub-projects.

Pictorial Representation

Pre-requisites:

  1. Node installation.
  2. Know Javascript(Typescript).

Let’s start with steps:

Create common utility project

Create project “CommonUtility”, which would be having most of the common reusable code/logic, as depicted in the image

Common code arrangement

Below is the sample tsconfig.json file

{
"compilerOptions": {
"lib": ["dom", "ES2020"],
"target": "ES2020",
"module": "commonjs",
"moduleResolution": "node",
"noImplicitAny": true,
"noImplicitReturns": true,
"resolveJsonModule": true,
"esModuleInterop": true,
"declaration": true,
"allowJs": false,
"outDir": "dist",
"sourceMap": true,
"types": ["node", "mocha", "chai", "webdriverio"],
"skipLibCheck": true
},
"compileOnSave": true,
"exclude": ["node_modules", "dist"]
}

Below is the sample .npmignore file, this file will help in what are the item’s we would like to ignore while publishing the package

/node_modules
/PreviousVersions

Publishing common utility:

Creating common code as a package(.tgz file) that can be used in other projects

below are the scripts we need to add under package.json

{
"name": "common-utility",
"version": "0.0.1",
"description": "common utility code base for reusable methods",
"main": "dist/index.js",
"types": "dist/index.d.ts",
"scripts": {
"compile": "tsc",
"generate-package": "npm pack"
},
"license": "ISC",
"devDependencies": {
.
.
},
"devDependencies":{
.
.
}
}

commands to execute to prepare a package

npm run compile (to compile code to for any error)npm run generate-package (to generate commonUtility-0.0.1.tgz file locally with all dependency)

post generation of the .tgz file, we need to move under the “versions” folder and push the code to git

Note: 
* As of now publishing package within git repo, even we can publish the package to repositories as well(refer
here).
* For every change in the code we need to modify version number in the package.json file execute above commands.

Utilising common utility within sub-projects

Copy commonUtility-0.0.1.tgz file from the Common Utility git repo to sub-projects, and update package.json dependencies with respective common utility version numbers.

"dependencies":{
"common-utility":"file:./commonUtility-0.0.1.tgz",
.
.
}

After updating the above dependency execute the command npm install

If newly added methods doesn’t reflect in sub-projects after npm i try to run command
npm cache clean — force

Use of methods exposed by Common Utility project in our Subprojects code

import {BrowserUtil, DateTimeUtil} from 'common-utility'describe('demo on usage of common utility code',()=>{
it('first test case', async ()=>{
let dummyConfig:{};
let driver = await BrowserUtil.setupBrowser(dummyConfig,'dummy spec name');
await BrowserUtil.open(driver, 'sample url to open');

// date time util
let todayDate = await DateTimeUtil.getTodayDate();
let addMinutes = await DateTimeUtil.addMinutesToDate(new Date(),10);
});
});

References:

Happy Learning!!!…

--

--