🪟 Windows TippsAndroid 17: Neue Version ist hier – Das ist alles neu(16.09.2026 um 11:40 Uhr)
🕵️ Hacking12 Best CASB Solutions Compared (2026): Features & Pricing(16.09.2026 um 09:31 Uhr)
🕵️ Hacking12 Best CIEM Tools Compared (2026): Features & Pricing(16.09.2026 um 09:37 Uhr)
🪟 Windows TippsAndroid 17: Neue Version ist hier – Das ist alles neu(16.09.2026 um 11:40 Uhr)
🕵️ Hacking12 Best CASB Solutions Compared (2026): Features & Pricing(16.09.2026 um 09:31 Uhr)
🕵️ Hacking12 Best CIEM Tools Compared (2026): Features & Pricing(16.09.2026 um 09:37 Uhr)

🔧 Programmierung 🕛 vor 4 Monaten 10 Min Lesezeit
0

Simple JavaScript Automation Unit Testing Using Jest

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht




Objective



Learn to implement automated unit testing using Jest in a Node.js application. By the end of this lab, you will:




  • Set up a Node.js project with Jest for unit testing

  • Write unit tests for functions with validation and error handling

  • Understand the difference between statement and branch coverage

  • Run tests and generate coverage reports to evaluate code quality






Prerequisites




  • Node.js (version 14 or higher) installed

  • Basic knowledge of JavaScript and Node.js

  • A code editor (e.g., VS Code)

  • Terminal or command-line interface






Lab Overview



This lab guides you through creating a Node.js application with a divide function. You will progressively enhance the function while learning about unit testing, the AAA pattern, and the critical difference between statement and branch coverage.






Why Unit Testing is Important



Unit testing ensures individual code components work as expected, catching errors early and maintaining software quality. Without unit tests, bugs can reach production and cause serious issues.



Real-world example: Suppose a developer accidentally modifies a divide function to use multiplication instead of division while fixing a bug. This would make divide(10, 2) return 20 instead of 5, causing incorrect calculations. A unit test like expect(divide(10, 2)).toBe(5) would immediately fail, alerting the developer to the error.



CI/CD Integration: Unit tests integrate with Continuous Integration/Continuous Deployment pipelines. In systems like GitHub Actions, tests run automatically on every code change. If any test fails, the pipeline blocks the code from being merged or deployed to production, ensuring faulty code never reaches users.






The AAA Pattern: Structure of a Good Unit Test



Before diving into testing, it's important to understand the AAA pattern (Arrange-Act-Assert), a fundamental structure for writing clear and effective unit tests:





  1. Arrange: Set up the test data and conditions


    • Prepare the inputs

    • Initialize any required variables or objects

    • Set up the environment for the test




  2. Act: Execute the code being tested


    • Call the function or method

    • Perform the action you want to test

    • This is usually a single line of code




  3. Assert: Verify the expected outcome


    • Check that the result matches expectations

    • Use assertion methods like expect().toBe()

    • Confirm the code behaved correctly





The AAA pattern makes tests easier to read, understand, and maintain. You'll see this pattern throughout the lab.






Step-by-Step Instructions






Step 1: Set Up the Node.js Project





  1. Create a project directory:


    CODE
    mkdir jest-divide-app
    cd jest-divide-app




  2. Initialize a Node.js project:


    CODE
    npm init -y




  3. Install Jest:


    CODE
    npm install --save-dev jest




  4. Update package.json:



    Open package.json and modify the scripts section:


    CODE
    "scripts": {
    "test": "jest",
    "test:coverage": "jest --coverage"
    }








Step 2: Create the Application Code





  1. Create divide.js:



    Create a file named divide.js in the project root with the following simple code:


    CODE
    function divide(a, b) {
    return a / b;
    }

    module.exports = divide;




  2. Verify the file structure:


    CODE
    jest-divide-app/
    ├── node_modules/
    ├── package.json
    ├── package-lock.json
    └── divide.js








