-
Notifications
You must be signed in to change notification settings - Fork 1
Writing tests
Tom edited this page Aug 12, 2019
·
3 revisions
There are a few rules you must follow when writing unit tests.
Each test function must start with
Test
eg
# Treated like a unit test
function Test_A {
}
# Treated like a unit test
function TestABC {
}
# Not a unit test
function ABC {
}This way you can write helper functions eg
# ignored by the tester
function createConnection {
echo "Creating a network connection"
}
# ran by the tester
function Test_Connection {
createConnection
echo "Manipulating connection"
}
# ran by the tester
function Test_AnotherConnection {
createConnection "A parameter"
echo "Manipulating another connection"
}As you can see above test don't need to have Assertions however that defeats the purpose of unit tests. So lets include some.
-
AssertEquals- 1: string, 2: string - Checks if both string are the same -
AssertFileEquals- 1: file, 2: file - Compares 2 files to check if they are the same -
AssertContains- 1:string, 2:string - checks if the second string is inside the first string -
AssertFileContains- 1: file, 2: string - checks if the string is present in the file -
AssertExists- 1: file/directory - checks if the file or directory exists -
AssertTrue- 1: boolean statement - checks if the boolean statement evaluates to true (test fails if it is false) -
Assert- 1: state, 2: message - asserts based on the state and uses the message as data. The state is either 1 or 0. 1=> error, 0 => Pass
When even one test fails the resulting exit code will be one. Useful for testing scripts in ci/cd pipelines
Lets see an example
# special function ran before every test
# it creates 2 empty files and a file containing abc def
function setupTest {
touch empty1 empty2
cat <<EOF > full
abc def
EOF
}
# special function ran after every test
# It removes all files from the filesystem
function destroyTest {
rm empty1 empty2 full
}
# unit tests
function Test_AssertEquals {
AssertEquals "abc" "abc" # Success
AssertEquals "abc" "def" # Test failed abc doesn't equal def
}
# Test if files are equal
function Test_AssertFileEquals {
AssertFileEquals "empty1" "empty2" # Success
AssertFileEquals "empty1" "full" # Test failed both files are different
}
function Test_AssertContains {
AssertContains "abcdef" "abc" # Success
AssertContains "abcdef" "defg" # Test failed defg isn't in abcdef
}
function Test_AssertFileContains {
AssertFileContains "full" "abc" # Success
AssertFileContains "full" "ghi" # Test failed string isn't in the file
}
function Test_AssertExists {
AssertExists "empty1" # empty1 exists (it is a file)
AssertExists "." # . exists it is the current directory
AssertExists "empty3" # fails. Empty3 isn't a file or directory
}
function Test_AssertTrue {
AssertTrue [[ -f "empty1" ]] # evaluates to true so no problem
AssertTrue [[ -f "empty3" ]] # evaluates to false so test fails
}
function Test_Assert {
Assert "0" "No problem"
Assert "1" "Error happened"
}
When running the above you should see something like this
Running unit: test.shUnit
special function ran before every test
Running test: Test_AssertEquals
PASS: abc and abc are equal
ERROR: expected abc, but got def instead
Running test: Test_AssertFileEquals
PASS: Files are equal
ERROR: File empty1 and File full are not equal
Running test: Test_AssertContains
PASS: Substring abc found
ERROR: Substring defg not found in abcdef
Running test: Test_AssertFileContains
PASS: Substring found in full
ERROR: Could not find ghi in full
Running test: Test_AssertExists
PASS: empty1 exists
PASS: . exists
ERROR: empty3 is not a file/directory
Running test: Test_AssertTrue
PASS: [[ -f empty1 ]] evaluated to true
ERROR: [[ -f empty3 ]] evaluated to false
Running test: Test_Assert
PASS: No problem
ERROR: Error happened
--------------------------------------------------------
Pass: 8, Errors: 7When even one test fails the resulting exit code will be one. Useful for testing scripts in ci/cd pipelines
-
setup- runs once per file as first function -
destroy- runs once per file as last function -
setupTest- runs just before each test function -
destroyTest- runs after each test function
In the examples above you see a use-case for setupTest and destroyTest