Bats Operations: Difference between revisions

From NovaOrdis Knowledge Base
Jump to navigation Jump to search
No edit summary
Line 7: Line 7:
  brew install bats
  brew install bats


=<span id='Script_to_Run_all_.bats_Tests_from_a_Directory'></span>Script to Run all .bats Tests from a Directory or Multiple Directories=


==Single Directory==
=Best Practices=
 
==<span id='Script_to_Run_all_.bats_Tests_from_a_Directory'></span>Script to Run all .bats Tests from a Directory or Multiple Directories==
 
===Single Directory===


<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
Line 20: Line 23:
</syntaxhighlight>
</syntaxhighlight>


==Multiple Directories==
===Multiple Directories===
<syntaxhighlight lang='bash'>
<syntaxhighlight lang='bash'>
#!/usr/bin/env bash
#!/usr/bin/env bash
Line 37: Line 40:
</syntaxhighlight>
</syntaxhighlight>


=Loading a Library to be Tested into a .bats Test=
==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:
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:
Line 53: Line 56:
For more details, see: {{Internal|Bats_Concepts#Libraries_being_Tested_and_Helpers|Libraries being Tested and Helpers}}
For more details, see: {{Internal|Bats_Concepts#Libraries_being_Tested_and_Helpers|Libraries being Tested and Helpers}}


=Handling stdout and stderr=
==Handling stdout and stderr==


<font color=darkgray>This is a proposed solution, I need to do more research:</font>
<font color=darkgray>This is a proposed solution, I need to do more research:</font>
Line 72: Line 75:
</syntaxhighlight>
</syntaxhighlight>


=Handling data=
==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/...
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==
=="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.
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'>
<syntaxhighlight lang='bash'>

Revision as of 21:47, 20 November 2019

Internal

Installation

brew install bats


Best Practices

Script to Run all .bats Tests from a Directory or Multiple Directories

Single Directory

#!/usr/bin/env bash

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

Multiple Directories

#!/usr/bin/env bash

for d in $(find . -type d -not -name '.'); do
    (
        d=${d#./}
        echo "running all tests from directory '${d}' ..."
        cd ${d};
        for i in *.bats; do
            echo "running $(basename ${i}) tests ..."
            bats ${i}
        done
    )
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/...



"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" ]]

    ...
}