Free tutorials & notes in Hindi & English · Clean code examples 🧰 Free PDF & Image Tools →
🛡️ Days 23–27 – Professional JavaScript  ·  Day 27

Day 27: Testing & Interview Preparation

⏱ 120 min📶 Pro🎯 100% self-study
Day 27 / 30

✅ Today you will learn

  • Why automated tests save time (and jobs)
  • Unit tests with node:test and assert
  • Test edge cases and fix a bug test-first
  • Jest/Vitest for units, Playwright for the browser
  • The top JavaScript interview questions and coding tasks

🏢 In the real world

During the Diwali rush a developer changed the delivery-fee rule and accidentally made every order above ₹1,500 cost ₹60 extra. Nobody noticed for two days. A 10-line test would have caught it in one second before the change went live. Companies now expect freshers to write basic tests – and to answer the classic JavaScript questions confidently.

Manual checking vs automated tests

Manual testing

  • Click through the site after every change
  • Slow, boring, easy to skip
  • Edge cases forgotten
  • Bugs reach customers

Automated tests

  • Code that checks code
  • Runs hundreds of checks in seconds
  • Edge cases written once, checked forever
  • Bugs caught before deploy (CI)

Your first tests with node:test

JavaScript
const { test } = require('node:test');
const assert = require('node:assert/strict');

// --- code under test ---
const FREE_FROM = 1500, FEE = 60;
function deliveryFee(subtotal) {
  if (subtotal <= 0) return 0;
  return subtotal >= FREE_FROM ? 0 : FEE;
}
function orderTotal(items, coupon) {
  const subtotal = items.reduce((s, i) => s + i.price * i.qty, 0);
  const discounted = coupon === 'SWEET10' ? Math.round(subtotal * 0.9) : subtotal;
  return discounted + deliveryFee(discounted);
}

// --- tests ---
test('delivery is free from ₹1,500', () => {
  assert.equal(deliveryFee(1500), 0);
  assert.equal(deliveryFee(2400), 0);
});
test('₹60 delivery below ₹1,500', () => {
  assert.equal(deliveryFee(1499), 60);
});
test('empty cart has no delivery fee', () => {
  assert.equal(deliveryFee(0), 0);
});
test('coupon is applied before the delivery rule', () => {
  // 1600 − 10% = 1440 → below 1500 → +60
  assert.equal(orderTotal([{ price: 800, qty: 2 }], 'SWEET10'), 1500);
});
✔ delivery is free from ₹1,500 (1.006543ms) ✔ ₹60 delivery below ₹1,500 (0.153124ms) ✔ empty cart has no delivery fee (0.115609ms) ✔ coupon is applied before the delivery rule (0.1732ms) ℹ tests 4 ℹ suites 0 ℹ pass 4 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 9.282598
AssertionChecks
assert.equal(a, b)a === b (strict module)
assert.deepEqual(obj1, obj2)Same structure and values
assert.ok(value)Truthy
assert.throws(() => fn(), /message/)Throws the expected error
await assert.rejects(promise)An async function fails as expected
💡 What to test first

Pure functions with money, dates and rules: totals, discounts, GST, validation. Test the boundaries – exactly 1500, 1499, 0, negative, empty, very large – that is where bugs live.

Fixing a bug test-first

JavaScript
const { test } = require('node:test');
const assert = require('node:assert/strict');

// Bug report: "Mobile +91 98290 12345 is rejected on the order form"
function isValidMobile(input) {
  const digits = input.replace(/\D/g, '');
  const ten = digits.length === 12 && digits.startsWith('91') ? digits.slice(2)
            : digits.length === 11 && digits.startsWith('0') ? digits.slice(1)
            : digits;                                     // ← the fix: accept 91/0 prefixes
  return /^[6-9]\d{9}$/.test(ten);
}

test('accepts common Indian formats (the bug report)', () => {
  for (const ok of ['9829012345', '+91 98290 12345', '098290-12345', '91-9829012345']) {
    assert.ok(isValidMobile(ok), ok);
  }
});
test('still rejects invalid numbers', () => {
  for (const bad of ['5829012345', '98290', '+1 202 555 0101', '']) {
    assert.equal(isValidMobile(bad), false, bad);
  }
});
✔ accepts common Indian formats (the bug report) (1.102807ms) ✔ still rejects invalid numbers (0.223457ms) ℹ tests 2 ℹ suites 0 ℹ pass 2 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 12.937961
  1. 1Write a test that reproduces the bug – it fails (red)
  2. 2Make the smallest change that fixes it – test passes (green)
  3. 3Clean up the code; tests still pass (refactor)
  4. 4Keep the test forever so the bug can never come back
Red → green → refactor

Testing tools you will meet at work

