Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add time measure to JUnit XML reports #180

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
153 changes: 151 additions & 2 deletions shunit2
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,129 @@ if ${__SHUNIT_BUILTIN} [ "`echo -e test`" = '-e test' ]; then
__SHUNIT_CMD_ECHO_ESC='echo'
fi

# Determine if `date` supports nanosecond resolution.
__SHUNIT_CMD_DATE_SECONDS='date +%s.%N'
if ${__SHUNIT_BUILTIN} [ "`date +%N`" = '%N' ]; then
__SHUNIT_CMD_DATE_SECONDS='date +%s'
fi

# Determine `bc` command.
__SHUNIT_CMD_BC='bc'
if ! (${__SHUNIT_CMD_BC} --help >/dev/null 2>&1); then
__SHUNIT_CMD_BC='busybox bc'
fi
if ! (${__SHUNIT_CMD_BC} --help >/dev/null 2>&1); then
__SHUNIT_CMD_BC=''
fi

# Determine `dc` command.
__SHUNIT_CMD_DC='dc'
if ! (${__SHUNIT_CMD_DC} --help >/dev/null 2>&1); then
__SHUNIT_CMD_DC='busybox dc'
fi
if ! (${__SHUNIT_CMD_DC} --help >/dev/null 2>&1); then
__SHUNIT_CMD_DC=''
fi

# Format float numbers to the single style from different tools.
# Args:
# num: string: float number to format
# Returns:
# string: formatted number. Empty string if error occurs.
_shunit_float_format() {
# Double-dot number is an error.
# No need to format if the number is an integer.
case "${1}" in
*.*.*)
return
;;
*.*)
;;
*)
echo "${1}"
return
;;
esac

_shunit_format_result_="$1"

# Add leading zero if needed.
_shunit_format_result_="$(echo "${_shunit_format_result_}" \
|command sed 's/^\./0./g')"

# Remove trailing zeros.
_shunit_format_result_="$(echo "${_shunit_format_result_}" \
|command sed 's/0\+$//g')"

# Remove trailing dot.
_shunit_format_result_="$(echo "${_shunit_format_result_}" \
|command sed 's/\.$//g')"

# Print the result.
echo "${_shunit_format_result_}"
unset _shunit_format_result_
}

