Skip to main content

Overview

LiveCodes includes a built-in test runner supporting:
  • Jest - JavaScript testing framework
  • Testing Library - React, Vue, and other framework testing
  • Custom test frameworks - Bring your own
  • Live results - See results as you type

Getting Started

1

Create Tests

Write tests in the Tests editor (separate from your main script)
2

Run Tests

Click the Tests tab in the tools pane
3

View Results

See pass/fail status with details
Tests run in isolation from your main code but can import and test your functions.

Jest Tests

Basic Test Structure

// In Tests editor
import { sum } from './script';

describe('Math functions', () => {
  test('adds 1 + 2 to equal 3', () => {
    expect(sum(1, 2)).toBe(3);
  });
  
  test('adds negative numbers', () => {
    expect(sum(-1, -2)).toBe(-3);
  });
});

Test Functions

test('description', () => {
  expect(value).toBe(expected);
});

it('also works', () => {
  expect(value).toBe(expected);
});

Matchers

expect(value).toBe(4);           // Strict equality (===)
expect(obj).toEqual({ a: 1 });   // Deep equality
expect(value).not.toBe(5);       // Negation

React Testing

Use Testing Library for React components:
1

Use React Template

Start with the Jest + React starter template
2

Write Component Tests

import { render, screen, fireEvent } from '@testing-library/react';
import App from './script';

test('renders button', () => {
  render(<App />);
  const button = screen.getByRole('button');
  expect(button).toBeInTheDocument();
});

test('increments counter', () => {
  render(<App />);
  const button = screen.getByText(/click me/i);
  fireEvent.click(button);
  expect(screen.getByText(/clicked 1 times/i)).toBeInTheDocument();
});

React Testing Queries

screen.getByRole('button')
screen.getByText('Submit')
screen.getByLabelText('Email')
screen.getByPlaceholderText('Enter name')
screen.getByTestId('custom-element')

User Interactions

import { fireEvent } from '@testing-library/react';

// Click
fireEvent.click(button);

// Type
fireEvent.change(input, { target: { value: 'Hello' } });

// Submit
fireEvent.submit(form);

// Custom events
fireEvent.mouseEnter(element);
fireEvent.keyDown(element, { key: 'Enter' });

Async Testing

Promises

test('async test', async () => {
  const data = await fetchData();
  expect(data).toBe('success');
});

// Or with .resolves/.rejects
test('promise resolves', () => {
  return expect(fetchData()).resolves.toBe('success');
});

test('promise rejects', () => {
  return expect(failingFunction()).rejects.toThrow('error');
});

Async Queries

import { waitFor, screen } from '@testing-library/react';

test('waits for element', async () => {
  render(<AsyncComponent />);
  
  await waitFor(() => {
    expect(screen.getByText('Loaded')).toBeInTheDocument();
  });
});

Test Runner Controls

Run

Execute all testsKeyboard: Ctrl/Cmd + Alt + T

Watch

Auto-run tests on code changes

Reset

Clear test results

Test Results

Result Display

Test results show:
  • Test name and description
  • Status: Pass (green), Fail (red), Skip (gray)
  • Error messages for failing tests
  • Stack traces for debugging
  • Summary: Total, passed, failed, skipped

Pass/Fail Indicators

✓ adds 1 + 2 to equal 3
Green checkmark, no additional info

Skipping Tests

// Skip single test
test.skip('not ready yet', () => {
  // Won't run
});

// Skip test suite
describe.skip('Feature in progress', () => {
  test('test 1', () => { /* ... */ });
  test('test 2', () => { /* ... */ });
});

// Run only specific tests
test.only('run only this', () => {
  // Only this test runs
});

Importing Code Under Test

Access your script code:
// Import from your script editor
import { functionToTest, Component } from './script';

// Test imported code
test('tests function', () => {
  expect(functionToTest()).toBe(expected);
});
The tests editor has access to the script editor’s exports via ./script path.

Mocking

Mock Functions

const mockFn = jest.fn();

// Use mock
mockFn('arg');

// Assertions
expect(mockFn).toHaveBeenCalled();
expect(mockFn).toHaveBeenCalledWith('arg');
expect(mockFn).toHaveBeenCalledTimes(1);

// Mock return value
mockFn.mockReturnValue(42);
expect(mockFn()).toBe(42);

// Mock implementation
mockFn.mockImplementation((x) => x * 2);
expect(mockFn(5)).toBe(10);

Mock Modules

jest.mock('./api', () => ({
  fetchData: jest.fn(() => Promise.resolve('mocked data'))
}));

import { fetchData } from './api';

test('uses mocked module', async () => {
  const data = await fetchData();
  expect(data).toBe('mocked data');
});

Coverage

Code coverage is not currently available in LiveCodes. Consider running tests locally with Jest for coverage reports.

Best Practices

1

Write Clear Test Names

// Good
test('adds two positive numbers correctly', () => { });

// Avoid
test('test1', () => { });
2

One Assertion Per Test

// Good
test('returns correct length', () => {
  expect(result.length).toBe(3);
});

test('contains expected values', () => {
  expect(result).toContain('value');
});
3

Arrange-Act-Assert

test('increments counter', () => {
  // Arrange
  const counter = new Counter();
  
  // Act
  counter.increment();
  
  // Assert
  expect(counter.value).toBe(1);
});
4

Test Edge Cases

test('handles empty array', () => {
  expect(sum([])).toBe(0);
});

test('handles negative numbers', () => {
  expect(sum([-1, -2])).toBe(-3);
});

Troubleshooting

  • Click the Run button in tests panel
  • Check for syntax errors in test code
  • Verify Jest template is being used
  • Enable watch mode for auto-run
  • Ensure you’re importing from './script'
  • Check that exports exist in script editor
  • Verify export syntax is correct
Increase timeout:
test('async test', async () => {
  // Test code
}, 10000); // 10 second timeout

Build docs developers (and LLMs) love