ToolTypeExample use
node:testBuilt-in unit testsUtilities, Node APIs
Vitest / JestUnit + component testsFunctions, React components (with Testing Library)
Playwright / CypressEnd-to-end in real browsers“Add to cart → checkout → see order number”
Lighthouse CIPerformance & accessibility budgetsFail the build if LCP gets worse
GitHub ActionsContinuous integrationRun all tests on every push / pull request
JavaScript – a Playwright end-to-end test (tests/order.spec.js)
import { test, expect } from '@playwright/test';

test('customer can order kaju katli', async ({ page }) => {
  await page.goto('http://localhost:5173/');
  await page.getByRole('button', { name: /add kaju katli/i }).click();
  await page.getByRole('link', { name: /cart/i }).click();
  await page.getByLabel('Name').fill('Aarti Gupta');
  await page.getByLabel('Mobile').fill('9829012345');
  await page.getByRole('button', { name: 'Place order' }).click();
  await expect(page.getByText(/order SS\d+/i)).toBeVisible();
});

Top interview questions – quick answers

Concept questions (tap to reveal)

Q1. What are the data types in JavaScript?

Primitives: string, number, bigint, boolean, undefined, null, symbol. Everything else is an object (arrays, functions, dates…).

Q2. Difference between == and ===?

=== compares value and type; == converts types first. Use ===.

Q3. What is hoisting?

Declarations are registered before code runs: functions fully, var as undefined, let/const in the temporal dead zone.

Q4. What is a closure?

A function that remembers variables from where it was created – used for private state, factories, debounce.

Q5. Explain the event loop.

One call stack; async callbacks wait in queues; microtasks (promises) run before tasks (timers, events) when the stack is empty.

Q6. map vs forEach?

map returns a new transformed array; forEach returns undefined and is for side effects.

Q7. What is event delegation?

One listener on a parent handles events from many (also future) children via bubbling and e.target.closest().

Q8. How does this work?

Determined by the call: obj.method() → obj; plain call → undefined (strict); new → instance; bind/call/apply → given value; arrows use outer this.

Q9. Promise.all vs allSettled?

all fails fast on the first rejection; allSettled waits for all and reports each result.

Q10. localStorage vs cookies?

localStorage: ~5 MB, JS-readable, not sent to server. Cookies: small, sent with requests, can be HttpOnly – use for sessions.

Q11. Debounce vs throttle?

Debounce runs after calls stop (search box); throttle runs at most once per interval (scroll).

Q12. How do you prevent XSS?

Render user data as text, escape/sanitise HTML, validate URLs, avoid eval, use CSP and HttpOnly cookies.

Classic coding questions

JavaScript
// 1. Reverse words, 2. palindrome, 3. frequency count, 4. flatten, 5. remove duplicates, 6. chunk, 7. deep equal
const reverseWords = s => s.trim().split(/\s+/).reverse().join(' ');
const isPalindrome = s => { const c = s.toLowerCase().replace(/[^a-z0-9]/g, ''); return c === [...c].reverse().join(''); };
const frequency = arr => arr.reduce((m, x) => ((m[x] = (m[x] || 0) + 1), m), {});
const flatten = arr => arr.reduce((out, x) => out.concat(Array.isArray(x) ? flatten(x) : x), []);
const unique = arr => [...new Set(arr)];
const chunk = (arr, n) => Array.from({ length: Math.ceil(arr.length / n) }, (_, i) => arr.slice(i * n, i * n + n));
const deepEqual = (a, b) => {
  if (a === b) return true;
  if (typeof a !== 'object' || typeof b !== 'object' || !a || !b) return false;
  const ka = Object.keys(a), kb = Object.keys(b);
  return ka.length === kb.length && ka.every(k => deepEqual(a[k], b[k]));
};

console.log(reverseWords('  fresh   ghewar daily '));
console.log(isPalindrome('Madam, in Eden I’m Adam'), isPalindrome('Rasmalai'));
console.log(frequency(['kaju', 'ladoo', 'kaju', 'ghewar', 'kaju']));
console.log(flatten([1, [2, [3, [4]], 5]]));
console.log(unique([302001, 302003, 302001, 302012]));
console.log(chunk(['A101', 'A102', 'A103', 'A104', 'A105'], 2));
console.log(deepEqual({ id: 1, tags: ['veg'] }, { id: 1, tags: ['veg'] }), deepEqual({ a: 1 }, { a: '1' }));
daily ghewar fresh true false { kaju: 3, ladoo: 1, ghewar: 1 } [ 1, 2, 3, 4, 5 ] [ 302001, 302003, 302012 ] [ [ 'A101', 'A102' ], [ 'A103', 'A104' ], [ 'A105' ] ] true false
PrepareHow
Explain your projectsSTAR format: situation, task, action, measurable result
Live codingThink aloud, start simple, test edge cases, then optimise
Machine-coding roundBuild a to-do / search with debounce / modal in 60–90 min – exactly what this course practised
FundamentalsClosures, this, event loop, promises, array methods, DOM, CSS layout
PortfolioLive links: HTML portfolio, CSS redesign, JS to-do, quiz and the shop project

