How do you programmatically add a bats test?

419 Views Asked by At

I'd like to have a BATS test created for every file in a directory, but I'm not sure what the best way to get this done is. The approach below only creates a single test even when there are many files in the directory.

#!/usr/bin/env bats

for i in ./*;do
  @test "testing $i" {
    pwd
  }  
done
2

There are 2 best solutions below

1
On

How about this?

#!/usr/bin/env bash

declare -r BATS=`mktemp`

trap "rm -f $BATS" EXIT

for i in $(ls)
do

cat > $BATS <<EOF
@test "testing $i" {
    pwd
}  
EOF

done

bats $BATS
0
On

When a test is run by BATS, the file is first preprocessed.1

This replaces the @test block with an actual function and adds a call to that function.

The result is then stored in the BATS_TMPDIR as bats.${PID}.src.

Any programmatically added tests would need to be added to the preprocessed file.

The test names would also have to be added to BATS_TEST_NAMES.

Putting all of this together we get:2

#!/usr/bin/env bats

declare sFile sSourceFile sTestFunction sTestName

readonly sSourceFile="${BATS_TMPDIR}/bats.$$.src"

if [[ -f "${sSourceFile}" ]];then
    for sFile in ./*;do
        sTestFunction="test_${sFile}"
        sTestName="Testing ${sFile}"

        cat <<EOT >> "${sSourceFile}"
            $sTestFunction() { bats_test_begin '$sTestName' 0;
                return 0
            }
            bats_test_function "${sTestFunction}"
EOT

        BATS_TEST_NAMES+=("${sTestFunction}")
    done
fi

#EOF

Why your example doesn't work

The preprocessed version of your example looks like this:

#!/usr/bin/env bats

for i in ./*; do
test_testing_-24i() { bats_test_begin "testing $i" 4;
    pwd
  }
done

bats_test_function test_testing_-24i

So effectively, the test function is declared as many times as there are files present. The test function, however, is only called once.3

Footnotes

  1. https://github.com/bats-core/bats-core/wiki/Bats-Evaluation-Process
  2. The variable naming scheme used in this code is an adaption of Systems Hungarian which is explained at http://blog.pother.ca/VariableNamingConvention/
  3. The solution suggested by NAKAI suffers from other issues, caused by the same process.