Step 3: Write Unit Tests





  1. Create divide.test.js:



    Create a file named divide.test.js in the project root:


    CODE
    const divide = require('./divide');

    test('divides 10 by 2 to equal 5', () => {
    expect(divide(10, 2)).toBe(5); // Arrange, Act, Assert combined
    });

    test('divides 20 by 4 to equal 5', () => {
    expect(divide(20, 4)).toBe(5);
    });

    test('divides 100 by 10 to equal 10', () => {
    expect(divide(100, 10)).toBe(10);
    });




  2. Test code explanation:





    • require('./divide'): Imports the divide function from divide.js


    • test(): Defines individual test cases with a description and assertion


    • expect(divide(10, 2)).toBe(5): Follows the AAA pattern in a single line



      • Arrange: The values 10 and 2 are the test inputs


      • Act: divide(10, 2) calls the function


      • Assert: .toBe(5) verifies the expected result










Step 4: Run the Tests





  1. Execute the tests:


    CODE
    npm test




  2. Expected output:


    CODE
    PASS  ./divide.test.js
    ✓ divides 10 by 2 to equal 5 (2 ms)
    ✓ divides 20 by 4 to equal 5 (1 ms)
    ✓ divides 100 by 10 to equal 10 (1 ms)

    Test Suites: 1 passed, 1 total
    Tests: 3 passed, 3 total
    Snapshots: 0 total
    Time: 0.5 s








Step 5: Generate Test Coverage Report





  1. Run the coverage command:


    CODE
    npm run test:coverage




  2. Expected output:


    CODE
    PASS  ./divide.test.js
    √ divides 10 by 2 to equal 5 (3 ms)
    √ divides 20 by 4 to equal 5 (1 ms)
    √ divides 100 by 10 to equal 10 (1 ms)
    -----------------|---------|----------|---------|---------|-------------------
    File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
    -----------------|---------|----------|---------|---------|-------------------
    All files | 100 | 100 | 100 | 100 |
    divide.js | 100 | 100 | 100 | 100 |
    -----------------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests: 3 passed, 3 total
    Snapshots: 0 total
    Time: 4.653 s, estimated 13 s
    Ran all test suites.




  3. View the HTML coverage report:




    • Jest creates a coverage directory in your project root

    • Open coverage/lcov-report/index.html in a web browser

    • The report displays which lines, functions, and branches are covered by tests





💡



Tip: Coverage doesn’t guarantee correctness. You can still have 100% statement/branch coverage and a failing test suite (for example, if the code is correct but a test has the wrong expected value, uses stale requirements, or has a flawed assertion). Always run and fix failing tests first, then use coverage to find what you’re missing—not to prove everything is correct.






Step 6: Analyze the Results





  1. Test results:


    • All 3 tests should pass

    • Tests cover basic division operations

    • If any test fails, review the test case and function implementation




  2. Coverage report:


    • The report should show 100% coverage for divide.js

    • All lines of the simple divide function are exercised by the tests








Adding Error Handling: Division by Zero



Mathematical operations have rules. Division by zero is undefined and should be handled properly.






Step 7: Add Zero-Division Protection





  1. Update divide.js:



    Add error handling for division by zero:


    CODE
    function divide(a, b) {
    if (b === 0) {
    throw new Error('Cannot divide by zero');
    }
    return a / b;
    }

    module.exports = divide;




  2. Run existing tests:


    CODE
    npm test



    Important: All 3 existing tests should still pass. They use non-zero divisors, but the coverage report will look like this:


    CODE
    PASS  ./divide.test.js
    √ divides 10 by 2 to equal 5 (3 ms)
    √ divides 20 by 4 to equal 5 (1 ms)
    √ divides 100 by 10 to equal 10 (1 ms)
    -----------------|---------|----------|---------|---------|-------------------
    File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
    -----------------|---------|----------|---------|---------|-------------------
    All files | 75 | 50 | 100 | 75 |
    divide.js | 75 | 50 | 100 | 75 | 3
    -----------------|---------|----------|---------|---------|-------------------
    Test Suites: 1 passed, 1 total
    Tests: 3 passed, 3 total
    Snapshots: 0 total
    Time: 4.653 s, estimated 13 s
    Ran all test suites.








