ZUnit

repository·master·Indexed 42 days ago

https://github.com/zunit-zsh/zunit

A unit testing framework for ZSH featuring a BATS-inspired syntax. It includes tools for bootstrapping test suites via `zunit init`, executing tests with `zunit run`, and generating reports in TAP, text, or HTML formats. Supports test timeouts, fail-fast execution, and configuration via a `.zunit.yml` file.

Tokens
1.8K
Snippets
10
Records
13
Agent score
49%

What's inside ZUnit

  1. Install ZUnit via zplug

    master

    ZUnit and its dependencies can be managed using zplug. Ensure you include the revolver dependency and use the hook-build option to run the build script during installation.

    zplug 'molovo/revolver', \
      as:command, \
      use:revolver
    zplug 'zunit-zsh/zunit', \
      as:command, \
      use:zunit, \
      hook-build:'./build.zsh'
  2. Write a ZUnit test file

    master

    ZUnit uses a syntax inspired by the BATS framework.

    Critical Requirement: Every test file MUST start with the ZUnit shebang #!/usr/bin/env zunit at the very top of the file, otherwise ZUnit will not execute the file.

    Each test is defined using the @test 'description' { ... } syntax, and the body can contain any valid ZSH code.

    #!/usr/bin/env zunit
    
    @test 'My first test' {
    	# Test contents here
    }
  3. Install ZUnit via Zulu

    master

    You can install ZUnit using the Zulu package manager.

    Note for Zulu versions prior to 1.2.0: You must manually build and link the package after installation:

    1. Install via Zulu: zulu install zunit
    2. Navigate to the package directory: cd ~/.zulu/packages/zunit
    3. Run the build script: ./build.zsh
    4. Link the package: zulu link zunit
    zulu install zunit
  4. Install ZUnit manually

    master

    To install manually, clone the repository, run the build script, and move the resulting binary to your local bin directory.

    Dependency Note: ZUnit requires Revolver to be installed and present in your $PATH. The Zulu and Homebrew installation methods handle this dependency automatically.

    git clone https://github.com/zunit-zsh/zunit
    cd ./zunit
    ./build.zsh
    chmod u+x ./zunit
    cp ./zunit /usr/local/bin
  5. Understand 'risky' tests and --allow-risky

    master

    A test is considered "risky" if it completes without executing any assertions (i.e., the internal _zunit_assertion_count remains 0). By default, ZUnit will issue a warning for these tests.

    To suppress these warnings, use the --allow-risky flag or set allow_risky: true in your .zunit.yml configuration.

  6. Handle test timeouts with --time-limit

    master

    You can prevent tests from hanging indefinitely by setting a maximum execution time per test using the --time-limit <n> flag, where <n> is the number of seconds.

    If a test exceeds this limit, ZUnit will terminate the test process and report an error (exit code 78). This feature requires ZSH version 5.1.0 or higher to support asynchronous process management.

    zunit run --time-limit 5
  7. Generate TAP, Text, or HTML reports

    master

    ZUnit can output test results in multiple formats for integration with other tools or for human review:

    • TAP Format: Use the -t or --tap flag. This is useful for CI/CD pipelines. If enabled, ZUnit will print the TAP header and footer to stdout.
    • Text Log: Use the --output-text flag. This writes a TAP-compatible report to a file. The file location is determined by the directories.output setting in your .zunit.yml file. The report is saved as output.txt within that directory.
    • HTML Report: Use the --output-html flag. This generates an HTML page summarizing the results. The file is saved as output.html within the directory specified by directories.output in your .zunit.yml file.

    Requirement: To use --output-text or --output-html, you must have a .zunit.yml file with a defined directories.output path.

  8. Default .zunit.yml configuration structure

    master

    When you run zunit init, a .zunit.yml file is created with the following default schema:

    tap: false
    directories:
      tests: tests
      output: tests/_output
      support: tests/_support
    time_limit: 0
    fail_fast: false
    allow_risky: false

    Key fields:

    • tap: Boolean, enables Test Anything Protocol output.
    • directories: Defines where tests, output files, and support files are located.
    • time_limit: Maximum execution time (0 for no limit).
    • fail_fast: If true, stops execution after the first failure.
    • allow_risky: Boolean flag for risky test operations.
    tap: false
    directories:
      tests: tests
      output: tests/_output
      support: tests/_support
    time_limit: 0
    fail_fast: false
    allow_risky: false
  9. Use 'zunit init' options

    master

    The zunit init command supports the following options:

    FlagDescription
    -h, --helpOutput help text and exit
    -v, --versionOutput version information and exit
    -t, --travisGenerate a .travis.yml file in the project directory

    Example: Initialize with Travis CI support

    zunit init --travis
    zunit init -t
  10. Configure 'zunit run' options

    master

    The zunit run command supports several flags to control execution behavior, output formats, and error handling:

    FlagLong FlagDescription
    -h--helpOutput help text and exit
    -v--versionOutput version information and exit
    -f--fail-fastStop the test runner immediately after the first failure
    -t--tapOutput results in a TAP (Test Anything Protocol) compatible format
    --verbosePrints full output from each test
    --output-textPrint results to a text log in TAP compatible format
    --output-htmlPrint results to an HTML page
    --allow-riskySuppress warnings generated for tests with no assertions
    --time-limit <n>Set a time limit of n seconds for each test
  11. Use the 'zunit run' command

    master

    The zunit run command is the primary entrypoint for executing ZUnit tests. You can pass specific test files, directories, or patterns as arguments. If no arguments are provided, ZUnit defaults to the path defined in your .zunit.yml configuration, or the tests directory if no configuration is found.

    Note: All ZUnit test files must contain the following shebang on the first line to be considered valid:

    #!/usr/bin/env zunit
    zunit run [options] [tests...]