Programming/Bash/Unit Testing: Difference between revisions
Brodriguez (talk | contribs) (Import contents from bash page) |
Brodriguez (talk | contribs) (Update page for proper syntax from non-depreciated Bats project) |
||
(6 intermediate revisions by the same user not shown) | |||
Line 1: | Line 1: | ||
For UnitTesting in bash, use [https://github.com/bats-core/bats-core Bats]. | |||
Bats is a Bash UnitTesting framework, that's installed into the system PATH via [[NPM]]. | |||
== | == Installing Bats == | ||
With [[NPM]] installed, run: | |||
sudo npm install -g bats | |||
See https://github.com/bats-core/bats-core for alternative install methods. | |||
== Using Bats == | |||
From what I've seen, documentation on the web is inconsistent in regards to calling bats, so I document here what I found to work best for me: | |||
1) Create a new test script in your project. Maybe something like {{ ic |<project_root>/tests/test.sh}}<br> | |||
2) Add execution permissions to this test script. | |||
chmod +x <project_root>/tests/test.sh | |||
3) In the first line of the script, prefix it with the standard {{ ic |#!/usr/bin/env bash}} header.<br> | |||
4) As the very first line of code to execute, set the command: | |||
cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )" | |||
This will set the scripts internal directory to the folder it exists in, regardless of where the terminal is upon calling it.<br> | |||
5) At this point, create one or more separate test files, group related tests together. Call these subfiles them from your main {{ ic |tests.sh}} file via the command: | |||
bats <test_file_to_call> | |||
If done correctly, all tests in that file should execute. Repeat for every test file you wish to run. | |||
For added clarification, add echo statements between file imports, in order to visually split up test output. | |||
== Functions == | |||
To initialize functions that run once before all tests and after all tests: | |||
### | |||
# This will run once, before any tests execute. | |||
## | |||
setup_file () { | |||
# Setup logic here. | |||
} | |||
### | |||
# This will run once, after all tests execute. | |||
## | |||
teardown_file () { | |||
# Teardown logic here. | |||
} | |||
To initialize functions that run at the start and end of every test with: | |||
### | ### | ||
# This will run at the start of every test. | # This will run at the start of every test. | ||
Line 30: | Line 74: | ||
} | } | ||
{{ note | To prevent variable state leak between tests, each test is executed as a separate process. Thus, any echo statements within the tests themselves will not visually print out to console.}} | |||
== | == Assertions == | ||
Assertions are done via standard if statement syntax. Simply include the condition clause but nothing else. | |||
Ex: | Ex: | ||
Line 73: | Line 91: | ||
If any of these checks were to fail, then the test itself would stop on the given line and return a failure. | If any of these checks were to fail, then the test itself would stop on the given line and return a failure. | ||
To check a status code of a function, we can use the '''run''' command: | |||
# Run function. | |||
run <my_function> | |||
# Check output. Assert was not 0 for function failure. | |||
[[ "${status}" != 1 ]] |
Latest revision as of 23:05, 25 October 2020
For UnitTesting in bash, use Bats.
Bats is a Bash UnitTesting framework, that's installed into the system PATH via NPM.
Installing Bats
With NPM installed, run:
sudo npm install -g bats
See https://github.com/bats-core/bats-core for alternative install methods.
Using Bats
From what I've seen, documentation on the web is inconsistent in regards to calling bats, so I document here what I found to work best for me:
1) Create a new test script in your project. Maybe something like <project_root>/tests/test.sh
2) Add execution permissions to this test script.
chmod +x <project_root>/tests/test.sh
3) In the first line of the script, prefix it with the standard #!/usr/bin/env bash
header.
4) As the very first line of code to execute, set the command:
cd "$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
This will set the scripts internal directory to the folder it exists in, regardless of where the terminal is upon calling it.
5) At this point, create one or more separate test files, group related tests together. Call these subfiles them from your main tests.sh
file via the command:
bats <test_file_to_call>
If done correctly, all tests in that file should execute. Repeat for every test file you wish to run.
For added clarification, add echo statements between file imports, in order to visually split up test output.
Functions
To initialize functions that run once before all tests and after all tests:
### # This will run once, before any tests execute. ## setup_file () { # Setup logic here. } ### # This will run once, after all tests execute. ## teardown_file () { # Teardown logic here. }
To initialize functions that run at the start and end of every test with:
### # This will run at the start of every test. ## setup () { # Setup logic here. } ### # This will run at the end of every test. ## teardown () { # Teardown logic here. }
Create actual tests with:
@test "<name_of_test>" { # Test logic here. }
Assertions
Assertions are done via standard if statement syntax. Simply include the condition clause but nothing else.
Ex:
# Check if ${my_var} is equal to 5. [[ ${my_var} == 5 ]] # Check if ${my_var} does not match the string "This is a string." [[ ${my_var} != "This is a string." ]] # Check if ${some_number} is greater than 5. [[ ${some_number} > 5 ]]
If any of these checks were to fail, then the test itself would stop on the given line and return a failure.
To check a status code of a function, we can use the run command:
# Run function. run <my_function> # Check output. Assert was not 0 for function failure. [[ "${status}" != 1 ]]