Skip to content

Recitation #5

17-356/17-766

Unit Testing

  • Testing individual components or units of code in isolation.
  • A unit can be a function, method, or class.
  • Why Unit Testing?
  • Easy to define scope and logic.
  • Catches bugs early in the development cycle.
  • Facilitates refactoring and maintenance.

Jest

  • JavaScript testing framework developed by Facebook
  • Great for testing both backend and frontend
  • Built-in assertion libraries and mocking functionalities
  • Easy to use!

Why Test Everything? Even Simple Logic

  • Future-Proofing
  • Refactoring Safety
  • Edge Cases
  • Different data type: JSON, null, None, undefined, empty strings, or unexpected objects.
  • Unpredictable behaviors: clicking button 1000 times, rapid API calls
  • Boundary Conditions: integer overflow
  • Concurrency Issues

Async Functions

  • Always use await and tools like waitFor to test async functions.
  • Example: handle API calls or delayed updates

Frontend Unit Test

  • Interact with component: (e.g., Click, Submit forms)
  • Styling and Layout
  • Write test for styling and properties if it is critical to functionality (e.g., a disabled button color).
  • Avoid testing purely visual aspects; use visual regression tools instead.
  • Test Error code as well

TDD: Worth the Hype or Overkill

  • Pros
  • Ensures testable design.
  • Prevents engineers from deleting failing tests when bugs arise.
  • Cons
  • Can slow down development, especially in fast-paced startups.
  • May feel restrictive for exploratory or prototype-driven projects.
  • Solution
  • Use TDD for critical components.
  • Avoid focusing too much on testing coding style.
  • Use AI tools to generate code based on test cases?

How Do We Know We Test Everything?

  • Black Box Testing
  • Focuses on all the possible input and output without knowing internal logic.
  • Tests functionality from the user’s perspective.
  • White Box Testing
  • Tests all internal structures and code.
  • Ensures all paths, branches, and conditions are covered

How to Test Randomness

  • Use a fixed seed to make random behavior deterministic.
  • Test Range or Distribution.
  • Verify that outputs fall within expected ranges.
  • Mock Randomness function.
  • Run several times, and make sure there’s no pattern between them

Mocking: Isolating Your Tests

  • Simulating the behavior of real objects or services.
  • Common Use Cases:
  • API calls.
  • Database queries.
  • Components that the output is hard to predict (e.g., time-dependent functions, randomness, AI algorithms)
  • Why Mock?
  • Speed
  • Reliability & Easy to debug
  • Simulate specific scenarios (e.g., errors, timeouts)
  • Avoid Extra Costs
  • Examples
    jest.mock("axios");
    
    beforeEach(() => {
      axios.mockClear(); // Clear previous mocks before each test
    });
    
    test("clicking (8 + 9 =) results in (17)", async () => {
      // Mock Axios response
      axios.post.mockResolvedValueOnce({
        data: { result: "17" }, // Mock response data
      });
    });