HackIndia Logo
HackathonsNewsSkillsGrowth
HackIndia LogoContact: +91 9910125804

General

  • Companies
  • Colleges
  • Board of Advisors
  • Brand Ambassadors
  • FAQ
  • Contact
  • Report a Bug

Hackathons

  • Upcoming Hackathons
  • Judges
  • Mentors
  • Partners
  • Participating Colleges
  • Testimonials

Resources

  • About Us
  • Branding
  • Latest News
  • Growth
  • Skills
  • Builders
  • Ecosystem
  • Forum
  • Ideas
  • Prompt Optimizer
  • Games

© 2026 HackIndia. All rights reserved.

Privacy PolicyTerms of ServiceCode of ConductSitemap

Build 2.139 · 05 Nov 2026, 10:27 UTC

    HackIndia
    HackathonsNewsInternshipsSkillsGrowthPro Perks
    ← Test code recruiters can trust

    All the reading

    Testing

    7 lessons, about 33 minutes. The check's questions come from these.

    Contents
    Picking test targets
    1. 1. Pick what is worth testing
    Writing unit tests
    1. 2. Write your first unit test
    2. 3. Choose unit or integration
    Test doubles and APIs
    1. 4. Use test doubles safely
    2. 5. Test an API endpoint
    CI and repo proof
    1. 6. Run tests on every push
    2. 7. Ship a tested public repo

    Picking test targets

    1. Pick what is worth testing

    4 min

    In 30 seconds
    • Pick tests that prove your app’s risky behaviour, not every line of code.
    • Turn features into test ideas using inputs, outputs, errors, and rules.
    • Create a small test plan you can later turn into unit and API tests.
    Key point

    Test behaviour

    A useful test proves something important your app does for a user. Do not start by asking “which files need tests?” Start by asking “what must not break?”

    Recruiters trust tests when they protect real behaviour: login rules, price totals, form validation, permissions, API responses, and data changes.

    What counts as worth testing

    Your hackathon project does not need 100 tests. It needs a few tests that show you understand risk.

    Pick things that are core to the app, easy to break while coding, or painful for users if wrong. A UPI split app must test amount splitting. A campus event app must test registration limits.

    Your to-do

    Find test ideas

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    Example

    Tiny test plan

    Before writing test code, write a plain test plan in your repo. This keeps you focused when you add Jest, Pytest, Vitest, or any other tool later.

    Writing unit tests

    2. Write your first unit test

    5 min

    In 30 seconds
    • Write a unit test for one small function with one clear job.
    • Use arrange, act, assert so your test is easy to read.
    • Run the test locally and commit it with the code it protects.

    What you test here

    A unit test checks one small piece of code by itself. Usually this is a function that takes input and returns output.

    For your hackathon repo, this is the easiest proof to add first. Pick business logic, not a button colour or a database call.

    Key point

    One idea

    A good unit test proves one expected behaviour with clear inputs and a clear result. If it needs a server, a database, or a logged-in user, it is probably not a unit test.

    Your to-do

    Pick a function

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 4 done

    Test doubles and APIs

    4. Use test doubles safely

    5 min

    In 30 seconds
    • Use fake dependencies without hiding real bugs.
    • Stub slow or paid services like email, UPI, maps, and AI APIs.
    • Keep one real integration test for the boundary you faked.
    Key point

    One idea

    Use a test double only when the real dependency makes the test slow, flaky, costly, or hard to control.

    Do not fake the code you are trying to prove. Fake the outside thing your code talks to.

    What doubles replace

    A test double is a stand-in used during a test. It can replace an email sender, payment gateway, database, clock, file system, map service, or AI API call.

    In hackathon projects, this often means you do not call Razorpay, Firebase, Google Maps, SendGrid, or an LLM API in a unit test. You replace that call with a small fake result.

    Common mistake

    CI and repo proof

    6. Run tests on every push

    5 min

    In 30 seconds
    • Add GitHub Actions to run your test command on every push.
    • Make CI fail when tests fail, so recruiters can trust the green check.
    • Show passing automated tests in your public hackathon repo.
    Key point

    One proof signal

    A test suite is stronger when it runs without you clicking anything. Put it in CI so every push to GitHub runs the same test command.

    Recruiters and mentors can then see a public commit, a workflow run, and a green check. That is better proof than saying “tests pass on my laptop.”

    What CI does

    CI means continuous integration. For this track, it only needs to do one job: install your project and run tests whenever code is pushed.

    GitHub Actions is free enough for most student public repos. It reads a workflow file from your repo and runs the commands on a clean machine.

    Your to-do

    Before you add CI

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    10 questions, 7 to pass.

    Sign in to take the test
    Feature: expense split
    
    User action: Create a group expense
    
    Worth testing:
    1. Happy path
       Given amount = 900 and members = 3
       Expect each member share = 300
    
    2. Rounding rule
       Given amount = 100 and members = 3
       Expect total assigned shares still equals 100
    
    3. Invalid input
       Given amount = -50
       Expect the app rejects the expense
    
    Not testing now:
    - Button colour
    - Exact wording of heading
    - Animation timing
    Common mistake

    Do not test everything

    Beginners often test easy things because they look quick: whether a heading renders, whether a function was called, or whether a variable exists.

    Those tests may pass while the app is broken. Prefer testing the result the user or API gets.

    Tip

    Use AI carefully

    You can ask ChatGPT, Gemini, or Claude to suggest test cases. Give it your feature, inputs, rules, and edge cases.

    Check the answer. AI often suggests too many tests, tests private implementation, or ignores Indian product rules like rupee rounding, phone number format, or UPI-style flows.

    Prompt:
    I am building a college expense split app.
    Feature: create expense.
    Rules: amount is in rupees, members must be at least 2, shares must add up to the original amount.
    Suggest 6 meaningful test cases.
    Separate happy path, edge cases, and invalid input.
    Do not suggest UI colour or layout tests.
    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    Example

    Example unit test

    Here is a small JavaScript example using Vitest. The function calculates a simple platform fee in rupees.

    The test has three parts: arrange the input, act by calling the function, and assert the expected output.

    // src/calculateFee.js
    export function calculateFee(amount) {
      if (amount <= 0) return 0;
      return Math.ceil(amount * 0.02);
    }
    
    // src/calculateFee.test.js
    import { describe, it, expect } from 'vitest';
    import { calculateFee } from './calculateFee.js';
    
    describe('calculateFee', () => {
      it('returns 2 percent fee rounded up', () => {
        // arrange
        const amount = 101;
    
        // act
        const fee = calculateFee(amount);
    
        // assert
        expect(fee).toBe(3);
      });
    
      it('returns zero for zero or negative amounts', () => {
        expect(calculateFee(0)).toBe(0);
        expect(calculateFee(-50)).toBe(0);
      });
    });
    Your to-do

    Run it locally

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 4 done

    npm install -D vitest
    
    // package.json
    {
      "scripts": {
        "test": "vitest run"
      }
    }
    
    npm test
    Tip

    Name tests plainly

    Write the test name like a sentence: returns zero for negative amounts. A recruiter should understand the behaviour without opening the function.

    If you use AI to draft tests, ask it for cases first, not code first. Then check that every case matches your actual product rules.

    Prompt you can use:
    I have this function. Suggest 5 useful unit test cases. Include normal cases and edge cases. Do not write code yet.
    
    Then paste your function.
    Common mistake

    Common mistake

    Do not test the implementation detail. Test the result the user or app depends on.

    For example, do not test that the function uses Math.ceil. Test that 101 rupees gives a 3 rupee fee. This keeps the test useful even if you rewrite the internals later.

    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 4 done

    git add src/calculateFee.js src/calculateFee.test.js package.json package-lock.json
    git commit -m "Add unit test for fee calculation"

    3. Choose unit or integration

    5 min

    In 30 seconds
    • Decide if a test should be unit or integration before writing it.
    • Use unit tests for logic and integration tests for wiring between parts.
    • Add a small test plan to your repo so recruiters see your choices.
    Key point

    One decision

    A unit test checks one small piece of code in isolation. An integration test checks that two or more parts work together, like route plus database query, or service plus payment client wrapper.

    The point is not to write the most tests. The point is to choose the cheapest test that gives real confidence.

    Use unit when

    Pick a unit test when the behaviour lives inside one function, class, or module. Good examples are price calculation, input validation, sorting, formatting, permission checks, and date logic.

    These tests should be fast and boring. They should not need a server, database, network, browser, or real API key.

    Use integration when

    Pick an integration test when the risk is in the connection between parts. For example, your Express route may call the correct service, but return the wrong status code. Your app may save the right data, but read it back incorrectly.

    Integration tests are slower, but they catch bugs that unit tests cannot. Use fewer of them, focused on important user flows.

    Your to-do

    Choose the level

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    Example

    Same feature, two tests

    Say your hackathon app splits a food bill for friends after a canteen order. The calculation is unit-test material. The HTTP endpoint that accepts the bill and returns the split is integration-test material.

    This example uses JavaScript with Jest and Supertest. The exact framework can change. The choice stays the same.

    // bill.js
    function splitBill(totalRupees, people) {
      if (people <= 0) throw new Error('people must be positive');
      return Math.ceil(totalRupees / people);
    }
    module.exports = { splitBill };
    
    // bill.test.js - unit test
    const { splitBill } = require('./bill');
    
    test('splits a bill and rounds up to the next rupee', () => {
      expect(splitBill(101, 4)).toBe(26);
    });
    
    // app.test.js - integration test
    const request = require('supertest');
    const app = require('./app');
    
    test('POST /split returns per-person amount', async () => {
      const res = await request(app)
        .post('/split')
        .send({ totalRupees: 101, people: 4 });
    
      expect(res.status).toBe(200);
      expect(res.body.perPersonRupees).toBe(26);
    });
    Common mistake

    Common mistake

    Do not turn every test into an integration test because it feels more real. You will get a slow test suite that breaks for setup reasons, not product reasons.

    Also avoid only unit tests. A repo with clean unit tests but no proof that the API works still leaves recruiters guessing.

    Tip

    Use AI carefully

    You can ask an AI tool: "For this feature, suggest unit tests and integration tests separately." Paste the function or route code with no secrets.

    Check its answer. Remove tests that repeat implementation details, depend on exact private function names, or need paid services. Keep tests that match user-visible behaviour.

    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    Common mistake

    Beginners mock every function. Then the test only proves that mocks return what the test wrote inside them.

    If your test mocks your own business logic, it is weak. For example, do not mock calculateTotal() when the purpose is to test checkout pricing.

    Your to-do

    Use safely

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    Example

    Small Node example

    Here the code sends an OTP only after saving it. The test fakes the SMS service because sending a real SMS costs money and can fail for reasons outside your code.

    The fake records what would have been sent. The test still checks real app behaviour.

    // otp.js
    async function sendLoginOtp(phone, store, smsClient) {
      const otp = "123456";
      await store.saveOtp(phone, otp);
      await smsClient.send(phone, `Your OTP is ${otp}`);
      return { ok: true };
    }
    
    module.exports = { sendLoginOtp };
    
    // otp.test.js
    const { sendLoginOtp } = require("./otp");
    
    test("saves OTP and asks SMS client to send it", async () => {
      const saved = [];
      const sent = [];
    
      const fakeStore = {
        saveOtp: async (phone, otp) => saved.push({ phone, otp })
      };
    
      const fakeSmsClient = {
        send: async (phone, message) => sent.push({ phone, message })
      };
    
      const result = await sendLoginOtp("9876543210", fakeStore, fakeSmsClient);
    
      expect(result).toEqual({ ok: true });
      expect(saved).toEqual([{ phone: "9876543210", otp: "123456" }]);
      expect(sent[0].phone).toBe("9876543210");
      expect(sent[0].message).toContain("123456");
    });
    Tip

    AI check

    If you ask ChatGPT, Gemini, or Claude to write tests with mocks, also ask: “What real behaviour does this test prove, and what could still break in production?”

    Check that the answer names the external dependency being faked. If it cannot, the mock is probably hiding too much.

    Common mistake

    Do not fake contracts

    If your fake returns a shape the real service never returns, your test gives false confidence. Keep fake responses copied from real docs, real logs, or a saved response from your app.

    For example, if your payment API returns amount in paise, do not let your fake return rupees. That bug can reach production.

    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    5. Test an API endpoint

    5 min

    In 30 seconds
    • Test an API endpoint by sending a real HTTP request to your app.
    • Check the status code and response body, not only that it runs.
    • Keep the test fast by using a test database or in-memory app setup.
    Key point

    One useful API test

    An API test proves that a route works from request to response. It should send a request, let your route handler run, and check what the client gets back.

    For your HackIndia repo, one good API test is better than five shallow checks. Pick a route that matters to your project, like login, create order, fetch notes, or submit feedback.

    What to check

    Check three things. First, the status code. Second, the response body. Third, the important side effect, if there is one.

    For example, a UPI split app may test POST /expenses. The test should confirm 201, the returned expense amount, and that the expense was saved.

    Your to-do

    Set up the route

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    Example

    Express example

    This example uses Node.js, Express, Jest, and Supertest. The route is small, but the pattern works for bigger apps too.

    Notice that app.js exports the app. It does not call listen. That makes the test fast and avoids port conflicts on your laptop or in CI.

    // app.js
    const express = require('express');
    
    const app = express();
    app.use(express.json());
    
    const expenses = [];
    
    app.post('/expenses', (req, res) => {
      const { title, amount } = req.body;
    
      if (!title || typeof amount !== 'number') {
        return res.status(400).json({ error: 'title and amount are required' });
      }
    
      const expense = { id: expenses.length + 1, title, amount };
      expenses.push(expense);
    
      return res.status(201).json(expense);
    });
    
    module.exports = app;
    
    // server.js
    const app = require('./app');
    app.listen(3000, () => console.log('Server running on port 3000'));
    
    // app.test.js
    const request = require('supertest');
    const app = require('./app');
    
    test('creates an expense', async () => {
      const response = await request(app)
        .post('/expenses')
        .send({ title: 'chai for team', amount: 120 });
    
      expect(response.status).toBe(201);
      expect(response.body).toMatchObject({
        id: 1,
        title: 'chai for team',
        amount: 120
      });
    });
    
    test('rejects an invalid expense', async () => {
      const response = await request(app)
        .post('/expenses')
        .send({ title: 'chai for team' });
    
      expect(response.status).toBe(400);
      expect(response.body.error).toBe('title and amount are required');
    });
    Tip

    Use AI carefully

    You can ask ChatGPT or Gemini to draft API tests from your route file. Paste the route and ask for tests using your actual test runner.

    Then check the output. It should import your app correctly, use real endpoint paths, await async calls, and assert status plus body. Do not accept tests that only check that a function was called.

    Common mistake

    Avoid weak tests

    A weak API test sends a request and only checks 200. That misses broken response data, missing validation, and wrong error messages.

    Also avoid testing against your running local server, like http://localhost:3000, unless you really need it. It is slower and can fail if the port is busy in your hostel Wi-Fi setup or CI.

    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    0 of 4 done

    Example

    Node.js workflow

    Create this file in your repo. Use it if your project has package.json and runs tests with npm test.

    The workflow installs dependencies with npm ci, then runs your test script on every push and pull request.

    # .github/workflows/tests.yml
    name: Tests
    
    on:
      push:
      pull_request:
    
    jobs:
      test:
        runs-on: ubuntu-latest
    
        steps:
          - name: Checkout code
            uses: actions/checkout@v4
    
          - name: Set up Node.js
            uses: actions/setup-node@v4
            with:
              node-version: 20
    
          - name: Install dependencies
            run: npm ci
    
          - name: Run tests
            run: npm test
    Example

    Python workflow

    Use this version if your tests run with pytest. Keep a requirements.txt file in the repo, or change the install step to match your project.

    If you use FastAPI, Flask, or Django, this same pattern still works. CI should run the command you already use locally.

    # .github/workflows/tests.yml
    name: Tests
    
    on:
      push:
      pull_request:
    
    jobs:
      test:
        runs-on: ubuntu-latest
    
        steps:
          - name: Checkout code
            uses: actions/checkout@v4
    
          - name: Set up Python
            uses: actions/setup-python@v5
            with:
              python-version: "3.11"
    
          - name: Install dependencies
            run: pip install -r requirements.txt
    
          - name: Run tests
            run: pytest
    Tip

    Use AI carefully

    You can ask ChatGPT or Gemini: “Write a GitHub Actions workflow for my repo. It uses Node 20 and npm test.” Paste your package.json or test command too.

    Check what it gives back. The file path must be .github/workflows/tests.yml. The run command must match your real local command. Do not add secrets or deployment steps for this lesson.

    Common mistake

    Green by accident

    A workflow can pass even when it did not run your real tests. This happens when npm test only prints a message, or when pytest finds zero tests.

    Open the workflow log after the first run. Look for your test runner output and the number of tests. Fix the script if CI is only pretending to test.

    // package.json
    {
      "scripts": {
        "test": "jest"
      }
    }
    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    7. Ship a tested public repo

    4 min

    In 30 seconds
    • Prepare a public repo so recruiters can see your tests fast.
    • Show one unit test, one API or integration test, and passing CI.
    • Add a clear README that explains how to run and read the tests.
    Key point

    Proof beats claims

    A recruiter should not have to trust your resume line. Your repo should show the proof in under two minutes: tests exist, tests pass, and CI ran on the latest push.

    Your goal is not to test everything. Your goal is to make the important behaviour visible and repeatable.

    Your to-do

    Repo checklist

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 6 done

    What recruiters scan

    They usually open your GitHub repo, then scan the README, file tree, and latest workflow status. Make those three things easy.

    Use simple names. A folder called tests is easier to spot than random files hidden inside the app. If your framework uses __tests__ or spec files, that is also fine.

    Example

    README test section

    Add a short section that tells someone how to run your tests locally. Mention what each test type covers.

    Keep it honest. If your API test uses a test database or mock server, say so.

    ## Tests
    
    This project includes:
    - Unit test: validates price calculation in src/utils/calculateTotal.js
    - API test: checks POST /api/orders returns 201 for a valid order
    - CI: GitHub Actions runs tests on every push
    
    Run locally:
    
    npm install
    npm test
    
    Latest CI status: check the Actions tab for the latest run on main.
    Common mistake

    Do not fake confidence

    Do not write “fully tested” if you only have two tests. Say what is covered.

    Do not submit a repo where CI is red. A failing workflow tells reviewers that you did not check your own proof before sharing it.

    Tip

    Use AI carefully

    You can ask ChatGPT, Gemini, or Claude to review your README and test names. Ask: “Can a recruiter understand what is tested in 60 seconds?”

    Check the answer yourself. AI may suggest claims your repo does not prove. Remove any line that is not backed by a real file or CI run.

    Your to-do

    Before you submit

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done