Busted Unit Testing Framework

repository·master·Indexed 23 days ago

https://github.com/lunarmodules/busted

A unit testing framework for Lua (>= 5.1), LuaJIT (>= 2.0.0), and MoonScript. Busted features a readable syntax using describe blocks, extensible assertions with method chaining, and built-in support for mocks and spies. It provides a comprehensive CLI for test filtering and execution control, supports multiple output formats including JSON and TAP, and can be deployed via Docker or as a GitHub Action.

Tokens
2.3K
Snippets
4
Records
8
Agent score
81%

What's inside Busted

  1. Overview of Busted unit testing framework

    master

    Busted is a unit testing framework for Lua (>= 5.1), LuaJIT (>= 2.0.0), and MoonScript. It focuses on ease of use through a natural, readable syntax for test specs.

    Key features include:

    • Nested Test Blocks: Use describe to group tests with contextual descriptions.
    • Extensible Assertions: An assertion library that supports method chaining (e.g., assert.is_not.equal).
    • Mocks and Spies: Built-in support for functional testing using spy.
    • Modular Output: Supports multiple output formats including pretty, plain, JSON (with/without streaming), and TAP-compatible output for CI integration.
    describe('Busted unit testing framework', function()
      describe('should be awesome', function()
        it('should be easy to use', function()
          assert.truthy('Yup.')
        end)
    
        it('should have lots of features', function()
          -- deep check comparisons!
          assert.same({ table = 'great'}, { table = 'great' })
    
          -- or check by reference!
          assert.is_not.equals({ table = 'great'}, { table = 'great'})
    
          assert.falsy(nil)
          assert.error(function() error('Wat') end)
        end)
    
        it('should provide some shortcuts to common functions', function()
          assert.unique({{ thing = 1 }, { thing = 2 }, { thing = 3 }})
        end)
    
        it('should have mocks and spies for functional tests', function()
          local thing = require('thing_module')
          spy.on(thing, 'greet')
          thing.greet('Hi!')
    
          assert.spy(thing.greet).was.called()
          assert.spy(thing.greet).was.called_with('Hi!')
        end)
      end)
    end)
  2. Configure Busted as a GitHub Actions job

    master

    You can use the official Busted GitHub Action to run tests in your CI workflow. By default, it runs busted --verbose. You can override the default behavior by passing custom args via the with block.

    name: Busted
    on: [push, pull_request]
    jobs:
      sile:
        runs-on: ubuntu-latest
        steps:
          - name: Checkout
            uses: actions/checkout@v3
          - name: Run Busted
            uses: lunarmodules/busted@v0
            with:
                args: --tags=MYTAGS
  3. Run Busted using Docker

    master

    Busted can be run as a standalone Docker container (based on Alpine Linux). This is ideal for pure-Lua projects. Luarocks is included in the container, and you can use apk add for system dependencies.

    To build your own image from the source:

    docker build -t ghcr.io/lunarmodules/busted:HEAD .

    To pull a prebuilt image:

    docker pull ghcr.io/lunarmodules/busted:latest

    To run Busted on an entire project (mounting the current directory to /data):

    docker run -v "$(pwd):/data" ghcr.io/lunarmodules/busted:latest

    To run Busted on a specific directory (e.g., specs):

    docker run -v "$(pwd):/data" ghcr.io/lunarmodules/busted:latest specs
  4. How Busted loads configuration

    master

    Busted follows a specific hierarchy for loading configuration:

    1. Explicit Config File: If -f, --config-file=FILE is provided, Busted loads that file. If the file does not exist, Busted returns an error.
    2. Default Config File: If no config file is specified via CLI, Busted looks for a .busted file in the current working directory (or the directory specified by --directory).
    3. CLI Arguments: Arguments passed via the command line override settings found in configuration files.

    When a configuration file is loaded, it is executed as a Lua file, and its return value is passed to the configuration_loader to merge with CLI arguments.

  5. Use spies for functional testing

    master

    Busted provides spy to track function calls. You can use spy.on(module, 'function_name') to attach a spy to an existing function. Once the function is called, you can verify its behavior using the assert.spy syntax, checking if it was.called() or was.called_with(...) specific arguments.

    local thing = require('thing_module')
    spy.on(thing, 'greet')
    thing.greet('Hi!')
    
    assert.spy(thing.greet).was.called()
    assert.spy(thing.greet).was.called_with('Hi!')
  6. Busted CLI Reference: Options and Flags

    master

    Busted provides a comprehensive set of command-line options for controlling test execution, filtering, and environment configuration.

    Test Selection and Filtering

    • -p, --pattern=PATTERN: Only run test files matching the Lua pattern. Supports multiple patterns.
    • --exclude-pattern=PATTERN: Do not run test files matching the Lua pattern. Takes precedence over --pattern.
    • -t, --tags=TAGS: Only run tests with these #tags. Supports comma-separated lists.
    • --exclude-tags=TAGS: Do not run tests with these #tags. Takes precedence over --tags.
    • --filter=PATTERN: Only run test names matching the Lua pattern.
    • --filter-out=PATTERN: Do not run test names matching the Lua pattern. Takes precedence over --filter.
    • --name=NAME: Run a specific test by its full name.
    • --exclude-names-file=FILE: Do not run tests with names listed in the specified file. Takes precedence over --filter.
    • -l, --list: List the names of all tests instead of running them.

    Execution Control

    • -e STATEMENT: Execute a Lua statement before running tests.
    • --repeat=COUNT: Run the tests repeatedly (default: 1).
    • --seed=SEED: Random seed value for shuffling test order.
    • --lang=LANG: Language for error messages (default: en).
    • --loaders=NAME: Specify test file loaders (default: lua,moonscript).
    • --helper=PATH: A helper script to run before tests.
    • --lua=LUA: Path to the Lua interpreter Busted should run under.
    • -R, --recursive: Recurse into subdirectories (default: true).
    • --[no-]shuffle: Randomize file and test order. Takes precedence over --sort.
    • --[no-]shuffle-files: Randomize file execution order.
    • --[no-]shuffle-tests: Randomize test order within a file.
    • --[no-]sort: Sort file and test order.
    • --[no-]sort-files: Sort file execution order.
    • --[no-]sort-tests: Sort test order within a file.
    • --[no-]lazy: Use lazy setup/teardown as the default.
    • --[no-]auto-insulate: Enable file insulation (default: true).
    • -k, --[no-]keep-going: Continue as much as possible after an error or failure (default: true).
    • --[no-]suppress-pending: Suppress pending test output.
    • --[no-]defer-print: Defer print to when the test suite is complete.

    Environment and Configuration

    • -o, --output=LIBRARY: Output library to load (default: utfTerminal).
    • -C, --directory=DIR: Change to directory DIR before running tests. Multiple options are interpreted relative to the previous one.
    • -f, --config-file=FILE: Load configuration options from a specific file.
    • --coverage-config-file=FILE: Load luacov configuration options from a file.
    • -m, --lpath=PATH: Prefix to the Lua module search path.
    • --cpath=PATH: Prefix to the Lua C module search path.
    • -r, --run=RUN: Configuration to run from a .busted file.
    • --log-success=FILE: Append the name of each successful test to the given file.
    • -Xoutput OPTION: Pass OPTION as an option to the output handler.
    • -Xhelper OPTION: Pass OPTION as an option to the helper script.

    Debugging and Metadata

    • --version: Prints the program version and exits.
    • -v, --[no-]verbose: Verbose output of errors.
    • -c, --[no-]coverage: Do code coverage analysis (requires LuaCov).
    • -s, --[no-]enable-sound: Executes say command if available.
  7. Run Busted via the CLI

    master
    The busted command is the primary CLI entrypoint for running Lua test suites. It invokes the busted.runner to discover and execute tests within your project. You can run it directly from your terminal to execute tests in the current directory or specify target paths.