Introduction to
Automated Testing

in
Hi.
Sanjeev Yadav
Trainee Software Engineer

What is Testing?


Why Should you care?

Testing = Documentation
// Import your highly mysterious function
const mysteriousFunction = require("./app");
// when you write descriptive test, it serves as a documentation
test("I don't know what this function do", () => {
// Setup
const input = "This is a sentence";
const expectedResult = ["This", "is", "a", "sentence"];
//
const result = mysteriousFunction(input);
// Verify
expect(result).toBe(expectedResult);
});
// Looks like, the mysteriousFunction takes string as an input
// and returns an array of wordsand more...
Get an error if you break code
Save Time
Think about possible issues & bugs
Integrate into build workflow
More modular code
Improve your code
Different Kinds of Tests
Fully Isolated
(e.g. testing one function)
With Dependencies
(e.g. testing a function
that calls another function)
Full Flow
(e.g. Validating a login
flow)
Unit Test
Integration Test
End-to-End Test
Write thousands
of these
Write a good
couple of these
Write a
few of these
Test Driven Development
(TDD)
Write test first, then logic

Jest.js
- JavaScript Testing Framework
- Developed by Facebook
- Works with React/Angular/Vue/Node/TypeScript/Babel
- Fast
- Function Mock
- Code Coverage & Snapshots

Jest Globals
// Runs a function before any of the tests in this file run.
beforeAll(fn, timeout)
// Runs a function before each of the tests in this file runs.
beforeEach(fn, timeout)
// Runs a function after all the tests in this file have completed.
afterAll(fn, timeout)
// Runs a function after each one of the tests in this file completes.
afterEach(fn, timeout)
// All you need in a test file is the test method which runs a test.
test(name, fn, timeout)Ex.
test('sum of 2 + 2 is 5', () => {
expect(add(2, 2)).toBe(4);
});Jest Matchers
Jest uses matchers to let you test values in different ways
// tobe uses Object.is
// to match two values
.toBe()// use toEqual to match objects
// & arrays
.toEqual()expect(2).toBe(2) // Pass
expect(true).toBe(false) // Fail
expect(null).toBe(null) // Passconst data = {one: 1};
data['two'] = 2;
// Pass
expect(data).toEqual({one: 1, two: 2});Truthiness
test('null', () => {
const n = null;
expect(n).toBeNull();
expect(n).toBeDefined();
expect(n).not.toBeUndefined();
expect(n).not.toBeTruthy();
expect(n).toBeFalsy();
});Numbers
test('two plus two', () => {
const value = 2 + 2;
expect(value).toBeGreaterThan(3);
expect(value).toBeGreaterThanOrEqual(3.5);
expect(value).toBeLessThan(5);
expect(value).toBeLessThanOrEqual(4.5);
});test('there is no I in team', () => {
expect('team').not.toMatch(/I/);
});Strings
And more...
.toContain()
.toBeFalsy()
.toHaveBeenCalled()
.toBeSexy()
// and many more...Part 2
Embarrassing myself while
trying to Live Code!

Example of Unit & Integration testing
(add 2 (subtract 4 3))add(2, subtract(4,3));Input
Output
Compiler
Lisp Syntax
C Syntax
Compiler
Input
Parsing
Transformation
Code Generation
output
(add 2 (subtract 4 3))abstract syntax tree
modified abstract syntax tree
add(2, subtract(4, 3));Parsing
Input
tokenizer()
parser()
(add 2 (subtract 4 3))[
{ type: 'paren', value: '(' },
{ type: 'name', value: 'add' },
{ type: 'number', value: '2' },
{ type: 'paren', value: '(' },
{ type: 'name', value: 'subtract' },
{ type: 'number', value: '4' },
{ type: 'number', value: '3' },
{ type: 'paren', value: ')' },
{ type: 'paren', value: ')' },
];{
type: 'Program',
body: [
{
type: 'CallExpression',
name: 'add',
params: [
{
type: 'NumberLiteral',
value: '2'
},
{
type: 'CallExpression',
name: 'subtract',
params: [
{
type: 'NumberLiteral',
value: '4'
},
{
type: 'NumberLiteral',
value: '3',
}
]
}
]
}
]
}tokens
abstract syntax tree
Compiler
Input
Parsing
Transformation
Code Generation
output
(add 2 (subtract 4 3))abstract syntax tree
modified abstract syntax tree
add(2, subtract(4, 3));Integration Test: Demo
Example of End 2 End testing
Detox.js

Detox.js
-
End-to-end testing framework
-
Help automate manual QA process
-
Detox uses EarlGrey for iOS and Espresso for Android under the hood
-
Deep first-class support for Recat-Native
-
Made For CI: Execute your E2E tests on CI platforms like Travis
-
Integrates with jest.js

Detox Matchers
Detox uses Matchers to find UI `elements`
// by.id will match an id that is given to the view
// via testID prop.
by.id()
// Find an element by text, useful for text fields, buttons.
by.text()
// Find an element by accessibilityLabel on iOS,
// or by contentDescription on Android.
by.label()
// Find an element by native view type.
by.type()// In a React Native component add testID like so:
<TouchableOpacity testID={'tap_me'}>// You can access the element using by.id function
const button = element(by.id('tap_me'))Component.js
test.js
Actions
Actions emulate user interaction with those `elements`
// Functions
.tap()
.longPress()
.multiTap()
.tapAtPoint()
.tapBackspaceKey()
.tapReturnKey()
.typeText()
.replaceText()
.clearText()
.scroll()
.scrollTo()
.swipe()// Example
const button = element(by.id('tap-me'));
button.tap();Expectations
Expectations to verify value on those `elements`
// Functions
.toBeVisible()
.toBeNotVisible()
.toExist()
.toNotExist()
.toHaveText()
.toHaveLabel()
.toHaveId()
.toHaveValue()// Example
const inputText = element(by.id('UniqueId204'))
expect(inputText).toBeVisible();Demo

Any Questions?

Feedback

Links
Slides:
Jest.js:
Detox.js:
Demo 1:
Demo 2:
Video recording of this seminar:
THE END

Introduction to Automated Testing in JavaScript
By Sanjeev Yadav
Introduction to Automated Testing in JavaScript
This session is meant to give a brief introduction to testing along with how to write tests for your JavaScript Application. The talk is orientated towards novices and it would be a stepping stone towards writing test for your React/Angular projects.
- 414