🏅 Job skills unlocked today

✔ Write unit tests with node:test and assert✔ Test boundaries and fix bugs test-first✔ Know where Vitest/Jest and Playwright fit✔ Answer the core JavaScript interview questions and coding tasks

Practice tasks

🏋️ Practice – do it yourself

Task 1: Write tests for a function grade(marks) (from Day 3) covering 100, 90, 89, 33, 32, 0 and a negative number that should throw.
Show solution
JavaScript
const { test } = require('node:test');
const assert = require('node:assert/strict');
function grade(m) {
  if (m < 0 || m > 100) throw new RangeError('marks must be 0–100');
  if (m >= 90) return 'A+';
  if (m >= 75) return 'A';
  if (m >= 60) return 'B';
  if (m >= 33) return 'C';
  return 'Fail';
}
test('grade boundaries', () => {
  assert.equal(grade(100), 'A+');
  assert.equal(grade(90), 'A+');
  assert.equal(grade(89), 'A');
  assert.equal(grade(33), 'C');
  assert.equal(grade(32), 'Fail');
  assert.equal(grade(0), 'Fail');
});
test('invalid marks throw', () => {
  assert.throws(() => grade(-5), RangeError);
});
✔ grade boundaries (1.143376ms) ✔ invalid marks throw (0.447816ms) ℹ tests 2 ℹ suites 0 ℹ pass 2 ℹ fail 0 ℹ cancelled 0 ℹ skipped 0 ℹ todo 0 ℹ duration_ms 9.663937
Task 2: Solve: given an array of order totals, return the second-highest unique total (or null).
Show solution
JavaScript
function secondHighest(totals) {
  const sorted = [...new Set(totals)].sort((a, b) => b - a);
  return sorted.length > 1 ? sorted[1] : null;
}
console.log(secondHighest([1800, 650, 2400, 2400, 900]));
console.log(secondHighest([500, 500]));
1800 null
Task 3: Machine-coding practice (60 min): build an accordion FAQ that loads questions from JSON, opens one at a time and is keyboard accessible.

Quick quiz

🧠 Quick Quiz – test yourself

1. A unit test checks…
E2E checks flows.
2. Best values to test for “free delivery from ₹1,500”?
Boundaries.
3. Red → green → refactor describes…
TDD cycle.
4. Tool for clicking through the real site automatically:
End-to-end testing.
5. [...new Set(arr)] …
Set keeps unique values.

Interview corner

💼 Interview Corner

How do you decide what to test?

Test business-critical logic and boundaries first (money, validation, permissions), then main user flows end-to-end; aim for confidence, not 100% coverage; add a regression test for every fixed bug; keep tests fast and independent.

Tell me about a bug you fixed.

Use STAR: the symptom and impact, how you reproduced it, how you found the cause (DevTools, logs), the fix, the test you added and what you changed to prevent similar bugs.

Summary

  • Automated tests catch bugs in seconds and protect against regressions.
  • node:test + assert for units; test boundaries; fix bugs test-first.
  • Vitest/Jest for units and components, Playwright for real user flows, CI to run them.
  • Master the core questions and classic coding tasks; explain projects with STAR.
➡️ Next

Day 28 – Mini project: a timed quiz app with scoring, review and high scores.

Frequently Asked Questions

Do freshers really need testing skills?
More and more job descriptions mention Jest/Vitest. Even basic unit tests on your portfolio projects make you stand out.
How do I practise interviews?
Explain each Day’s interview corner aloud in English and Hindi, time yourself on machine-coding tasks and review your solutions the next day.
← JavaScript (30 Days)
🔗

Share this topic with a friend

यह topic किसी दोस्त को भेजें

Found it useful? Send it to a classmate learning the same thing.

अच्छा लगा? जो दोस्त यही सीख रहा है, उसे भेज दीजिए।

Next topicDay 28: Mini Project: Quiz App with Timer Your progress: 27 / 30 (90%) · Lesson 28 / 30 Continue →

How was this lesson?

Your feedback helps us make the content better.

Write a review or suggestion (optional)

After approval, your name and city may appear publicly with your review. Please do not write your email or phone number.

▶ CodingEasily on YouTube

Learn with video lessons in easy Hindi

Featured video: RDBMS Part 3 – Class XI Commerce IT

▶ Subscribe – it’s free