Difference between revisions of "Bats Operations"

From NovaOrdis Knowledge Base
Jump to: navigation, search
(Handling data)
("Overload" Functions)
 
Line 62: Line 62:
  
 
A useful technique when testing a layer is to "override" (declare) the functions called from that layer right before the test, so we can control input and output in the layer.
 
A useful technique when testing a layer is to "override" (declare) the functions called from that layer right before the test, so we can control input and output in the layer.
 +
 +
 +
<syntaxhighlight lang='bash'>
 +
function setup() {
 +
 +
    function some-function() {
 +
        echo "some-function($@)"
 +
    }
 +
}
 +
 +
...
 +
 +
@test "test invocation through layer to some-function()" {
 +
 +
    run caller-function A B C
 +
 +
    [[ ${status} -eq 0 ]]
 +
    [[ "${output}" =~ some-function\(.*\) ]]
 +
 +
    args=${output#some-function(}
 +
    args=${args%)}
 +
 +
    arg0=${args%% *}
 +
    [[ ${arg0} = "A" ]]
 +
 +
    args=${args#${arg0} }
 +
    arg1=${args%% *}
 +
    [[ ${arg1} = "B" ]]
 +
 +
    ...
 +
}
 +
</syntaxhighlight>

Latest revision as of 18:48, 11 October 2019

Internal

Installation

brew install bats

Script to Run all .bats Tests from a Directory

#!/usr/bin/env bash

for i in $(dirname $0)/*.bats; do
    echo "running $(basename ${i}) tests ..."
    bats $i
done

Loading a Library to be Tested into a .bats Test

Assuming that the library you want to test is called 'blue.shlib', create a 'blue-library.bash' file in the directory that contain the .bats tests. If the library is located at a fixed relative location to the .bats test files, use this arrangement:

source ${BATS_TEST_DIRNAME}/[...]/blue.shlib

Otherwise, you can use an absolute path, but that is more fragile.

From each .bats test that wants to test functionality from that library:

load blue-library
For more details, see:
Libraries being Tested and Helpers

Handling stdout and stderr

This is a proposed solution, I need to do more research:

@test "test all outputl" {
  local stdoutPath="${BATS_TMPDIR}/${BATS_TEST_NAME}.stdout"
  local stderrPath="${BATS_TMPDIR}/${BATS_TEST_NAME}.stderr"

  myCommandOrFunction 1>${stdoutPath} 2>${stderrPath}

  grep "What Im looking for in stdout"  ${stdoutPath}
  ! grep "something it cannot appear in stdout"  ${stdoutPath}

  grep "What I'm looking for in stderr" ${stderrPath}
  ! grep "Something it cannot appear in stderr" ${stderrPath}
}

Handling data

A useful pattern is to create a "data" subdirectory in the directory that holds the .bats tests, and then access it from the tests with ${BATS_TEST_DIRNAME}/data/...

Best Practice

"Overload" Functions

A useful technique when testing a layer is to "override" (declare) the functions called from that layer right before the test, so we can control input and output in the layer.


function setup() {

    function some-function() {
        echo "some-function($@)"
    }
}

...

@test "test invocation through layer to some-function()" {

    run caller-function A B C

    [[ ${status} -eq 0 ]]
    [[ "${output}" =~ some-function\(.*\) ]]

    args=${output#some-function(}
    args=${args%)}

    arg0=${args%% *}
    [[ ${arg0} = "A" ]]

    args=${args#${arg0} }
    arg1=${args%% *}
    [[ ${arg1} = "B" ]]

    ...
}