Javascript Unit Testing and TDD
Techniques
By Mona Mohsen
● Testing Life Cycle
● Types of Test
● Unit Test Features
● Test Utility Code
● Structure Inspection and
Course Content Test-Specific identity
● Writing unit test using Mocha
● Writing unit tests using Jasmine
● Introduction to TDD
What is the testing
What’s the testing ?
Jupiter
Is the a way is a gas
to assess thegiant andofalso
quality the the biggest
software and to reduce the
planet
risk of SW failures in operation in the Solar System
Jupiter
Jupiterinvolves
Testing is a gas checking
giant andwhether
also thethe
biggest
system meets specified
Testing requirements planet in the Solar System
Jupiter
Testing also involves validation : which is checking whether the
Jupiter
system meets is aand
user gasother
giantstakeholder
and also the biggest
needs in its operational
planet in the Solar System
Jupiter
environment
Why do we test?
Why do we test?
● Most of people have had an experience with Sw that didn’t work as expected
● SW that does not work correctly can lead to many problems including:
○ Loss of money, time, or business reputation, and even injury or death .
● To prevent defects by evaluate work products such as :
○ Requirements, User stories,Design, and Code
● To verify whether the test objective is complete, and works as the users and
other stakeholder expect .
Objectives of Testing
● Build confidence in the level of the quality of the SW.
● Find defects and failures thus reduce the level of risk in tested SW
● Provide sufficient information to stakeholders to allow them to make
information decisions especially regarding the level of quality of the test
objectives
● To comply with contractual, legal, or regulator requirements. Or standards, and
/or to verify the test objectives compliance with such requirements or standards
Testing Life Cycle
Software Testing Life Cycle (STLC):
Test Planning
Requirement
Analysis
Monitoring And Control
Testing life Cycle Test Design
Test
is a sequence of specific activities conducted Implementation
during the testing process to ensure software
quality goals are met.
Test Execution
Test Cycle
closure
Testing vs Debugging
Testing VS Debugging
Executing test can show failures Is the development activity that
that are caused by defects in SW finds,analyzed and fixes such
defects
Failures life cycle
A person can make an Fault/bug in SW code or When code executing
mistake in some other related
works products
Error Leads to Defects Leads to Failures
Test Levels
Test Levels
4 Acceptance Test
System Test. 3
1
C
C
C C 6
2 C C 5
3 4
C
2 Integration Test
1 C
C 6
2 C
C 5 2
3 C
4
Unit Test 1
C1
C6
C2
C5
C3
C4
Types of Test
Types of Test
Functional Test White-box
Testing performed to evaluate if a Testing based on an analysis of the internal
component or system satisfies functional structure of the component or system.
requirements.
Non Functional Test Change-Related
Testing the attributes of a component or When the system undergoes changes due
system that do not relate to functionality, to defect fixes, two types of tests are
e.g., reliability, efficiency, usability, needed; one to verify the change has not
maintainability and portability. broken the existing, working code and the
second to ensure the defect has been
fixed. These tests are called Regression
and Confirmation testing.
Unit Test Features
What is SW Unit ?
A unit is the smallest testable part of any software. It usually has one or a few
inputs and usually a single output. In procedural programming, a unit may be an
individual program, function, procedure, etc.
What is the Unit Test ?
Is a level of software testing where individual units / components of a software are
tested. The purpose is to validate that each unit of the software performs as
designed.
What is the Unit Test Methods ?
Unit Testing is usually performed by using the White Box Testing method and is
normally automated.
When is it performed?
Unit Testing is the first level of software testing and is performed prior to
Integration Testing. Though unit testing is normally performed after coding,
sometimes, specially in test-driven development (TDD), automated unit tests are
written prior to coding.
Who performs it?
It is normally performed by software developers themselves or their peers. In rare
cases, it may also be performed by independent software testers but they will need to
have access to the code and have an understanding of the architecture and design.
Unit Testing - Advantages:
● Reduces Defects in the Newly developed features or reduces bugs when
changing the existing functionality.
● Reduces Cost of Testing as defects are captured in very early phase.
● Improves design and allows better refactoring of code.
● Unit Tests, when integrated with build gives the quality of the build as well.
Test Utility Code
Unit Testing Techniques:
● Software testing techniques are the ways employed to test the application under
test against the functional or non-functional requirements gathered from
business.
● Each testing technique helps to find a specific type of defect. For example,
Techniques which may find structural defects might not be able to find the
defects against the end-to-end business flow.
Unit Testing Techniques:
Structure Based Techniques Specification Based Techniques
White box techniques :are focused on how It basically means creating and executing
the code structure works and test tests based on functional or non-functional
accordingly. specifications from the business.
● Statement coverage ● Equivalence partitioning
● Decision coverage ● Boundary Value Analysis (BVA)
● Conditional/Multiple condition ● Use case-based Testing:
coverage:
Structure Based Techniques
Statement Coverage Decision Coverage Conditional/Multiple condition
Number of decision outcomes exercised
coverage:
Number of Statements of code exercised
Total number of statements Total number of Decisions It has the aim to identify that each outcome of
every logical condition in a program has been
exercised.
If a code segment has 10 lines and the test For Example, If a code segment has 4 decisions
designed by you covers only 5 of them then we (If conditions) and your test executes just 1,
can say that statement coverage given by the then decision coverage is 25%
test is 50%.
Equivalence partitioning
● Partition the input range of data
into valid and non-valid sections
(equivalent)
● Select to test with any value in a
given partition assuming that all
values in the partition will behave
the same.
Equivalence partitioning examples
Equivalence partitioning
Students Scores in an exames let
Invalid Valid Invalid
assume Valid Scores between 0 and
>0 0<= and <= 100 > 100
100 and other than that is invalid
-10 50 150
Car speed identification system :
Equivalence partitioning
● Valid range for valid car speed is
Invalid Low Normal High Invalid
from 0 to 220km/h . Speed speed Speed
● low speed if car speed is below 0 <= → 40 → 120 < →
>0 > 220
40km/h < 40 120 >= 220
● high speed is above 120
● otherwise will be normal speed -10 20 50 200 300
Boundary Value Analysis (BVA)
● Test cases are designed using
boundary values.
● BVA is based on the single fault
assumption, which states that the
bugs are most commonly
concentrate at the boundary.
Boundary Value Analysis examples
BVA
Students scores in an exames let Invalid Valid Invalid
assume Valid scores between 0 and
>0 0<= and <= 100 > 100
100 and other than that is invalid
→ -1 → -1 → 99 → 99
→0 →0 →100 →100
→1 →1 → 101 → 101
Car speed identification system :
BVA
● Valid range for valid car speed is
Low Speed Normal High Speed Invalid
Invalid
from 0 to 220km/h . speed
● low speed if car speed is below >0 0 <= → < 40 40 → 120 120 < → >= 220 > 220
40km/h
● high speed is above 120 → -1 → -1 → 39 →39 →119 →119 →219 → 219
→0 → 0 → 40 →40 → 120 →120→220 → 220
● otherwise will be normal speed →1 → 1 → 41 → 41 →121 →121→221 → 221
Use case-based Testing
● Identify test cases that execute
the system as a whole- like an
actual user (Actor), transaction
by transaction
Use Case testing Examples
Use cases are a sequence of steps that
describe the interaction between the
Actor and the system. They are
always defined in the language of the
Actor, not the system. This testing is
most effective in identifying the
integration defects. Use case also
defines any preconditions and
postconditions of the process flow.
ATM machine example can be tested
via use case:
Test Techniques
Exercises
Notes
In each exercise please identify the followings:
1. Used Techniques
2. Reasons
3. Test cases
Ex 1
Write test ideas for this Scenario: You are at the grocery store checkout counter.
You have bought five items (x, y, z, a, and b). You make payment and move to the
EXIT door.
Example Test ideas as a hint:
If the checkout counter is humanless, scan all the five items, scan your card and make payment.
The scanners should scan proper relevant information.
Ex2 :
The text box accepts numeric values in the range of 18 to 25 (18 and 25 are also
part of the class). So this class becomes our valid class.
Ex 3:
One of the fields on a form contains a text box that accepts alphanumeric values.
Identify the Valid Equivalence class.
a) BOOK
b) Book
c) Boo01k
d) Book
Ex 4:
The Switch is switched off once the temperature falls below 18 and then it is turned
on when the temperature is more than 21.
Ex5
A program validates numeric fields as follows: values less than 10 are rejected,
values between 10 and 21 are accepted, values greater than or equal to 22 are
rejected.
Structure Inspection
and Test-Specific
identity
Introduction To BDD
Behavior-Driven Development (BDD)
● A collaborative approach to development in which the team is focusing on
delivering expected behavior of a component or system for the customer, which
forms the basis for testing.
ISTQB :Advanced Agile Technical Tester - 2019
● BDD is designed to test an application’s behavior from the end user’s
standpoint
Cucumber
How is testing using BDD ?
Behavior-driven development involves a developer, test engineer and a product
manager (and potentially other stakeholders). The group meets to come up with
concrete examples of acceptance criteria in a user story. These examples are
described using a domain-specific language,
Examples for BDD frameworks for testing
JavaScript Code
Jasmine Mocha
Writing Unit Tests
using Mocha
Writing Unit Tests
using Jasmine
● Jasmine is a behavior-driven
JavaScript unit testing
framework
● It aims to run on any
JavaScript-enabled platform,
to not intrude on the
application nor the IDE, and
to have easy-to-read syntax.
First Test
describe(“Math module Suite”, function(){
it(“should return the exponent”, function(){
expect(Math.pow(2,3)).toBe(8)
});
});
Test structure in Jasmine
Test Suite
Test Case
Expectations
Test Suite
A test suite is a collection of test cases, test suites, or both. It is used to aggregate
tests that should be executed together.
describe(suite_title, fn)
describe("Math module Suite", function(){
it("should return the exponent", function(){
expect(Math.pow(2,3)).toBe(8)
});
describe("Constants Suite", function(){
// Test Cases
});
});
Test Case
A test case is the individual unit of testing. It checks for a specific response to a
particular set of inputs.
it(spec_title, fn)
describe("Math module Suite", function(){
it("should return the exponent", function(){
expect(Math.pow(2,3)).toBe(8)
expect(Math.pow(2,4)).toBe(16)
});
});
Expectations
Expectations are built with the function expect which takes a value, called the
actual. It is chained with a Matcher function, which takes the expected value.
expect( actual_value ).matcher_fn( expected_value )
describe("Math module Suite", function(){
it("should return the exponent", function(){
expect(Math.pow(2,3)).toBe(8)
});
});
Matchers
Matchers:Matching
describe("Math module Suite", function(){
it("should return the exponent", function(){
Var output = Math.pow(2,3)
expect(output).toBe(8) // === Matching
expect(Math.pow(2,4)).toEqual(16) // == Matching
});
});
Matchers:Undefined & Null
var x, y=2, z=null
describe("Math module Suite", function(){
it("should return the exponent", function(){
expect(y).toBeDefined() // === Matching against defined
expect(x).not.toBeDefined() // === Matching against undefined
expect(x).toBeUndefined() // === Matching against undefined
expect(z).toBeNull() // === Matching against null
});
});
Matchers:Regular Expressions
describe("Regular Expressions Suite", function(){
it("Should return if string matched with string", function(){
expect("01007882343").toMatch(/[0-9]{11}/) // Matching regex
});
});
Matchers:True & False
describe("Checking Regular expressions Suite", function(){
it("Should return True or false", function(){
expect("Ahmed").toBeTruthy // Matching Truthy Values
expect(0).toBeFalsy // Matching Falsy Values
expect(2 == "2").toBeTruthy // Matching Falsy Values
});
});
Matchers:In collections
describe("Checking Regular expressions Suite", function(){
it("Should return True or false", function(){
expect("Ahmed").toContain ("h")
expect([1,"ahmed",True].toContain ("True")
});
});
Skip
Skip
We can skip any test case or test suite by prepend it definition by x
xdescribe(suite_title, fn)
xit(spec_title, fn)
Setup &
Teardown
Setup & Teardown
To help a test suite DRY up any duplicated setup and teardown code
● beforeEach(fn) # It runs before every spec
● afterEach(fn) # It runs before every spec
● beforeAll(fn) # It runs at the beginning of test
● afterAll(fn) # It runs at the end of test
Jasmine vs Mocha
Features Jasmine Mocha
APIs:
● Test suite → describe blocks → describe blocks
● Test case → Spec it function → Spec it function
● Expectations → Build-in assertion library → No build-in assertion library, instead
use external library like : Chai, should.js,
expect.js, and better-assert
Test doubles come in the form of Mocha does not come with a test double
spies library.
Doubles
Instead, you will need to load in Sinon
into your test harness.
Jasmine vs Mocha
Features Jasmine Mocha
Asynchronous Testing Asynchronous testing can be a bit of Asynchronous testing is very simple
a headache
Jasmine does not is a fake server Sinon supports features
Fake Server
Jasmine does not have a command Mocha comes with a command line
line utility to run tests. utility that you can use to run tests
Running Tests
But Karma could use instead
mocha tests --recursive --watch
Jasmine vs Mocha
Pros ● Pros
●
● Simple setup for node through ● Clear, Simple API
jasmine-node ● Headless running out of the box
● Headless running out of the box ● Allows use of any assertion library
● Nice fluent syntax for assertions that will throw exceptions on failure,
built-in such as Chai
● Supported by many CI servers ● Supported by some CI servers
● Descriptive syntax for BDD ● Has aliases for functions to be more
paradigm(which is a big plus for us) BDD-oriented or TDD-oriented
● Highly extensible
● Asynchronous testing is very simple
Jasmine vs Mocha
Cons Cons
● Asynchronous testing can be a bit of ● Tests cannot run in random order.
a headache ● Allows use of any assertion
● Expects a specific suffix to all test library(Both pro and con)
files (*spec.js by default) ● No auto mocking or snapshot testing
Jasmine
Exercises
Create Tests using Jasmine framework
Using the test techniques => write test cases to test the following function with
respect to to following rules :
● Mentioned used techniques
● Create 2 Test suites
● In each test suite create at least 2 test cases
● Use the following methods
○ before All
○ afterAll
Ex #1 :Test function to evaluate Car speed
Req # 1 : Input to the function is the car speed and output shall be speed level
Req# 2 : Function shall calculate output to be :
● If Speed < 0 Level shall be Invalid
● If 0 <= Speed < 40 Level shall be Low
● If 40 <= Speed < 120 Level shall be Normal
● If 120 <= Speed < 200 Level shall be High
● If 200 <= Speed < 220 Level shall be V.High
● If 220 < Speed Level shall be Invalid
Ex #2 :Test function to evaluate students Speeds
Req # 1 : Input to the function is student Speed and output student Level
Req# 2 : Function shall calculate output to be :
● If Speed < 0 Level shall be Invalid
● If 0 < = Speed < 50 Level shall be Failed
● If 50 <= Speed < 65 Level shall be Passed
● If 65 <= Speed < 75 Level shall be Good
● If 75 <= Speed < 85 Level shall be V.Good
● If 85 <= Speed < 100 Level shall be Excellent
● If 100 <= Speed Level shall be Invalid
Introduction To TDD
Introduction To TDD Write code
Traditionally, the software
Add a test
development workflow is mostly a
loop of the following steps:
Run the test
Fix the bug
[Pass
Development
[Fail]
continues]
Run the test
Introduction To TDD
Test-driven development changes
this workflow by writing
automated tests, and by writing
tests before we write the code
BDD vs TDD
Features BDD TDD
● BDD is designed to test an ● TDD is focused on testing smaller
application’s behavior from the pieces of functionality in isolation
end user’s standpoint ● The TDD test asserts the result of a
What You’re Testing ?
● The BDD test is only specific method
concerned about the result of
the higher level scenario.
BDD involves product managers, TDD can be done by a solo developer
developers, and test engineers who without any external input from product
How You’re Testing ?
collaborate to come up with concrete managers or stakeholders.
examples of desirable functionality
BDD vs TDD
BDD TDD
Behavior-driven development represents an Test-driven development has become the default
evolution beyond TDD, where business goals can be approach for Agile software development over the
better communicated to developers. past several years.
By bridging the gap between business and technical The approach minimizes bugs reaching
teams, BDD helps reduce any confusion about production and ensures that software can be
acceptance criteria, identify potential problems with continuously released without issue.
user stories early, and ensure that the application
functions as-expected for end users.
TDD Exercises
TDD Exercises
Using TDD approach develop the following functions :
TDD EX