Building Reusable Components in Test Automation
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.
Pre-requisites:
- Node installation.
- 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
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!!!…