Skip to content

Commit 1c1f273

Browse files
authored
ENH XFAIL in common tests with estimator tags (#16502)
1 parent 93776b9 commit 1c1f273

File tree

10 files changed

+50
-18
lines changed

10 files changed

+50
-18
lines changed

doc/developers/develop.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -527,6 +527,11 @@ _skip_test (default=``False``)
527527
whether to skip common tests entirely. Don't use this unless you have a
528528
*very good* reason.
529529

530+
_xfail_test (default=``False``)
531+
dictionary ``{check_name : reason}`` of common checks to mark as a
532+
known failure, with the associated reason. Don't use this unless you have a
533+
*very good* reason.
534+
530535
stateless (default=``False``)
531536
whether the estimator needs access to data for fitting. Even though an
532537
estimator is stateless, it might still need a call to ``fit`` for

doc/developers/tips.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ Other `pytest` options that may become useful include:
8686
- ``-s`` so that pytest does not capture the output of ``print()``
8787
statements
8888
- ``--tb=short`` or ``--tb=line`` to control the length of the logs
89+
- ``--runxfail`` also run tests marked as a known failure (XFAIL) and report
90+
errors.
8991

9092
Since our continuous integration tests will error if
9193
``FutureWarning`` isn't properly caught,

setup.cfg

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ addopts =
1313
--ignore maint_tools
1414
--doctest-modules
1515
--disable-pytest-warnings
16-
-rs
16+
-rxXs
1717

1818
filterwarnings =
1919
ignore:the matrix subclass:PendingDeprecationWarning

sklearn/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
'stateless': False,
3232
'multilabel': False,
3333
'_skip_test': False,
34+
'_xfail_test': False,
3435
'multioutput_only': False,
3536
'binary_only': False,
3637
'requires_fit': True}

sklearn/decomposition/_sparse_pca.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,14 @@ def transform(self, X):
230230

231231
return U
232232

233+
def _more_tags(self):
234+
return {
235+
'_xfail_test': {
236+
"check_methods_subset_invariance":
237+
"fails for the transform method"
238+
}
239+
}
240+
233241

234242
class MiniBatchSparsePCA(SparsePCA):
235243
"""Mini-batch Sparse Principal Components Analysis

sklearn/dummy.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -354,7 +354,13 @@ def predict_log_proba(self, X):
354354
return [np.log(p) for p in proba]
355355

356356
def _more_tags(self):
357-
return {'poor_score': True, 'no_validation': True}
357+
return {
358+
'poor_score': True, 'no_validation': True,
359+
'_xfail_test': {
360+
'check_methods_subset_invariance':
361+
'fails for the predict method'
362+
}
363+
}
358364

359365
def score(self, X, y, sample_weight=None):
360366
"""Returns the mean accuracy on the given test data and labels.

sklearn/neural_network/_rbm.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -372,3 +372,11 @@ def fit(self, X, y=None):
372372
begin = end
373373

374374
return self
375+
376+
def _more_tags(self):
377+
return {
378+
'_xfail_test': {
379+
'check_methods_subset_invariance':
380+
'fails for the decision_function method'
381+
}
382+
}

sklearn/svm/_classes.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,15 @@ def __init__(self, nu=0.5, kernel='rbf', degree=3, gamma='scale',
828828
break_ties=break_ties,
829829
random_state=random_state)
830830

831+
def _more_tags(self):
832+
return {
833+
'_xfail_test': {
834+
'check_methods_subset_invariance':
835+
'fails for the decision_function method',
836+
'check_class_weight_classifiers': 'class_weight is ignored.'
837+
}
838+
}
839+
831840

832841
class SVR(RegressorMixin, BaseLibSVM):
833842
"""Epsilon-Support Vector Regression.

sklearn/tests/test_common.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
from sklearn.utils import all_estimators
2121
from sklearn.utils._testing import ignore_warnings
2222
from sklearn.exceptions import ConvergenceWarning
23-
from sklearn.utils.estimator_checks import check_estimator
23+
from sklearn.utils.estimator_checks import check_estimator, _safe_tags
2424

2525
import sklearn
2626
from sklearn.base import BiclusterMixin
@@ -87,12 +87,19 @@ def _tested_estimators():
8787

8888

8989
@parametrize_with_checks(_tested_estimators())
90-
def test_estimators(estimator, check):
90+
def test_estimators(estimator, check, request):
9191
# Common tests for estimator instances
9292
with ignore_warnings(category=(FutureWarning,
9393
ConvergenceWarning,
9494
UserWarning, FutureWarning)):
9595
_set_checking_parameters(estimator)
96+
97+
xfail_checks = _safe_tags(estimator, '_xfail_test')
98+
check_name = _set_check_estimator_ids(check)
99+
if xfail_checks:
100+
if check_name in xfail_checks:
101+
msg = xfail_checks[check_name]
102+
request.applymarker(pytest.mark.xfail(reason=msg))
96103
check(estimator)
97104

98105

sklearn/utils/estimator_checks.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,13 +1032,6 @@ def check_methods_subset_invariance(name, estimator_orig):
10321032

10331033
msg = ("{method} of {name} is not invariant when applied "
10341034
"to a subset.").format(method=method, name=name)
1035-
# TODO remove cases when corrected
1036-
if (name, method) in [('NuSVC', 'decision_function'),
1037-
('SparsePCA', 'transform'),
1038-
('MiniBatchSparsePCA', 'transform'),
1039-
('DummyClassifier', 'predict'),
1040-
('BernoulliRBM', 'score_samples')]:
1041-
raise SkipTest(msg)
10421035

10431036
if hasattr(estimator, method):
10441037
result_full, result_by_batch = _apply_on_subsets(
@@ -2243,13 +2236,6 @@ def check_regressors_no_decision_function(name, regressor_orig):
22432236

22442237
@ignore_warnings(category=FutureWarning)
22452238
def check_class_weight_classifiers(name, classifier_orig):
2246-
if name == "NuSVC":
2247-
# the sparse version has a parameter that doesn't do anything
2248-
raise SkipTest("Not testing NuSVC class weight as it is ignored.")
2249-
if name.endswith("NB"):
2250-
# NaiveBayes classifiers have a somewhat different interface.
2251-
# FIXME SOON!
2252-
raise SkipTest
22532239

22542240
if _safe_tags(classifier_orig, 'binary_only'):
22552241
problems = [2]

0 commit comments

Comments
 (0)