Skip to content

Commit

Permalink
[MRG] Make tests runnable with pytest without error (scikit-learn#8246)
Browse files Browse the repository at this point in the history
* Make tests runnable with pytest without error.

Errors were due to pytest quirks with (deprecated) yield support.

* Add pytest build on Travis

and tweak pytest settings in setup.cfg

* Tweak comment
  • Loading branch information
lesteve authored and ogrisel committed Feb 20, 2017
1 parent 41200e1 commit 0ec6664
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 50 deletions.
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ env:
- DISTRIB="conda" PYTHON_VERSION="3.6" INSTALL_MKL="true"
NUMPY_VERSION="1.11.2" SCIPY_VERSION="0.18.1" PANDAS_VERSION="0.19.1"
CYTHON_VERSION="0.25.2"
# This environment use pytest to run the tests. It uses the newest
# supported anaconda env. It also runs tests requiring Pandas.
- USE_PYTEST="true" DISTRIB="conda" PYTHON_VERSION="3.6" INSTALL_MKL="true"
NUMPY_VERSION="1.11.2" SCIPY_VERSION="0.18.1" PANDAS_VERSION="0.19.1"
CYTHON_VERSION="0.25.2"
# flake8 linting on diff wrt common ancestor with upstream/master
- RUN_FLAKE8="true" SKIP_TESTS="true"
DISTRIB="conda" PYTHON_VERSION="3.5" INSTALL_MKL="true"
Expand Down
4 changes: 2 additions & 2 deletions build_tools/travis/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,13 @@ if [[ "$DISTRIB" == "conda" ]]; then
# Configure the conda environment and put it in the path using the
# provided versions
if [[ "$INSTALL_MKL" == "true" ]]; then
conda create -n testenv --yes python=$PYTHON_VERSION pip nose \
conda create -n testenv --yes python=$PYTHON_VERSION pip nose pytest \
numpy=$NUMPY_VERSION scipy=$SCIPY_VERSION \
mkl cython=$CYTHON_VERSION \
${PANDAS_VERSION+pandas=$PANDAS_VERSION}

else
conda create -n testenv --yes python=$PYTHON_VERSION pip nose \
conda create -n testenv --yes python=$PYTHON_VERSION pip nose pytest \
numpy=$NUMPY_VERSION scipy=$SCIPY_VERSION \
nomkl cython=$CYTHON_VERSION \
${PANDAS_VERSION+pandas=$PANDAS_VERSION}
Expand Down
10 changes: 7 additions & 3 deletions build_tools/travis/test_script.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ except ImportError:
python -c "import multiprocessing as mp; print('%d CPUs' % mp.cpu_count())"

run_tests() {
if [[ "$USE_PYTEST" == "true" ]]; then
TEST_CMD="pytest --showlocals --pyargs"
else
TEST_CMD="nosetests --with-coverage" # --with-timer --timer-top-n 20"
fi
# Get into a temp directory to run test from the installed scikit learn and
# check if we do not leave artifacts
mkdir -p $TEST_DIR
Expand All @@ -34,10 +39,9 @@ run_tests() {
export SKLEARN_SKIP_NETWORK_TESTS=1

if [[ "$COVERAGE" == "true" ]]; then
nosetests -s --with-coverage --with-timer --timer-top-n 20 sklearn
else
nosetests -s --with-timer --timer-top-n 20 sklearn
TEST_CMD="$TEST_CMD --with-coverage"
fi
$TEST_CMD sklearn

# Test doc
cd $OLDPWD
Expand Down
7 changes: 7 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ doctest-fixtures = _fixture
ignore-files=^setup\.py$
#doctest-options = +ELLIPSIS,+NORMALIZE_WHITESPACE

[tool:pytest]
# disable-pytest-warnings should be removed once we drop nose and we
# rewrite tests using yield with parametrize
addopts =
--doctest-modules
--disable-pytest-warnings

[wheelhouse_uploader]
artifact_indexes=
# OSX wheels built by travis (only for specific tags):
Expand Down
18 changes: 11 additions & 7 deletions sklearn/gaussian_process/tests/test_kernels.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,6 @@ def check_hyperparameters_equal(kernel1, kernel2):

def test_kernel_clone():
# Test that sklearn's clone works correctly on kernels.
bounds = (1e-5, 1e5)
for kernel in kernels:
kernel_cloned = clone(kernel)

Expand All @@ -209,12 +208,17 @@ def test_kernel_clone():
# Check that all hyperparameters are equal.
yield check_hyperparameters_equal, kernel, kernel_cloned

# This test is to verify that using set_params does not
# break clone on kernels.
# This used to break because in kernels such as the RBF, non-trivial
# logic that modified the length scale used to be in the constructor
# See https://github.com/scikit-learn/scikit-learn/issues/6961
# for more details.

def test_kernel_clone_after_set_params():
# This test is to verify that using set_params does not
# break clone on kernels.
# This used to break because in kernels such as the RBF, non-trivial
# logic that modified the length scale used to be in the constructor
# See https://github.com/scikit-learn/scikit-learn/issues/6961
# for more details.
bounds = (1e-5, 1e5)
for kernel in kernels:
kernel_cloned = clone(kernel)
params = kernel.get_params()
# RationalQuadratic kernel is isotropic.
isotropic_kernels = (ExpSineSquared, RationalQuadratic)
Expand Down
17 changes: 9 additions & 8 deletions sklearn/neighbors/tests/test_ball_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,14 @@ def compute_kernel_slow(Y, X, kernel, h):
raise ValueError('kernel not recognized')


def check_results(kernel, h, atol, rtol, breadth_first, bt, Y, dens_true):
dens = bt.kernel_density(Y, h, atol=atol, rtol=rtol,
kernel=kernel,
breadth_first=breadth_first)
assert_allclose(dens, dens_true,
atol=atol, rtol=max(rtol, 1e-7))


def test_ball_tree_kde(n_samples=100, n_features=3):
np.random.seed(0)
X = np.random.random((n_samples, n_features))
Expand All @@ -167,18 +175,11 @@ def test_ball_tree_kde(n_samples=100, n_features=3):
for h in [0.01, 0.1, 1]:
dens_true = compute_kernel_slow(Y, X, kernel, h)

def check_results(kernel, h, atol, rtol, breadth_first):
dens = bt.kernel_density(Y, h, atol=atol, rtol=rtol,
kernel=kernel,
breadth_first=breadth_first)
assert_allclose(dens, dens_true,
atol=atol, rtol=max(rtol, 1e-7))

for rtol in [0, 1E-5]:
for atol in [1E-6, 1E-2]:
for breadth_first in (True, False):
yield (check_results, kernel, h, atol, rtol,
breadth_first)
breadth_first, bt, Y, dens_true)


def test_gaussian_kde(n_samples=1000):
Expand Down
40 changes: 21 additions & 19 deletions sklearn/neighbors/tests/test_kd_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,28 +24,29 @@ def brute_force_neighbors(X, Y, k, metric, **kwargs):
return dist, ind


def check_neighbors(dualtree, breadth_first, k, metric, X, Y, kwargs):
kdt = KDTree(X, leaf_size=1, metric=metric, **kwargs)
dist1, ind1 = kdt.query(Y, k, dualtree=dualtree,
breadth_first=breadth_first)
dist2, ind2 = brute_force_neighbors(X, Y, k, metric, **kwargs)

# don't check indices here: if there are any duplicate distances,
# the indices may not match. Distances should not have this problem.
assert_array_almost_equal(dist1, dist2)


def test_kd_tree_query():
np.random.seed(0)
X = np.random.random((40, DIMENSION))
Y = np.random.random((10, DIMENSION))

def check_neighbors(dualtree, breadth_first, k, metric, kwargs):
kdt = KDTree(X, leaf_size=1, metric=metric, **kwargs)
dist1, ind1 = kdt.query(Y, k, dualtree=dualtree,
breadth_first=breadth_first)
dist2, ind2 = brute_force_neighbors(X, Y, k, metric, **kwargs)

# don't check indices here: if there are any duplicate distances,
# the indices may not match. Distances should not have this problem.
assert_array_almost_equal(dist1, dist2)

for (metric, kwargs) in METRICS.items():
for k in (1, 3, 5):
for dualtree in (True, False):
for breadth_first in (True, False):
yield (check_neighbors,
dualtree, breadth_first,
k, metric, kwargs)
k, metric, X, Y, kwargs)


def test_kd_tree_query_radius(n_samples=100, n_features=10):
Expand Down Expand Up @@ -107,6 +108,14 @@ def compute_kernel_slow(Y, X, kernel, h):
raise ValueError('kernel not recognized')


def check_results(kernel, h, atol, rtol, breadth_first, Y, kdt, dens_true):
dens = kdt.kernel_density(Y, h, atol=atol, rtol=rtol,
kernel=kernel,
breadth_first=breadth_first)
assert_allclose(dens, dens_true, atol=atol,
rtol=max(rtol, 1e-7))


def test_kd_tree_kde(n_samples=100, n_features=3):
np.random.seed(0)
X = np.random.random((n_samples, n_features))
Expand All @@ -118,18 +127,11 @@ def test_kd_tree_kde(n_samples=100, n_features=3):
for h in [0.01, 0.1, 1]:
dens_true = compute_kernel_slow(Y, X, kernel, h)

def check_results(kernel, h, atol, rtol, breadth_first):
dens = kdt.kernel_density(Y, h, atol=atol, rtol=rtol,
kernel=kernel,
breadth_first=breadth_first)
assert_allclose(dens, dens_true, atol=atol,
rtol=max(rtol, 1e-7))

for rtol in [0, 1E-5]:
for atol in [1E-6, 1E-2]:
for breadth_first in (True, False):
yield (check_results, kernel, h, atol, rtol,
breadth_first)
breadth_first, Y, kdt, dens_true)


