shUnit2 Documentation

repository·master·Indexed 23 days ago

https://github.com/kward/shunit2

An xUnit-style unit testing framework for Bourne-based shell scripts, including sh, bash, dash, ksh, and zsh. It provides structured test lifecycles (oneTimeSetUp, setUp, tearDown, oneTimeTearDown), a variety of assertion types (assertEquals, assertTrue, assertContains, etc.), and support for JUnit XML reports, custom test suites, and conditional test skipping.

Tokens
3K
Snippets
11
Records
21
Agent score
33%

What's inside shUnit2

  1. How shUnit2 test lifecycles work

    master

    shUnit2 follows an xUnit-style lifecycle. It automatically identifies and executes any function in your script that is prefixed with test.

    To manage the environment, you can define several optional lifecycle hooks:

    1. oneTimeSetUp(): Runs once before any tests are executed. Use this for global setup like creating directories or setting environment variables.
    2. oneTimeTearDown(): Runs once after all tests have completed. Use this for global cleanup.
    3. setUp(): Runs before each individual test function. Use this to ensure each test starts with a clean state.
    4. tearDown(): Runs after each individual test function. Use this to clean up files or state created during a specific test.

    The execution flow for each test is: setUp() $\rightarrow$ test<Name>() $\rightarrow$ tearDown().

    sequenceDiagram
      participant unit_test as unit test
    
      unit_test-->>shUnit2: shUnit2 loaded from unit test
    
      note over unit_test,shUnit2: shUnit2 identifies test*() functions
    
      shUnit2->>unit_test: oneTimeSetUp()
    
      loop for each test function
        shUnit2->>unit_test: setUp()
        shUnit2->>unit_test: testSomeFunction()
        unit_test-->>script: code called from testSomeFunction()
        shUnit2->>unit_test: tearDown()
      end
    
      shUnit2->>unit_test: oneTimeTearDown()
  2. Configure test lifecycle with Setup and Teardown functions

    master

    shUnit2 provides several lifecycle hooks that you can override to manage your test environment. If these functions exist in your script, shUnit2 will call them automatically.

    • oneTimeSetUp: Called once before any tests are run. Use this to prepare a common environment for the entire suite.
    • oneTimeTearDown: Called once after all tests are completed. Use this for global cleanup.
    • setUp: Called before each individual test is run. Use this to reset the environment for every test.
    • tearDown: Called after each individual test completes. Use this to clean up after each test.
  3. Use shUnit2 as an executable or a library

    master

    shUnit2 can be used in two ways:

    1. As a library: Source the shunit2 script directly into your test script.
    2. As an executable: Call the shunit2 binary directly. This is helpful for maintaining compatibility across different OS distributions where the location of the shunit2 executable might vary.
  4. Write your first shUnit2 test

    master

    To use shUnit2, create a shell script containing functions prefixed with test. At the end of your script, source the shunit2 library.

    If you installed shUnit2 via a package manager (like Debian), you can simply use . shunit2. Otherwise, provide the path to the shunit2 file.

    Example of a basic equality test:

    #! /bin/sh
    # file: examples/equality_test.sh
    
    testEquality() {
      assertEquals 1 1
    }
    
    # Load shUnit2.
    . ../shunit2
  5. Configure Zsh compatibility for shUnit2

    master

    To use shUnit2 with Zsh, the shwordsplit option must be enabled. You can accomplish this in one of three ways:

    1. Inside the test script: Add setopt shwordsplit before sourcing the shunit2 library.
    2. Via Shebang: Use #! /bin/zsh -y at the top of your script.
    3. Via Command Line: Invoke zsh with the -o shwordsplit flag.
  6. Include line numbers in assert messages using macros

    master

    To identify exactly which assertion failed in a long test function, you can use shUnit2 macros. These macros include the line number in the error message (e.g., ASSERT:[123] ...).

    Supported Shells: bash (>=3.0), ksh, mksh, and zsh.

    Important Quoting Rule: Because of how shell parses arguments, all strings used with macros must be quoted twice. You must convert single-quotes to single-double-quotes and vice-versa.

    Example Mapping:

    • Standard: assertEquals 'message' 'x' 'y'
    • Macro: ${_ASSERT_EQUALS_} '"message"' 'x' '"y"'
    #! /bin/sh
    
    testLineNo() {
      # This assert will have line numbers included (e.g. "ASSERT:[123] ...").
      echo "ae: ${_ASSERT_EQUALS_}"
      ${_ASSERT_EQUALS_} '"not equal"' 1 2
    
      # This assert will not have line numbers included (e.g. "ASSERT: ...").
      assertEquals 'not equal' 1 2
    }
    
    # Load shUnit2.
    . ../shunit2
  7. Generate JUnit XML test reports

    master

    You can generate test results in JUnit XML format, which is compatible with CI tools like CircleCI. To use this feature, you must pass the --output-junit-xml flag to your test script. Note that because shUnit2 uses -- to separate script arguments from shUnit2 arguments, you must use the -- delimiter when invoking your script.

    Available flags:

    • --output-junit-xml=<path>: Specifies the file path where the XML report will be generated.
    • --suite-name=<name>: (Optional) Specifies a custom, more verbose name for the test suite in the XML output.
    # Basic usage
    $ mkdir -p results
    $ test-script.sh -- --output-junit-xml=results/test-script.xml
    
    # Usage with a custom suite name
    $ test-script.sh -- --output-junit-xml=results/test-script.xml --suite-name=Test_Script
  8. Configure shUnit2 color output

    master

    shUnit2 supports colored output. Color is enabled automatically when supported by the terminal. You can control this behavior by defining the SHUNIT_COLOR environment variable before sourcing shunit2.

    Accepted values:

    • auto (default)
    • always
    • none
  9. Use shUnit2 user-defined configuration constants

    master

    You can configure shUnit2 behavior by setting these variables in your environment or script:

    ConstantDescription
    SHUNIT_CMD_EXPROverride the expr command used (defaults to expr, or gexpr on BSD)
    SHUNIT_COLOREnable colorized output. Options: auto (default), always, or none
    SHUNIT_PARENTThe filename of the shell script containing the tests (required for Zsh support)
    SHUNIT_TEST_PREFIXA prefix added to each test name in the test report
  10. Define custom test suites using suite() and suite_addTest()

    master

    By default, shUnit2 dynamically finds all functions prefixed with test. To use a custom naming scheme or a specific subset of tests, you can define a suite() function.

    1. Define a suite() function in your script.
    2. Inside suite(), use suite_addTest name to add specific function names to the execution list.

    This approach overrides the default dynamic discovery.

  11. Use assertEquals and assertNotEquals

    master

    Asserts equality or inequality between two values. Both expected and actual values are treated as strings, so they work for both integers and string comparisons.

    • assertEquals [message] expected actual
    • assertNotEquals [message] unexpected actual

    Note: assertSame and assertNotSame are deprecated and functionally equivalent to the above.

    assertEquals [message] expected actual
    assertNotEquals [message] unexpected actual