commit 4d666eacaf8ddbdceb029c711870a63568e894da Author: Jim Myhrberg Date: Mon May 26 12:52:06 2014 +0100 Initial commit diff --git a/README.md b/README.md new file mode 100644 index 0000000..6c0c0ca --- /dev/null +++ b/README.md @@ -0,0 +1,105 @@ +# test-runner.sh + +Simple helper script to easily run tests for shell scripts or other languages. + + +## Test Files + +For your test files to compatible with test-runner.sh they need to adhere to +three rules: + +1. Be executable (`chmod +x`), and assume it is being executed from within the + directory it resides in. +2. Have a file name matching `test/**/*.test.sh` (configurable). +3. Return a non-zero exit status on failure, and a `0` exit status on success. + +Test frameworks, helpers, libraries or other things is up to the test writer, +and not something that test-runner.sh cares about. + + +## Setup + +If you've already got a Makefile in your project, you could simply do +something like the following: + +```Makefile +test: test-runner.sh + ./test-runner.sh + +clean: remove-test-runner.sh + +test-runner.sh: + test -f "test-runner.sh" || \ + echo "fetching test-runner.sh..." && \ + curl -s -L -o test-runner.sh \ + https://github.com/jimeh/test-runner.sh/raw/master/test-runner.sh && \ + chmod +x test-runner.sh + +remove-test-runner.sh: + ( \ + test -f "test-runner.sh" && rm "test-runner.sh" && \ + echo "removed test-runner.sh"\ + ) || exit 0 + +update-test-runner.sh: remove-test-runner.sh test-runner.sh +``` + +**Note:** To version lock `test-runner.sh` you will want to fetch it from a +specific release tag instead of the master branch. + + +## Usage + +Without any arguments the `test` directory will be recursively searched for +any files who's filename ends in `.test.sh` and executed without any +arguments. + +To run specific test files, simply pass them in as arguments: + + ./test-runner.sh test/foo.test.sh test/bar.test.sh + +To pass custom arguments to test files, pass `--` followed by your arguments: + + ./test-runner.sh test/foo.test.sh test/bar.test.sh -- --verbose + +This will execute `./foo.test.sh --verbose` and `./bar.test.sh --verbose` from +withing the `test` directory. + +And to pass custom arguments too all test files: + + ./test-runner.sh -- --verbose + + +## Configuration + +Configuration is done via environment variables: + +- `TEST_DIR`: Name of directory to recursively look for test files + in. (default: `test`) +- `TEST_RUNNER_PATTERN`: Test files' file name must end in specified + pattern. (default: `.test.sh`) + + +## License + +(The MIT license) + +Copyright (c) 2014 Jim Myhrberg. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/test-runner.sh b/test-runner.sh new file mode 100755 index 0000000..2d4976f --- /dev/null +++ b/test-runner.sh @@ -0,0 +1,143 @@ +#! /usr/bin/env bash +# +# test-runner.sh 0.0.0 - easily run generic self-executable test files. +# https://github.com/jimeh/test-runner.sh +# +# (The MIT License) +# +# Copyright (c) 2014 Jim Myhrberg. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to +# deal in the Software without restriction, including without limitation the +# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +# sell copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. +# + + + +# +# Configuration. +# + +if [ -z "$TEST_RUNNER_DIR" ]; then + TEST_DIR="test" +fi + +if [ -z "$TEST_RUNNER_PATTERN" ]; then + TEST_RUNNER_PATTERN=".test.sh" +fi + + +# +# Helper functions. +# + +resolve_link() { + $(type -p greadlink readlink | head -1) $1 +} + +abs_dirname() { + local cwd="$(pwd)" + local path="$1" + + while [ -n "$path" ]; do + cd "${path%/*}" + local name="${path##*/}" + path="$(resolve_link "$name" || true)" + done + + pwd + cd "$cwd" +} + + +# +# Argument parsing. +# + +testfiles=() +testargs="" + +if [ $# -gt 0 ]; then + capture_args=0 + for arg in $@; do + if [ "$arg" == "--" ]; then + capture_args=1 + elif [ "$capture_args" == "0" ]; then + testfiles+=("$arg") + elif [ "$capture_args" == "1" ]; then + if [ -n "$testargs" ]; then testargs+=" "; fi + testargs+="$arg" + fi + done +fi + + +# +# Internal setup. +# + +testdir="$(abs_dirname "$0")/${TEST_DIR}" + +if [ -z "$testfiles" ]; then + testfiles="$(find "$testdir" -name "*${TEST_RUNNER_PATTERN}")" +fi + + +# +# Run tests. +# + +success_count=0 +fail_count=0 + +cwd="$(pwd)" +for testfile in ${testfiles[@]}; do + echo "" + echo -en "$(tput setaf 5)running: " + echo -e "$(tput setaf 6)${testfile/#$(dirname "$testdir")\//}$(tput sgr0)" + cd "$(dirname "$testfile")" + "./$(basename "$testfile")" ${testargs[@]} + if [ "$?" == "0" ]; then + ((success_count++)) + else + ((fail_count++)) + fi + cd "$cwd" +done +echo "" + + +# +# Print summary and exit. +# + +if [ "$fail_count" == "0" ]; then + echo -n "$(tput setaf 2)PASSED:$(tput sgr0) " +else + echo -n "$(tput setaf 1)FAILED:$(tput sgr0) " +fi + +if [ "$fail_count" != "0" ]; then + if [ "$fail_count" != "1" ]; then fail_plurar="s"; fi + echo -n "$(tput setaf 1)${fail_count} test file${fail_plurar}" \ + "failed.$(tput sgr0) " +fi + +if [ "$success_count" != "1" ]; then success_plurar="s"; fi +echo "$(tput setaf 2)${success_count} test file${success_plurar}" \ + "passed.$(tput sgr0)" +exit $fail_count