def test_gaussian_kde(n_samples=1000):
Expand Down
24 changes: 13 additions & 11 deletions sklearn/neighbors/tests/test_kde.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,17 @@ def compute_kernel_slow(Y, X, kernel, h):
raise ValueError('kernel not recognized')


def check_results(kernel, bandwidth, atol, rtol, X, Y, dens_true):
kde = KernelDensity(kernel=kernel, bandwidth=bandwidth,
atol=atol, rtol=rtol)
log_dens = kde.fit(X).score_samples(Y)
assert_allclose(np.exp(log_dens), dens_true,
atol=atol, rtol=max(1E-7, rtol))
assert_allclose(np.exp(kde.score(Y)),
np.prod(dens_true),
atol=atol, rtol=max(1E-7, rtol))


def test_kernel_density(n_samples=100, n_features=3):
rng = np.random.RandomState(0)
X = rng.randn(n_samples, n_features)
Expand All @@ -39,20 +50,11 @@ def test_kernel_density(n_samples=100, n_features=3):
for bandwidth in [0.01, 0.1, 1]:
dens_true = compute_kernel_slow(Y, X, kernel, bandwidth)

def check_results(kernel, bandwidth, atol, rtol):
kde = KernelDensity(kernel=kernel, bandwidth=bandwidth,
atol=atol, rtol=rtol)
log_dens = kde.fit(X).score_samples(Y)
assert_allclose(np.exp(log_dens), dens_true,
atol=atol, rtol=max(1E-7, rtol))
assert_allclose(np.exp(kde.score(Y)),
np.prod(dens_true),
atol=atol, rtol=max(1E-7, rtol))

for rtol in [0, 1E-5]:
for atol in [1E-6, 1E-2]:
for breadth_first in (True, False):
yield (check_results, kernel, bandwidth, atol, rtol)
yield (check_results, kernel, bandwidth, atol, rtol,
X, Y, dens_true)


def test_kernel_density_sampling(n_samples=100, n_features=3):
Expand Down

0 comments on commit 0ec6664

Please sign in to comment.