Note#
Our team is equally versed at using the Windows CMD scripts as we are using Bash
scripts. For convenience, the following examples will refer to the ptest.sh Bash
script for executing a series of tests and observing the changes in the summary
information. Those references to ptest.sh can easily be replaced with the
ptest.cmd scripts with no issues.
Using This Project On Itself - Setup#
For the Project Summarizer project itself, there is a ptest.sh script that allows
for various modes to be used in executing PyTest against the project. These different
modes allow for more focused testing depending on the needs of the developer at
the time. Those different modes use environment variables to specify how to execute
PyTest, and for the purpose of this documentation, those variables are ignored to
supply a clearer picture of how the Project Summarizer tool works.
Focusing explicitly on executing PyTest, either pytest_args (Bash) or
PYTEST_ARGS (Cmd) are set to:
--timeout=10 -ra --strict-markers --junitxml=report/tests.xml --html=report/report.html
When testing with code coverage applied, the following text is appended to the contents of that variable:
--cov --cov-branch --cov-report xml:report/coverage.xml --cov-report html:report/coverage
As the project uses PipEnv, when the tests are executed, they are effectively executed with the following command line:
pipenv run pytest ${pytest_args}
or
pipenv run pytest %PYTEST_ARGS%
The important parts here are the --junitxml argument and the --cov-report xml:
arguments passed to PyTest. The first argument specifies the location where the
JUnit compatible report of test results will be written. The second argument specifies
the location where the Cobertura compatible report of test coverage will be written.
Using This Project On Itself - Adding In Project Summarizer#
Given that setup, adding in the Project Summarizer to the ptest.sh script is
easy. As code coverage can sometimes slow test execution, the following function
controls the execution of the tool:
summarize_test_executions() {
# Determine if we report on the tests, or tests + coverage.
PYSCAN_REPORT_OPTIONS=(--junit "${TEST_RESULTS_XML_PATH}")
if [[ ${COVERAGE_MODE} -ne 0 ]]; then
if [[ ${TEST_EXECUTION_SUCCEEDED} -ne 0 ]]; then
PYSCAN_REPORT_OPTIONS+=(--cobertura "${TEST_COVERAGE_XML_PATH}")
else
echo "{Coverage was specified, but one or more tests failed. Skipping reporting of coverage.}"
fi
fi
echo "{Summarizing changes in execution of full test suite.}"
if ! pipenv run ${PYSCAN_SCRIPT_PATH} ${PYSCAN_OPTIONS} "${PYSCAN_REPORT_OPTIONS[@]}"; then
echo ""
complete_process 1 "{Summarizing changes in execution of full test suite failed.}"
fi
}
As the summarizer is being used in the same project as it is created in, the
PYSCAN_SCRIPT_PATH variable is set to point to the project's main.py module.
Normally, that value would be the name of the Python package project_summarizer.
The PYSCAN_OPTIONS variable holds the --only-changes argument by default but
can be turned off if desired. The TEST_RESULTS_XML_PATH variable is set to
report\tests.xml to correspond with the --junitxml=report/tests.xml argument
passed to PyTest. The TEST_COVERAGE_XML_PATH variable is set to report\coverage.xml
to match the --cov-report xml:report/coverage.xml argument passed to PyTest.
Because our team wanted publishing summaries to be a function of testing, there
is an alternate flow in the ptest.sh script that published the summaries.
This is easy accomplished by invoking the summarizer with only the --publish argument.
Using This Project On Itself - Generating The Above Samples#
All the samples in the Sample Output section
are generated using the ptest.sh script with the Project Summarizer tool added
in.
- used as part of the normal development process,
ptest.sh --publishwas previously invoked to benchmark the summaries for the last commit- this effectively invoked
project_summarizer --publish
- this effectively invoked
ptest.sh -c -fwas invoked to run tests with coverage and supply the Full Output sample- this ran PyTest with coverage enabled, and effectively invoked
project_summarizer --junit report\tests.xml --cobertura report\coverage.xml
- this ran PyTest with coverage enabled, and effectively invoked
ptest.sh -cwas invoked to run tests with coverage and present the No Change sample- this ran PyTest with coverage enabled, and effectively invoked
project_summarizer --only-changes --junit report\tests.xml --cobertura report\coverage.xml
- this ran PyTest with coverage enabled, and effectively invoked
ptest.sh -cwas invoked to run tests with coverage and present the Expected Change sample- same as above, but with the test "missing", it reported that test as not being executed and reported the coverage that was missing
Advanced Features#
Quiet Mode and Output Character Columns#
After use in different real-world scenarios, the ability to maintain better control
on the report output became more apparent. To that extent, two new arguments were
added to the command line: --quiet and --columns. The --quiet argument instructs
the report summarizers to only generate their output files, and not to generate
any console output. This feature is useful on servers where the tool is still executed
to keep things coordinated with developer workflows, but the console output is not
important. In those cases where the output on servers is relevant, the --columns
argument is useful in specifying the number of character columns to use for the
output. The integer value passed after the --columns argument is passed to the
table formatting package that is suggested for plugins: columnar. In the past,
when the tool has been run on server environments, there have been situations where
the columnar package's determination of number of output columns has been wrong
or had returned 0. By using this setting, those situations can be sidestepped
by hardwiring the number of columns from the command line.
Setting The Reporting and Publishing Directories#
As mentioned above, the report directory is used to generate summary reports in,
and those reports can then be published into the publish directory. If different
names are wanted for these two directories, they can be set with the --report-dir
argument and the --publish-dir argument. Note that the report directory, either
the default report or the value supplied with the --report-dir argument, must
exist before this tool is called. However, the publish directory, either the default
publish or the value supplied with the --publish-dir argument, will be created
if it does not exist.