Step 8: Add Tests for Error Handling





  1. Update divide.test.js:



    Add test cases for the zero-division error:


    CODE
    const divide = require('./divide');

    // Tests for valid division operations
    test('divides 10 by 2 to equal 5', () => {
    expect(divide(10, 2)).toBe(5);
    });

    test('divides 20 by 4 to equal 5', () => {
    expect(divide(20, 4)).toBe(5);
    });

    test('divides 100 by 10 to equal 10', () => {
    expect(divide(100, 10)).toBe(10);
    });

    // Tests for error handling (AAA pattern for error testing)
    test('throws error when dividing by zero', () => {
    // Arrange - prepare invalid input
    const divisor = 0;

    // Act & Assert - expect function to throw error
    expect(() => divide(10, divisor)).toThrow('Cannot divide by zero');
    });

    test('throws error when dividing zero by zero', () => {
    expect(() => divide(0, 0)).toThrow('Cannot divide by zero');
    });



    Note on testing errors with AAA:






CODE
- **Arrange**: Prepare invalid inputs
- **Act & Assert**: Use `expect(() => ...)` to wrap the function call and verify it throws
- The arrow function prevents the error from stopping the test execution






  1. Run the updated tests:


    CODE
    npm test



    Expected output:


    CODE
    PASS  ./divide.test.js
    ✓ divides 10 by 2 to equal 5 (2 ms)
    ✓ divides 20 by 4 to equal 5 (1 ms)
    ✓ divides 100 by 10 to equal 10 (1 ms)
    ✓ throws error when dividing by zero (3 ms)
    ✓ throws error when dividing zero by zero (1 ms)

    Test Suites: 1 passed, 1 total
    Tests: 5 passed, 5 total
    Snapshots: 0 total
    Time: 0.6 s




  2. Verify coverage:


    CODE
    npm run test:coverage



    The coverage should still be 100% as all code paths are tested.








Understanding Statement vs Branch Coverage



Now we'll learn a critical lesson: 100% statement coverage does NOT guarantee fully tested code.






Step 9: Add Complex Logic with Branches





  1. Update divide.js with conditional logic:



    Add a feature to handle negative numbers by returning the absolute value:


    CODE
    function divide(a, b) {
    if (b === 0) {
    throw new Error('Cannot divide by zero');
    }
    if (a < 0 || b < 0) {
    return Math.abs(a / b);
    }
    return a / b;
    }

    module.exports = divide;



    New logic explained:






