Replace run_tests bash script with xsh script.

This replaces the bash script I originally proposed as a way to safely invoke
unit tests with a xonsh script (we need to eat our own dog food). This also
udpates the documentation.
This commit is contained in:
Kurtis Rader 2015-11-14 19:20:00 -08:00
parent 333468d719
commit 40034d7315
5 changed files with 134 additions and 38 deletions

View file

@ -1,5 +1,7 @@
SHELL = /bin/sh
which = edited # which tests to run
all:
@echo "You must specifiy a make target."
@echo "Targets are:"
@ -32,13 +34,14 @@ lint-all:
# Test just the changed python files. It doesn't matter if "git add" has
# already been done but obviously if you've already done "git commit" then
# they're no longer consider changed. This should be run (along with "make
# lint") before commiting a set of changes.
# lint") before commiting a set of changes. You can also pass a list of test
# names via a "which=name1 name2..." argument.
test:
scripts/run_tests.sh -e
scripts/run_tests.xsh $(which)
# Test all the python files.
test-all:
scripts/run_tests.sh
scripts/run_tests.xsh all
# Build the parser_table.py module. This is normally done by setup.py at
# install time. This just makes it easy to create the parser module on the fly

View file

@ -61,22 +61,66 @@ is open to interpretation.
unittest directly or write tests in an object-oriented style.
* Test generators make more dots and the dots must flow!
You can easily check for style issues, including some outright bugs such
as mispelled variable names, using pylint. If you're using Anaconda you'll
need to run "conda install pylint" once. You can easily run pylint on
the edited files in your uncommited git change:
$ make lint
If you want to lint the entire code base run:
$ make lint-all
How to Test
================
First, install nose: http://nose.readthedocs.org/en/latest/
First, install nose: http://nose.readthedocs.org/en/latest/. Second, ensure
your cwd is the root directory of the project (i.e., the one containing the
.git directory).
To perform all unit tests::
$ cd tests/
$ nosetests
$ make test-all
This will recursively look through the currently directory, open up every file
named test_* and run every function (or method) named test_*.
Or, if you want to do it the hard way:
Nosetests can also take file(s) as an argument. For example, to run just the
lexer and parser module tests::
$ scripts/run-tests.xsh
$ nosetests test_lexer.py test_parser.py
Or, if you want to do it the really hard way:
$ python3 -c 'import setup; setup.build_tables()'
$ XONSHRC='' nosetests
If you're working on a change and haven't yet commited it you can run the
associated tests with:
$ make test
If you want to run specific tests you can specify the test names. For example
to run test_parser:
$ python3 -c 'import setup; setup.build_tables()'
$ XONSHRC='' nosetests tests/test_parser.py
If you want to run specific tests you can pass the test name to the
scripts/run_tests.xsh script. The test name can be the bare test name
(e.g., ``aliases``), include the ``test_`` prefix and ``.py`` suffix
without the directory (e.g., ``test_aliases.py``), or the complete relative
path (e.g., ``tests/test_aliases.py``). For example:
$ make test which=aliases
Or by invoking the run_tests script directly:
$ scripts/run_tests.xsh aliases
Note that you can pass multiple test names in the above examples:
$ make test which='aliases environ'
Or:
$ scripts/run_tests.xsh aliases environ
Happy testing!
@ -247,7 +291,10 @@ When releasing xonsh, make sure to do the following items in order:
--------------------
Maintenance Tasks
--------------------
None currently.
You can cleanup your local repository of transient files such as \*.pyc files
created by unit testing by running:
$ make clean
-----------------------
Performing the Release

View file

@ -230,7 +230,8 @@ Xonsh currently has the following external dependencies,
*Documentation:*
#. Sphinx
#. `Sphinx <http://sphinx-doc.org/>` (which uses
`reStructuredText <http://sphinx-doc.org/rest.html>`)
#. Numpydoc
#. Cloud Sphinx Theme

View file

@ -1,25 +0,0 @@
#!/bin/sh
#
# Run all the nosetests or just the ones relevant for the edited files.
#
make build-tables # ensure lexer/parser table module is up to date
if [[ $1 == "-e" ]]; then
tmp_file=$(mktemp /tmp/nose_tests_XXXXXX)
git status -s |
awk '/\.py$/ { print $2 }' |
while read f; do
if [[ $f == xonsh/* ]]; then
f="tests/test_$(basename $f)"
if [[ -f $f ]]; then
echo $f
fi
else
echo $f
fi
done |
sort -u > $tmp_file
XONSHRC=/dev/null nosetests -v $(< $tmp_file)
rm $tmp_file
else
XONSHRC=/dev/null nosetests
fi

70
scripts/run_tests.xsh Executable file
View file

@ -0,0 +1,70 @@
#!/usr/bin/env xonsh --no-rc
#
# Run all the nosetests or just the ones relevant for the edited files in the
# current uncommited git change or just the ones named on the command line.
# Your cwd must be the top of the project tree.
#
# Usage:
# run_tests.xsh [edited | all | list of test names]
#
# You can omit the "all" argument if you want all tests run.
#
import os.path
import sys
if not os.path.isdir('.git'):
print('No .git directory. The cwd must be the top of the project tree.',
file=sys.stderr)
sys.exit(1)
if len($ARGS) == 1:
# Run all tests.
$[make build-tables] # ensure lexer/parser table module is up to date
$[env XONSHRC='' nosetests]
elif len($ARGS) == 2 and $ARG1 == 'all':
# Run all tests.
$[make build-tables] # ensure lexer/parser table module is up to date
$[env XONSHRC='' nosetests]
elif len($ARGS) == 2 and $ARG1 == 'edited':
# Run just the tests for the files edited in the uncommited change.
tests = set()
for edited_fname in $(git status -s).split():
if not edited_fname.endswith('.py'):
continue
if edited_fname.startswith('xonsh/'):
test_fname = 'tests/test_' + edited_fname[len('xonsh/')]
if os.path.exists(test_fname):
tests.add(test_fname)
elif edited_fname.startswith('tests/'):
tests.add(test_fname)
else:
print('Ignoring file because I cannot find a test for: {!r}.'.
format(edited_fname), file=sys.stderr)
if tests:
$[make build-tables] # ensure lexer/parser table module is up to date
$[env XONSHRC='' nosetests -v @(sorted(tests))]
else:
print('Cannot find any tests in the pending changes.', file=sys.stderr)
else:
# Run the named tests.
tests = set()
for test_fname in $ARGS[1:]:
if not test_fname.startswith('tests/'):
if not test_fname.startswith('test_'):
test_fname = 'tests/test_' + test_fname
if not test_fname.endswith('.py'):
test_fname += '.py'
if os.path.exists(test_fname):
tests.add(test_fname)
else:
print('Cannot find test module {!r}; ignoring the argument.'.
format(test_fname), file=sys.stderr)
if tests:
$[make build-tables] # ensure lexer/parser table module is up to date
$[env XONSHRC='' nosetests -v @(sorted(tests))]
else:
print('Cannot find any tests matching {}.'.format($ARGS[1:]),
file=sys.stderr)
sys.exit(1)