Building Your Learning Module...
Getting things ready for you!
Find videos you like?
Save to resource drawer for future reference!
Unit testing is the practice of testing individual units (functions, methods, components) of your code in isolation. Each test verifies that a specific piece of code works as expected.
Tests one function or method at a time
No external dependencies or side effects
Runs quickly - thousands in seconds
// Function to test
function add(a, b) {
return a + b;
}
// Unit test
function testAdd() {
const result = add(2, 3);
if (result === 5) {
console.log('✓ Test passed: add(2, 3) returns 5');
} else {
console.error('✗ Test failed: expected 5, got ' + result);
}
}
testAdd(); // Run the testSet up test data and conditions
// Arrange const x = 10; const y = 5;
Execute the function being tested
// Act const result = add(x, y);
Verify the result is correct
// Assert expect(result).toBe(15);
function multiply(a, b) {
return a * b;
}
function testMultiply() {
// Arrange - Set up test data
const num1 = 4;
const num2 = 5;
const expected = 20;
// Act - Execute the function
const actual = multiply(num1, num2);
// Assert - Check the result
if (actual === expected) {
console.log('✓ Test passed');
} else {
console.error(`✗ Test failed: expected ${expected}, got ${actual}`);
}
}
testMultiply();// Pure function - easy to test
function calculateDiscount(price, percentage) {
if (price < 0 || percentage < 0 || percentage > 100) {
throw new Error('Invalid input');
}
return price * (percentage / 100);
}
// Tests for pure function
function testCalculateDiscount() {
// Test normal case
console.assert(
calculateDiscount(100, 10) === 10,
'Should calculate 10% of 100'
);
// Test edge case - zero
console.assert(
calculateDiscount(100, 0) === 0,
'Should handle 0% discount'
);
// Test edge case - 100%
console.assert(
calculateDiscount(100, 100) === 100,
'Should handle 100% discount'
);
// Test error handling
try {
calculateDiscount(-50, 10);
console.error('Should throw error for negative price');
} catch (e) {
console.log('✓ Correctly throws error for negative price');
}
}
testCalculateDiscount();function getFirstElement(array) {
if (!Array.isArray(array)) {
throw new TypeError('Input must be an array');
}
return array[0];
}
// Comprehensive tests
function testGetFirstElement() {
// Normal case
console.assert(
getFirstElement([1, 2, 3]) === 1,
'Should return first element'
);
// Edge case: empty array
console.assert(
getFirstElement([]) === undefined,
'Should return undefined for empty array'
);
// Edge case: single element
console.assert(
getFirstElement([42]) === 42,
'Should work with single element'
);
// Edge case: null/undefined in array
console.assert(
getFirstElement([null, 1, 2]) === null,
'Should return null if first element is null'
);
// Error case: not an array
try {
getFirstElement('not array');
console.error('Should throw TypeError');
} catch (e) {
console.log('✓ Correctly throws TypeError for non-array');
}
}
testGetFirstElement();class Calculator {
constructor() {
this.result = 0;
}
add(n) {
this.result += n;
return this;
}
subtract(n) {
this.result -= n;
return this;
}
getResult() {
return this.result;
}
reset() {
this.result = 0;
return this;
}
}
// Tests
function testCalculator() {
// Test addition
const calc1 = new Calculator();
calc1.add(5);
console.assert(
calc1.getResult() === 5,
'Should add correctly'
);
// Test chaining
const calc2 = new Calculator();
const result = calc2.add(10).subtract(3).getResult();
console.assert(
result === 7,
'Should support method chaining'
);
// Test reset
const calc3 = new Calculator();
calc3.add(100).reset();
console.assert(
calc3.getResult() === 0,
'Should reset to zero'
);
console.log('✓ All Calculator tests passed');
}
testCalculator();% of lines executed
% of if/else paths tested
% of functions called
% of statements run
function getGrade(score) {
if (score >= 90) return 'A';
if (score >= 80) return 'B';
if (score >= 70) return 'C';
if (score >= 60) return 'D';
return 'F';
}
// Test all branches for 100% coverage
function testGetGrade() {
// Test each branch
console.assert(getGrade(95) === 'A', 'Should return A for 90+');
console.assert(getGrade(85) === 'B', 'Should return B for 80-89');
console.assert(getGrade(75) === 'C', 'Should return C for 70-79');
console.assert(getGrade(65) === 'D', 'Should return D for 60-69');
console.assert(getGrade(50) === 'F', 'Should return F for <60');
// Test boundaries
console.assert(getGrade(90) === 'A', 'Should return A for exactly 90');
console.assert(getGrade(89) === 'B', 'Should return B for 89');
console.assert(getGrade(60) === 'D', 'Should return D for exactly 60');
console.assert(getGrade(59) === 'F', 'Should return F for 59');
console.log('✓ All grade tests passed - 100% branch coverage');
}
testGetGrade();Each test should focus on one function
No dependencies on external systems
Arrange → Act → Assert
Standard test structure
Empty arrays, null, undefined, 0
Boundaries and error conditions
Test all critical paths
100% coverage isn't always necessary