Skip to Content

Last Updated: 4/7/2026


Testing Guide

Agricultural Microworlds uses Jest as its testing framework to ensure code quality and maintain the Sprint 5 goal of 90%+ test coverage. This guide walks you through running tests, understanding the existing test structure, checking coverage, and writing new unit tests.

Prerequisites

Before running tests, ensure you have:

  • Node.js and npm installed (handled automatically in the devcontainer)
  • Dependencies installed via npm install in the agricultural-microworlds.client/ directory
  • Babel configured for ESM module transformation (already set up in babel.config.js)

Running Tests

To run all tests in the project:

cd agricultural-microworlds.client npm run test

This command executes Jest, which will discover and run all test files in the tests/ directory.

Checking Test Coverage

To generate a coverage report and verify you’re meeting the 90%+ coverage goal:

npm run test -- --coverage

Jest will output a detailed coverage report showing:

  • Statements: Percentage of code statements executed
  • Branches: Percentage of conditional branches tested
  • Functions: Percentage of functions called
  • Lines: Percentage of code lines covered

The coverage report also identifies which files need additional test coverage.

Existing Test Structure

Currently, the test suite focuses on core simulation data structures. All test files are located in the tests/ directory.

Test FileCoverage AreaPurpose
BitmapFieldState.test.jsBitmapFieldState classTests the binary array abstraction layer used for efficient field tile storage, including initialization, cloning, variable management, and tile access methods

What Is Currently Tested

The existing test suite validates:

  • Field State Initialization: Correct creation of typed arrays (Uint8Array, Float32Array) for tile properties
  • Field Initialization: Proper population of all tiles with starting values
  • Cloning: Deep copy functionality for field states
  • Dynamic Variable Addition: Adding new properties to the field state at runtime
  • Tile Manipulation: Setting and getting individual tile properties
  • Variable Access: Reading and writing specific variables at tile coordinates

Writing a New Unit Test

To add a new test, create a .test.js file in the tests/ directory. Here’s the structure based on the existing test suite:

Example Test Structure

import BitmapFieldState from "../src/BinaryArrayAbstractionMethods/BitmapFieldState"; import { CROP_GDDS, CROP_STAGES, CROP_TYPES, } from "../src/States/StateClasses/CropState"; function CreateFieldState(rows, cols) { const tileKey = { ["stage"]: { size: 1, type: "uint8", }, ["type"]: { size: 1, type: "uint8", }, ["currentGDD"]: { size: 4, type: "float32", }, ["requiredGDD"]: { size: 4, type: "float32", }, ["waterLevel"]: { size: 4, type: "float32", }, ["minerals"]: { size: 4, type: "float32", }, }; return new BitmapFieldState(rows, cols, tileKey); } test("Initialization creates the correct arrays and values", () => { const rows = 10; const cols = 10; const test = CreateFieldState(rows, cols); const buffer1 = new ArrayBuffer(rows * cols * 1); const array1 = new Uint8Array(buffer1); expect(test.fieldProps["stage"]).not.toEqual(null); expect(test.fieldProps["stage"]).not.toEqual(undefined); expect(test.fieldProps["stage"].arr).toBeInstanceOf(Uint8Array); });

Test Writing Best Practices

  1. Import Dependencies: Import the module under test and any required constants or utilities
  2. Use Descriptive Test Names: Clearly describe what behavior is being tested
  3. Arrange-Act-Assert Pattern: Set up test data, execute the function, verify the result
  4. Test Edge Cases: Include tests for boundary conditions, empty inputs, and error states
  5. Isolate Tests: Each test should be independent and not rely on other tests

Common Jest Matchers

  • expect(value).toEqual(expected): Deep equality check
  • expect(value).not.toEqual(unexpected): Negation
  • expect(array).toBeInstanceOf(ArrayType): Type checking
  • expect(value).toBe(expected): Strict equality (===)
  • expect(fn).toThrow(): Function throws an error

Babel Configuration for ESM Modules

Agricultural Microworlds uses ES modules ("type": "module" in package.json), which require Babel transformation for Jest. The babel.config.js file configures this:

export default { presets: [["@babel/preset-env", { targets: { node: "current" } }]], };

This preset transforms modern JavaScript features to work with the current Node.js version during testing. The configuration is already set up and should not require modification for standard test cases.

Next Steps for Test Coverage

To reach the 90%+ coverage goal, consider adding tests for:

  • Simulation Managers: WeatherManager, CropGrowthManager, WorkerManager
  • State Classes: CropState, WeatherState, WorkerState
  • Blockly Integration: Custom block definitions and code generation
  • Rendering Pipeline: Canvas rendering and sprite management
  • Command System: Worker command execution and validation

Run npm run test -- --coverage regularly to identify untested code paths and prioritize test development.

What’s Next