# Calculate numbers using bc.
# Args:
# left: string: left operand (may be float point)
# operation: string: operation (+ - * /)
# right: string: right operand (may be float point)
# Returns:
# string: result
_shunit_calc_bc() {
_shunit_output_="$(echo "$@" \
|command ${__SHUNIT_CMD_BC:?})"
shunit_return=$?
if ${__SHUNIT_BUILTIN} [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then
_shunit_float_format "${_shunit_output_}"
shunit_return=$?
fi

unset _shunit_output_
return ${shunit_return}
}

# Calculate numbers using dc.
# Args:
# left: string: left operand (may be float point)
# operation: string: operation (+ - * /)
# right: string: right operand (may be float point)
# Returns:
# string: result
_shunit_calc_dc() {
_shunit_output_="$(echo "$1" "$3" "$2" "p" \
|command ${__SHUNIT_CMD_DC:?})"
shunit_return=$?
if ${__SHUNIT_BUILTIN} [ ${shunit_return} -eq ${SHUNIT_TRUE} ]; then
_shunit_float_format "${_shunit_output_}"
shunit_return=$?
fi

unset _shunit_output_
return ${shunit_return}
}

# Calculate numbers using expr.
# Args:
# left: string: left integer number operand
# operation: string: operation (+ - * /)
# right: string: right integer number operand
# Returns:
# string: result. Empty string if error occurs.
_shunit_calc_expr() {
expr "$@" 2>/dev/null || ${__SHUNIT_BUILTIN} true
}

# Determine what command to use for calculating numbers.
__SHUNIT_CMD_CALC='_shunit_calc_bc'
if ! ("${__SHUNIT_CMD_CALC}" 1 + 2 >/dev/null 2>&1); then
__SHUNIT_CMD_CALC=_shunit_calc_dc
fi
if ! ("${__SHUNIT_CMD_CALC}" 1 + 2 >/dev/null 2>&1); then
__SHUNIT_CMD_CALC=_shunit_calc_expr
fi

# Commands a user can override if needed.
__SHUNIT_CMD_TPUT='tput'
SHUNIT_CMD_TPUT=${SHUNIT_CMD_TPUT:-${__SHUNIT_CMD_TPUT}}
Expand Down Expand Up @@ -89,6 +212,12 @@ __shunit_junitXmlOutputFile='' # File to use for JUnit XML output in addition t
__shunit_junitXmlTestCases='' # Test cases info in the JUnit XML format for output
__shunit_junitXmlCurrentTestCaseErrors='' # Current test case error info in the JUnit XML format for output

# Time variables
__shunit_startSuiteTime='' # When the suite execution was started
__shunit_endSuiteTime='' # When the suite execution ended
__shunit_startCaseTime='' # When the case execution was started
__shunit_endCaseTime='' # When the case execution ended

# ANSI colors (populated by _shunit_configureColor()).
__shunit_ansi_none=''
__shunit_ansi_red=''
Expand Down Expand Up @@ -1032,8 +1161,10 @@ _shunit_cleanup() {
__shunit_clean=${SHUNIT_TRUE}

tearDown || _shunit_warn 'tearDown() returned non-zero return code.'
__shunit_endCaseTime=`${__SHUNIT_CMD_DATE_SECONDS}`
oneTimeTearDown || \
_shunit_warn 'oneTimeTearDown() returned non-zero return code.'
__shunit_endSuiteTime=`${__SHUNIT_CMD_DATE_SECONDS}`

command rm -fr "${__shunit_tmpDir}"
fi
Expand Down Expand Up @@ -1114,6 +1245,8 @@ _shunit_execSuite() {
# Disable skipping.
endSkipping

__shunit_startCaseTime=`${__SHUNIT_CMD_DATE_SECONDS}`

# Execute the per-test setUp() function.
if ! setUp; then
_shunit_fatal "setUp() returned non-zero return code."
Expand All @@ -1131,12 +1264,16 @@ _shunit_execSuite() {
if ! tearDown; then
_shunit_fatal "tearDown() returned non-zero return code."
fi
__shunit_endCaseTime=`${__SHUNIT_CMD_DATE_SECONDS}`

_shunit_test_execution_time_=`"${__SHUNIT_CMD_CALC}" "${__shunit_endCaseTime}" - "${__shunit_startCaseTime}"`

# Store current test case info in JUnit XML.
__shunit_junitXmlTestCases="${__shunit_junitXmlTestCases}
<testcase
classname=\"${__shunit_xmlSuiteName}\"
name=\"${_shunit_test_}\"
${_shunit_test_execution_time_:+"time=\"${_shunit_test_execution_time_}\""}
assertions=\"${__shunit_assertsCurrentTest}\"
>${__shunit_junitXmlCurrentTestCaseErrors}
</testcase>"
Expand All @@ -1149,7 +1286,7 @@ _shunit_execSuite() {
fi
done

unset _shunit_test_
unset _shunit_test_ _shunit_test_execution_time_
}

# Generates the user friendly report with appropriate OK/FAILED message.
Expand Down Expand Up @@ -1179,11 +1316,19 @@ _shunit_generateReport() {
fi

if ${__SHUNIT_BUILTIN} [ -n "${__shunit_junitXmlOutputFile}" ]; then
# Calculate total execution time in seconds.
_shunit_suite_execution_time_=`"${__SHUNIT_CMD_CALC}" "${__shunit_endSuiteTime}" - "${__shunit_startSuiteTime}"`

# Generate a ISO-8601 compliant date.
_shunit_suite_start_time_preformatted_=`date -u '+%Y-%m-%dT%H:%M:%S%z' -d "@${__shunit_startSuiteTime}"`

echo "<?xml version=\"1.0\" encoding=\"UTF-8\"?>
<testsuite
failures=\"${__shunit_testsFailed}\"
name=\"${__shunit_xmlSuiteName}\"
tests=\"${__shunit_testsTotal}\"
timestamp=\"${_shunit_suite_start_time_preformatted_}\"
${_shunit_suite_execution_time_:+"time=\"${_shunit_suite_execution_time_}\""}
assertions=\"${__shunit_assertsTotal}\"
>${__shunit_junitXmlTestCases}
</testsuite>" > "${__shunit_junitXmlOutputFile}"
Expand All @@ -1209,7 +1354,7 @@ _shunit_generateReport() {
${__SHUNIT_CMD_ECHO_ESC} "${_shunit_msg_}"
__shunit_reportGenerated=${SHUNIT_TRUE}

unset _shunit_msg_ _shunit_ok_
unset _shunit_msg_ _shunit_ok_ _shunit_suite_execution_time_ _shunit_suite_start_time_preformatted_
}

# Test for whether a function should be skipped.
Expand Down Expand Up @@ -1390,6 +1535,8 @@ fi
# Configure default output coloring behavior.
_shunit_configureColor "${SHUNIT_COLOR}"

__shunit_startSuiteTime=`${__SHUNIT_CMD_DATE_SECONDS}`

# Execute the oneTimeSetUp function (if it exists).
if ! oneTimeSetUp; then
_shunit_fatal "oneTimeSetUp() returned non-zero return code."
Expand Down Expand Up @@ -1455,6 +1602,8 @@ if ! oneTimeTearDown; then
_shunit_fatal "oneTimeTearDown() returned non-zero return code."
fi

__shunit_endSuiteTime=`${__SHUNIT_CMD_DATE_SECONDS}`

# Generate a report summary.
_shunit_generateReport

Expand Down
113 changes: 113 additions & 0 deletions shunit2_tools_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
#!/bin/sh
# vim:et:ft=sh:sts=2:sw=2
#
# shunit2 unit test for tools testing.
#
# Copyright 2023 AxxonSoft. All Rights Reserved.
# Released under the Apache 2.0 license.
# http://www.apache.org/licenses/LICENSE-2.0
#
# https://github.com/kward/shunit2
#
# Disable source following.
# shellcheck disable=SC1090,SC1091

# Load test helpers.
. ./shunit2_test_helpers

# Run integer calculation checks.
# Arguments:
# funcName: string: name of function to call as a calculator.
commonCalcInteger() {
_common_function="$1"

assertEquals "3" "$("${_common_function}" 1 + 2)"
assertEquals "42" "$("${_common_function}" 0 + 42)"
assertEquals "-42" "$("${_common_function}" 0 - 42)"
assertEquals "78" "$("${_common_function}" 123 - 45)"
assertEquals "0" "$("${_common_function}" 1 - 1)"
}

# Run float calculation checks.
# Arguments:
# funcName: string: name of function to call as a calculator.
commonCalcFloat() {
_common_function="$1"

assertEquals "3" "$("${_common_function}" 1.0 + 2.0)"
assertEquals "42" "$("${_common_function}" 0.000 + 42.0)"
assertEquals "-42" "$("${_common_function}" 0 - 42.0)"
assertEquals "78" "$("${_common_function}" 123 - 45.00)"
assertEquals "0" "$("${_common_function}" 1.0 - 1.0)"
assertEquals "0" "$("${_common_function}" 1.0 - 1.00)"

assertEquals "4.6" "$("${_common_function}" 1.2 + 3.4)"
assertEquals "5.1" "$("${_common_function}" 1.2 + 3.9)"
assertEquals "-2.9005" "$("${_common_function}" 1 - 3.9005)"
assertEquals "7.905" "$("${_common_function}" 11.005 - 3.1)"
assertEquals "0.01" "$("${_common_function}" 0.085 - 0.075)"
}

testFloatFormat() {
# Bad values.
assertEquals '' "$(_shunit_float_format ..)"
assertEquals '' "$(_shunit_float_format 0.1.2)"
assertEquals '' "$(_shunit_float_format 0...)"
assertEquals '' "$(_shunit_float_format 123.123.123)"
assertEquals '' "$(_shunit_float_format 123.123.123.)"

# Good values (unusual cases).
assertEquals '0' "$(_shunit_float_format .)"

# Good values (integer).
assertEquals '1' "$(_shunit_float_format 1)"
assertEquals '10' "$(_shunit_float_format 10)"
assertEquals '2300' "$(_shunit_float_format 2300)"

# Good values (float).
assertEquals '1' "$(_shunit_float_format 1.)"
assertEquals '10' "$(_shunit_float_format 10.)"
assertEquals '2300' "$(_shunit_float_format 2300.)"
assertEquals '1' "$(_shunit_float_format 1.0)"
assertEquals '10' "$(_shunit_float_format 10.0)"
assertEquals '2300' "$(_shunit_float_format 2300.000)"
assertEquals '0' "$(_shunit_float_format .000)"
assertEquals '1.2' "$(_shunit_float_format 1.2)"
assertEquals '4.3' "$(_shunit_float_format 4.30)"
assertEquals '0.3' "$(_shunit_float_format .30)"
assertEquals '0.7' "$(_shunit_float_format .7)"
assertEquals '1.08' "$(_shunit_float_format 1.080)"
}

testCalcDc() {
if [ -z "${__SHUNIT_CMD_DC}" ]; then
# shellcheck disable=SC2016
startSkipping '`dc` not found'
fi

commonCalcInteger "_shunit_calc_dc"
commonCalcFloat "_shunit_calc_dc"
}

testCalcBc() {
if [ -z "${__SHUNIT_CMD_BC}" ]; then
# shellcheck disable=SC2016
startSkipping '`bc` not found'
fi

commonCalcInteger "_shunit_calc_bc"
commonCalcFloat "_shunit_calc_bc"
}

testCalcExpr() {
commonCalcInteger "_shunit_calc_expr"
}

oneTimeSetUp() {
th_oneTimeSetUp
}

# Load and run shunit2.
# shellcheck disable=SC2034
[ -n "${ZSH_VERSION:-}" ] && SHUNIT_PARENT=$0
. "${TH_SHUNIT}"
Loading