CODE
- If either number is negative, return the absolute value of the division
- This creates multiple branches: both positive, first negative, second negative, both negative






  1. Run existing tests (don't add new ones yet):


    CODE
    npm test



    All 5 tests should still pass!




  2. Check coverage:


    CODE
    npm run test:coverage



    Critical observation:


    CODE
    -----------------|---------|----------|---------|---------|-------------------
    File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
    -----------------|---------|----------|---------|---------|-------------------
    All files | 100 | 50 | 100 | 100 |
    divide.js | 100 | 50 | 100 | 100 | 5
    -----------------|---------|----------|---------|---------|-------------------



    Notice:






CODE
- **Statement coverage**: 100% ✓ (all lines executed)
- **Branch coverage**: 50% ✗ (not all decision paths tested)
- Line 5 (the `if (a < 0 || b < 0)` condition) shows partially covered






  1. Open the HTML coverage report:



    Open coverage/lcov-report/index.html in a browser:







CODE
- Line 5 will be highlighted in yellow or have an indicator showing 2/4 or similar


  • This means the condition was executed, but not all branches were taken







Step 10: Understanding the Gap




Why 100% statement coverage but only 50% branch coverage?



The condition if (a < 0 || b < 0) has multiple branches:





  • a < 0 is true (left side of ||)


  • a < 0 is false AND b < 0 is true (right side of ||)

  • Both are false (skip the if block)



Our current tests only cover:




  • Both positive: divide(10, 2) → condition is false, line 5 executes but if-block doesn't

  • This gives 100% statement coverage (line 5 executed) but misses the branches!



The danger: We've never actually tested what happens when negative numbers are passed!






Step 11: Achieve 100% Branch Coverage





  1. Update divide.test.js with comprehensive tests:


    CODE
    const divide = require('./divide');

    describe('divide function', () => {
    describe('positive numbers', () => {
    test('divides 10 by 2 to equal 5', () => {
    expect(divide(10, 2)).toBe(5);
    });

    test('divides 20 by 4 to equal 5', () => {
    expect(divide(20, 4)).toBe(5);
    });

    test('divides 100 by 10 to equal 10', () => {
    expect(divide(100, 10)).toBe(10);
    });
    });

    describe('negative numbers (returns absolute value)', () => {
    test('divides negative dividend by positive divisor', () => {
    // Arrange
    const dividend = -10;
    const divisor = 2;

    // Act
    const result = divide(dividend, divisor);

    // Assert
    expect(result).toBe(5); // |-10 / 2| = 5
    });

    test('divides positive dividend by negative divisor', () => {
    expect(divide(10, -2)).toBe(5); // |10 / -2| = 5
    });

    test('divides two negative numbers', () => {
    expect(divide(-10, -2)).toBe(5); // |-10 / -2| = 5
    });

    test('divides negative by negative with different result', () => {
    expect(divide(-20, -4)).toBe(5); // |-20 / -4| = 5
    });
    });

    describe('error handling', () => {
    test('throws error when dividing by zero', () => {
    expect(() => divide(10, 0)).toThrow('Cannot divide by zero');
    });

    test('throws error when dividing zero by zero', () => {
    expect(() => divide(0, 0)).toThrow('Cannot divide by zero');
    });

    test('throws error when dividing negative by zero', () => {
    expect(() => divide(-10, 0)).toThrow('Cannot divide by zero');
    });
    });
    });




  2. Run the complete test suite:


    CODE
    npm test



    Expected output:


    CODE
    PASS  ./divide.test.js
    divide function
    positive numbers
    ✓ divides 10 by 2 to equal 5 (2 ms)
    ✓ divides 20 by 4 to equal 5 (1 ms)
    ✓ divides 100 by 10 to equal 10 (1 ms)
    negative numbers (returns absolute value)
    ✓ divides negative dividend by positive divisor (1 ms)
    ✓ divides positive dividend by negative divisor (1 ms)
    ✓ divides two negative numbers (1 ms)
    ✓ divides negative by negative with different result (1 ms)
    error handling
    ✓ throws error when dividing by zero (3 ms)
    ✓ throws error when dividing zero by zero (1 ms)
    ✓ throws error when dividing negative by zero (1 ms)

    Test Suites: 1 passed, 1 total
    Tests: 10 passed, 10 total
    Snapshots: 0 total
    Time: 0.8 s




  3. Generate final coverage report:


    CODE
    npm run test:coverage



    Now you should see:


    CODE
    -----------------|---------|----------|---------|---------|-------------------
    File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
    -----------------|---------|----------|---------|---------|-------------------
    All files | 100 | 100 | 100 | 100 |
    divide.js | 100 | 100 | 100 | 100 |
    -----------------|---------|----------|---------|---------|-------------------



    Perfect! 100% coverage across all metrics!




  4. Check the HTML report:



    Open coverage/lcov-report/index.html:







CODE
- All lines should be highlighted in green


  • No yellow or red indicators

  • All branches fully tested







References





  • Jest Documentation:

  • Jest Expect API:

Vollständiger Original-Artikel
Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
2 Quellen
CVE-2026-88255 | ZenHive mpp up to 0.16.1 Duplicate Submission Gate lib/mpp/replay.ex reserve_hash_atomic input validation (EUVD-2026-80256)
1 Quelle
Android 17: Neue Version ist hier – Das ist alles neu
1 Quelle
Die entscheidende Hürde: Xpeng will deutsch und nicht chinesisch sein
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Simple JavaScript Automation Unit Testing Using Jest

Thematisch verwandte Begriffe: Simple, JavaScript, Automation, Unit · 6 Treffer

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...