LSSTApplications  18.1.0
LSSTDataManagementBasePackage
Classes | Functions | Variables
lsst.utils.tests Namespace Reference

Classes

class  ExecutablesTestCase
 
class  MemoryTestCase
 
class  TestCase
 

Functions

def init ()
 
def run (suite, exit=True)
 
def sort_tests (tests)
 
def suiteClassWrapper (tests)
 
def getTempFilePath (ext, expectOutput=True)
 
def inTestCase (func)
 
def assertRaisesLsstCpp (testcase, excClass, callableObj, args, kwargs)
 
def debugger (exceptions)
 
def plotImageDiff (lhs, rhs, bad=None, diff=None, plotFileName=None)
 
def assertFloatsAlmostEqual (testCase, lhs, rhs, rtol=sys.float_info.epsilon, atol=sys.float_info.epsilon, relTo=None, printFailures=True, plotOnFailure=False, plotFileName=None, invert=False, msg=None)
 
def assertFloatsNotEqual (testCase, lhs, rhs, kwds)
 
def assertFloatsEqual (testCase, lhs, rhs, kwargs)
 
def assertClose (args, kwargs)
 
def assertNotClose (args, kwargs)
 

Variables

 psutil = None
 
 dafBase = None
 
int memId0 = 0
 
int nleakPrintMax = 20
 
 open_files = set()
 

Function Documentation

◆ assertClose()

def lsst.utils.tests.assertClose (   args,
  kwargs 
)
.. note:: Deprecated in 12_0

Definition at line 793 of file tests.py.

793 def assertClose(*args, **kwargs):
794  """.. note:: Deprecated in 12_0"""
795  warnings.warn("assertClose is deprecated; please use TestCase.assertFloatsAlmostEqual",
796  DeprecationWarning, stacklevel=2)
797  return assertFloatsAlmostEqual(*args, **kwargs)
798 
799 
800 @inTestCase
def assertClose(args, kwargs)
Definition: tests.py:793
def assertFloatsAlmostEqual(testCase, lhs, rhs, rtol=sys.float_info.epsilon, atol=sys.float_info.epsilon, relTo=None, printFailures=True, plotOnFailure=False, plotFileName=None, invert=False, msg=None)
Definition: tests.py:612

◆ assertFloatsAlmostEqual()

def lsst.utils.tests.assertFloatsAlmostEqual (   testCase,
  lhs,
  rhs,
  rtol = sys.float_info.epsilon,
  atol = sys.float_info.epsilon,
  relTo = None,
  printFailures = True,
  plotOnFailure = False,
  plotFileName = None,
  invert = False,
  msg = None 
)
Highly-configurable floating point comparisons for scalars and arrays.

The test assertion will fail if all elements ``lhs`` and ``rhs`` are not
equal to within the tolerances specified by ``rtol`` and ``atol``.
More precisely, the comparison is:

``abs(lhs - rhs) <= relTo*rtol OR abs(lhs - rhs) <= atol``

If ``rtol`` or ``atol`` is `None`, that term in the comparison is not
performed at all.

When not specified, ``relTo`` is the elementwise maximum of the absolute
values of ``lhs`` and ``rhs``.  If set manually, it should usually be set
to either ``lhs`` or ``rhs``, or a scalar value typical of what is
expected.

Parameters
----------
testCase : `unittest.TestCase`
    Instance the test is part of.
lhs : scalar or array-like
    LHS value(s) to compare; may be a scalar or array-like of any
    dimension.
rhs : scalar or array-like
    RHS value(s) to compare; may be a scalar or array-like of any
    dimension.
rtol : `float`, optional
    Relative tolerance for comparison; defaults to double-precision
    epsilon.
atol : `float`, optional
    Absolute tolerance for comparison; defaults to double-precision
    epsilon.
relTo : `float`, optional
    Value to which comparison with rtol is relative.
printFailures : `bool`, optional
    Upon failure, print all inequal elements as part of the message.
plotOnFailure : `bool`, optional
    Upon failure, plot the originals and their residual with matplotlib.
    Only 2-d arrays are supported.
plotFileName : `str`, optional
    Filename to save the plot to.  If `None`, the plot will be displayed in
    a window.
invert : `bool`, optional
    If `True`, invert the comparison and fail only if any elements *are*
    equal. Used to implement `~lsst.utils.tests.assertFloatsNotEqual`,
    which should generally be used instead for clarity.
msg : `str`, optional
    String to append to the error message when assert fails.

Raises
------
AssertionError
    The values are not almost equal.

Definition at line 612 of file tests.py.

612  plotFileName=None, invert=False, msg=None):
613  """Highly-configurable floating point comparisons for scalars and arrays.
614 
615  The test assertion will fail if all elements ``lhs`` and ``rhs`` are not
616  equal to within the tolerances specified by ``rtol`` and ``atol``.
617  More precisely, the comparison is:
618 
619  ``abs(lhs - rhs) <= relTo*rtol OR abs(lhs - rhs) <= atol``
620 
621  If ``rtol`` or ``atol`` is `None`, that term in the comparison is not
622  performed at all.
623 
624  When not specified, ``relTo`` is the elementwise maximum of the absolute
625  values of ``lhs`` and ``rhs``. If set manually, it should usually be set
626  to either ``lhs`` or ``rhs``, or a scalar value typical of what is
627  expected.
628 
629  Parameters
630  ----------
631  testCase : `unittest.TestCase`
632  Instance the test is part of.
633  lhs : scalar or array-like
634  LHS value(s) to compare; may be a scalar or array-like of any
635  dimension.
636  rhs : scalar or array-like
637  RHS value(s) to compare; may be a scalar or array-like of any
638  dimension.
639  rtol : `float`, optional
640  Relative tolerance for comparison; defaults to double-precision
641  epsilon.
642  atol : `float`, optional
643  Absolute tolerance for comparison; defaults to double-precision
644  epsilon.
645  relTo : `float`, optional
646  Value to which comparison with rtol is relative.
647  printFailures : `bool`, optional
648  Upon failure, print all inequal elements as part of the message.
649  plotOnFailure : `bool`, optional
650  Upon failure, plot the originals and their residual with matplotlib.
651  Only 2-d arrays are supported.
652  plotFileName : `str`, optional
653  Filename to save the plot to. If `None`, the plot will be displayed in
654  a window.
655  invert : `bool`, optional
656  If `True`, invert the comparison and fail only if any elements *are*
657  equal. Used to implement `~lsst.utils.tests.assertFloatsNotEqual`,
658  which should generally be used instead for clarity.
659  msg : `str`, optional
660  String to append to the error message when assert fails.
661 
662  Raises
663  ------
664  AssertionError
665  The values are not almost equal.
666  """
667  if not numpy.isfinite(lhs).all():
668  testCase.fail("Non-finite values in lhs")
669  if not numpy.isfinite(rhs).all():
670  testCase.fail("Non-finite values in rhs")
671  diff = lhs - rhs
672  absDiff = numpy.abs(lhs - rhs)
673  if rtol is not None:
674  if relTo is None:
675  relTo = numpy.maximum(numpy.abs(lhs), numpy.abs(rhs))
676  else:
677  relTo = numpy.abs(relTo)
678  bad = absDiff > rtol*relTo
679  if atol is not None:
680  bad = numpy.logical_and(bad, absDiff > atol)
681  else:
682  if atol is None:
683  raise ValueError("rtol and atol cannot both be None")
684  bad = absDiff > atol
685  failed = numpy.any(bad)
686  if invert:
687  failed = not failed
688  bad = numpy.logical_not(bad)
689  cmpStr = "=="
690  failStr = "are the same"
691  else:
692  cmpStr = "!="
693  failStr = "differ"
694  errMsg = []
695  if failed:
696  if numpy.isscalar(bad):
697  if rtol is None:
698  errMsg = ["%s %s %s; diff=%s with atol=%s"
699  % (lhs, cmpStr, rhs, absDiff, atol)]
700  elif atol is None:
701  errMsg = ["%s %s %s; diff=%s/%s=%s with rtol=%s"
702  % (lhs, cmpStr, rhs, absDiff, relTo, absDiff/relTo, rtol)]
703  else:
704  errMsg = ["%s %s %s; diff=%s/%s=%s with rtol=%s, atol=%s"
705  % (lhs, cmpStr, rhs, absDiff, relTo, absDiff/relTo, rtol, atol)]
706  else:
707  errMsg = ["%d/%d elements %s with rtol=%s, atol=%s"
708  % (bad.sum(), bad.size, failStr, rtol, atol)]
709  if plotOnFailure:
710  if len(lhs.shape) != 2 or len(rhs.shape) != 2:
711  raise ValueError("plotOnFailure is only valid for 2-d arrays")
712  try:
713  plotImageDiff(lhs, rhs, bad, diff=diff, plotFileName=plotFileName)
714  except ImportError:
715  errMsg.append("Failure plot requested but matplotlib could not be imported.")
716  if printFailures:
717  # Make sure everything is an array if any of them are, so we can treat
718  # them the same (diff and absDiff are arrays if either rhs or lhs is),
719  # and we don't get here if neither is.
720  if numpy.isscalar(relTo):
721  relTo = numpy.ones(bad.shape, dtype=float) * relTo
722  if numpy.isscalar(lhs):
723  lhs = numpy.ones(bad.shape, dtype=float) * lhs
724  if numpy.isscalar(rhs):
725  rhs = numpy.ones(bad.shape, dtype=float) * rhs
726  if rtol is None:
727  for a, b, diff in zip(lhs[bad], rhs[bad], absDiff[bad]):
728  errMsg.append("%s %s %s (diff=%s)" % (a, cmpStr, b, diff))
729  else:
730  for a, b, diff, rel in zip(lhs[bad], rhs[bad], absDiff[bad], relTo[bad]):
731  errMsg.append("%s %s %s (diff=%s/%s=%s)" % (a, cmpStr, b, diff, rel, diff/rel))
732 
733  if msg is not None:
734  errMsg.append(msg)
735  testCase.assertFalse(failed, msg="\n".join(errMsg))
736 
737 
738 @inTestCase
def plotImageDiff(lhs, rhs, bad=None, diff=None, plotFileName=None)
Definition: tests.py:544
bool all(CoordinateExpr< N > const &expr) noexcept
Return true if all elements are true.

◆ assertFloatsEqual()

def lsst.utils.tests.assertFloatsEqual (   testCase,
  lhs,
  rhs,
  kwargs 
)
Assert that lhs == rhs (both numeric types, whether scalar or array).

See `~lsst.utils.tests.assertFloatsAlmostEqual` (called with
``rtol=atol=0``) for more information.

Parameters
----------
testCase : `unittest.TestCase`
    Instance the test is part of.
lhs : scalar or array-like
    LHS value(s) to compare; may be a scalar or array-like of any
    dimension.
rhs : scalar or array-like
    RHS value(s) to compare; may be a scalar or array-like of any
    dimension.

Raises
------
AssertionError
    The values are not equal.

Definition at line 766 of file tests.py.

766 def assertFloatsEqual(testCase, lhs, rhs, **kwargs):
767  """
768  Assert that lhs == rhs (both numeric types, whether scalar or array).
769 
770  See `~lsst.utils.tests.assertFloatsAlmostEqual` (called with
771  ``rtol=atol=0``) for more information.
772 
773  Parameters
774  ----------
775  testCase : `unittest.TestCase`
776  Instance the test is part of.
777  lhs : scalar or array-like
778  LHS value(s) to compare; may be a scalar or array-like of any
779  dimension.
780  rhs : scalar or array-like
781  RHS value(s) to compare; may be a scalar or array-like of any
782  dimension.
783 
784  Raises
785  ------
786  AssertionError
787  The values are not equal.
788  """
789  return assertFloatsAlmostEqual(testCase, lhs, rhs, rtol=0, atol=0, **kwargs)
790 
791 
792 @inTestCase
def assertFloatsEqual(testCase, lhs, rhs, kwargs)
Definition: tests.py:766
def assertFloatsAlmostEqual(testCase, lhs, rhs, rtol=sys.float_info.epsilon, atol=sys.float_info.epsilon, relTo=None, printFailures=True, plotOnFailure=False, plotFileName=None, invert=False, msg=None)
Definition: tests.py:612

◆ assertFloatsNotEqual()

def lsst.utils.tests.assertFloatsNotEqual (   testCase,
  lhs,
  rhs,
  kwds 
)
Fail a test if the given floating point values are equal to within the
given tolerances.

See `~lsst.utils.tests.assertFloatsAlmostEqual` (called with
``rtol=atol=0``) for more information.

Parameters
----------
testCase : `unittest.TestCase`
    Instance the test is part of.
lhs : scalar or array-like
    LHS value(s) to compare; may be a scalar or array-like of any
    dimension.
rhs : scalar or array-like
    RHS value(s) to compare; may be a scalar or array-like of any
    dimension.

Raises
------
AssertionError
    The values are almost equal.

Definition at line 739 of file tests.py.

739 def assertFloatsNotEqual(testCase, lhs, rhs, **kwds):
740  """Fail a test if the given floating point values are equal to within the
741  given tolerances.
742 
743  See `~lsst.utils.tests.assertFloatsAlmostEqual` (called with
744  ``rtol=atol=0``) for more information.
745 
746  Parameters
747  ----------
748  testCase : `unittest.TestCase`
749  Instance the test is part of.
750  lhs : scalar or array-like
751  LHS value(s) to compare; may be a scalar or array-like of any
752  dimension.
753  rhs : scalar or array-like
754  RHS value(s) to compare; may be a scalar or array-like of any
755  dimension.
756 
757  Raises
758  ------
759  AssertionError
760  The values are almost equal.
761  """
762  return assertFloatsAlmostEqual(testCase, lhs, rhs, invert=True, **kwds)
763 
764 
765 @inTestCase
def assertFloatsAlmostEqual(testCase, lhs, rhs, rtol=sys.float_info.epsilon, atol=sys.float_info.epsilon, relTo=None, printFailures=True, plotOnFailure=False, plotFileName=None, invert=False, msg=None)
Definition: tests.py:612
def assertFloatsNotEqual(testCase, lhs, rhs, kwds)
Definition: tests.py:739

◆ assertNotClose()

def lsst.utils.tests.assertNotClose (   args,
  kwargs 
)
.. note:: Deprecated in 12_0

Definition at line 801 of file tests.py.

801 def assertNotClose(*args, **kwargs):
802  """.. note:: Deprecated in 12_0"""
803  warnings.warn("assertNotClose is deprecated; please use TestCase.assertFloatsNotEqual",
804  DeprecationWarning, stacklevel=2)
805  return assertFloatsNotEqual(*args, **kwargs)
806 
def assertFloatsNotEqual(testCase, lhs, rhs, kwds)
Definition: tests.py:739
def assertNotClose(args, kwargs)
Definition: tests.py:801

◆ assertRaisesLsstCpp()

def lsst.utils.tests.assertRaisesLsstCpp (   testcase,
  excClass,
  callableObj,
  args,
  kwargs 
)
.. note:: Deprecated in 12_0

Definition at line 503 of file tests.py.

503 def assertRaisesLsstCpp(testcase, excClass, callableObj, *args, **kwargs):
504  """.. note:: Deprecated in 12_0"""
505  warnings.warn("assertRaisesLsstCpp is deprecated; please just use TestCase.assertRaises",
506  DeprecationWarning, stacklevel=2)
507  return testcase.assertRaises(excClass, callableObj, *args, **kwargs)
508 
509 
def assertRaisesLsstCpp(testcase, excClass, callableObj, args, kwargs)
Definition: tests.py:503

◆ debugger()

def lsst.utils.tests.debugger (   exceptions)
Decorator to enter the debugger when there's an uncaught exception

To use, just slap a ``@debugger()`` on your function.

You may provide specific exception classes to catch as arguments to
the decorator function, e.g.,
``@debugger(RuntimeError, NotImplementedError)``.
This defaults to just `AssertionError`, for use on `unittest.TestCase`
methods.

Code provided by "Rosh Oxymoron" on StackOverflow:
http://stackoverflow.com/questions/4398967/python-unit-testing-automatically-running-the-debugger-when-a-test-fails

Notes
-----
Consider using ``pytest --pdb`` instead of this decorator.

Definition at line 510 of file tests.py.

510 def debugger(*exceptions):
511  """Decorator to enter the debugger when there's an uncaught exception
512 
513  To use, just slap a ``@debugger()`` on your function.
514 
515  You may provide specific exception classes to catch as arguments to
516  the decorator function, e.g.,
517  ``@debugger(RuntimeError, NotImplementedError)``.
518  This defaults to just `AssertionError`, for use on `unittest.TestCase`
519  methods.
520 
521  Code provided by "Rosh Oxymoron" on StackOverflow:
522  http://stackoverflow.com/questions/4398967/python-unit-testing-automatically-running-the-debugger-when-a-test-fails
523 
524  Notes
525  -----
526  Consider using ``pytest --pdb`` instead of this decorator.
527  """
528  if not exceptions:
529  exceptions = (AssertionError, )
530 
531  def decorator(f):
532  @functools.wraps(f)
533  def wrapper(*args, **kwargs):
534  try:
535  return f(*args, **kwargs)
536  except exceptions:
537  import sys
538  import pdb
539  pdb.post_mortem(sys.exc_info()[2])
540  return wrapper
541  return decorator
542 
543 
def debugger(exceptions)
Definition: tests.py:510

◆ getTempFilePath()

def lsst.utils.tests.getTempFilePath (   ext,
  expectOutput = True 
)
Return a path suitable for a temporary file and try to delete the
file on success

If the with block completes successfully then the file is deleted,
if possible; failure results in a printed warning.
If a file is remains when it should not, a RuntimeError exception is
raised. This exception is also raised if a file is not present on context
manager exit when one is expected to exist.
If the block exits with an exception the file if left on disk so it can be
examined. The file name has a random component such that nested context
managers can be used with the same file suffix.

Parameters
----------

ext : `str`
    File name extension, e.g. ``.fits``.
expectOutput : `bool`, optional
    If `True`, a file should be created within the context manager.
    If `False`, a file should not be present when the context manager
    exits.

Returns
-------
`str`
    Path for a temporary file. The path is a combination of the caller's
    file path and the name of the top-level function

Notes
-----
::

    # file tests/testFoo.py
    import unittest
    import lsst.utils.tests
    class FooTestCase(unittest.TestCase):
        def testBasics(self):
            self.runTest()

        def runTest(self):
            with lsst.utils.tests.getTempFilePath(".fits") as tmpFile:
                # if tests/.tests exists then
                # tmpFile = "tests/.tests/testFoo_testBasics.fits"
                # otherwise tmpFile = "testFoo_testBasics.fits"
                ...
                # at the end of this "with" block the path tmpFile will be
                # deleted, but only if the file exists and the "with"
                # block terminated normally (rather than with an exception)
    ...

Definition at line 389 of file tests.py.

389 def getTempFilePath(ext, expectOutput=True):
390  """Return a path suitable for a temporary file and try to delete the
391  file on success
392 
393  If the with block completes successfully then the file is deleted,
394  if possible; failure results in a printed warning.
395  If a file is remains when it should not, a RuntimeError exception is
396  raised. This exception is also raised if a file is not present on context
397  manager exit when one is expected to exist.
398  If the block exits with an exception the file if left on disk so it can be
399  examined. The file name has a random component such that nested context
400  managers can be used with the same file suffix.
401 
402  Parameters
403  ----------
404 
405  ext : `str`
406  File name extension, e.g. ``.fits``.
407  expectOutput : `bool`, optional
408  If `True`, a file should be created within the context manager.
409  If `False`, a file should not be present when the context manager
410  exits.
411 
412  Returns
413  -------
414  `str`
415  Path for a temporary file. The path is a combination of the caller's
416  file path and the name of the top-level function
417 
418  Notes
419  -----
420  ::
421 
422  # file tests/testFoo.py
423  import unittest
424  import lsst.utils.tests
425  class FooTestCase(unittest.TestCase):
426  def testBasics(self):
427  self.runTest()
428 
429  def runTest(self):
430  with lsst.utils.tests.getTempFilePath(".fits") as tmpFile:
431  # if tests/.tests exists then
432  # tmpFile = "tests/.tests/testFoo_testBasics.fits"
433  # otherwise tmpFile = "testFoo_testBasics.fits"
434  ...
435  # at the end of this "with" block the path tmpFile will be
436  # deleted, but only if the file exists and the "with"
437  # block terminated normally (rather than with an exception)
438  ...
439  """
440  stack = inspect.stack()
441  # get name of first function in the file
442  for i in range(2, len(stack)):
443  frameInfo = inspect.getframeinfo(stack[i][0])
444  if i == 2:
445  callerFilePath = frameInfo.filename
446  callerFuncName = frameInfo.function
447  elif callerFilePath == frameInfo.filename:
448  # this function called the previous function
449  callerFuncName = frameInfo.function
450  else:
451  break
452 
453  callerDir, callerFileNameWithExt = os.path.split(callerFilePath)
454  callerFileName = os.path.splitext(callerFileNameWithExt)[0]
455  outDir = os.path.join(callerDir, ".tests")
456  if not os.path.isdir(outDir):
457  outDir = ""
458  prefix = "%s_%s-" % (callerFileName, callerFuncName)
459  outPath = tempfile.mktemp(dir=outDir, suffix=ext, prefix=prefix)
460  if os.path.exists(outPath):
461  # There should not be a file there given the randomizer. Warn and remove.
462  # Use stacklevel 3 so that the warning is reported from the end of the with block
463  warnings.warn("Unexpectedly found pre-existing tempfile named %r" % (outPath,),
464  stacklevel=3)
465  try:
466  os.remove(outPath)
467  except OSError:
468  pass
469 
470  yield outPath
471 
472  fileExists = os.path.exists(outPath)
473  if expectOutput:
474  if not fileExists:
475  raise RuntimeError("Temp file expected named {} but none found".format(outPath))
476  else:
477  if fileExists:
478  raise RuntimeError("Unexpectedly discovered temp file named {}".format(outPath))
479  # Try to clean up the file regardless
480  if fileExists:
481  try:
482  os.remove(outPath)
483  except OSError as e:
484  # Use stacklevel 3 so that the warning is reported from the end of the with block
485  warnings.warn("Warning: could not remove file %r: %s" % (outPath, e), stacklevel=3)
486 
487 
def format(config, name=None, writeSourceLine=True, prefix="", verbose=False)
Definition: history.py:168
def getTempFilePath(ext, expectOutput=True)
Definition: tests.py:389

◆ init()

def lsst.utils.tests.init ( )
Initialize the memory tester and file descriptor leak tester.

Definition at line 75 of file tests.py.

75 def init():
76  """Initialize the memory tester and file descriptor leak tester."""
77  global memId0
78  global open_files
79  if dafBase:
80  memId0 = dafBase.Citizen.getNextMemId() # used by MemoryTestCase
81  # Reset the list of open files
82  open_files = _get_open_files()
83 
84 
def init()
Definition: tests.py:75

◆ inTestCase()

def lsst.utils.tests.inTestCase (   func)
A decorator to add a free function to our custom TestCase class, while also
making it available as a free function.

Definition at line 494 of file tests.py.

494 def inTestCase(func):
495  """A decorator to add a free function to our custom TestCase class, while also
496  making it available as a free function.
497  """
498  setattr(TestCase, func.__name__, func)
499  return func
500 
501 
502 @inTestCase
def inTestCase(func)
Definition: tests.py:494

◆ plotImageDiff()

def lsst.utils.tests.plotImageDiff (   lhs,
  rhs,
  bad = None,
  diff = None,
  plotFileName = None 
)
Plot the comparison of two 2-d NumPy arrays.

Parameters
----------
lhs : `numpy.ndarray`
    LHS values to compare; a 2-d NumPy array
rhs : `numpy.ndarray`
    RHS values to compare; a 2-d NumPy array
bad : `numpy.ndarray`
    A 2-d boolean NumPy array of values to emphasize in the plots
diff : `numpy.ndarray`
    difference array; a 2-d NumPy array, or None to show lhs-rhs
plotFileName : `str`
    Filename to save the plot to.  If None, the plot will be displayed in
    a window.

Notes
-----
This method uses `matplotlib` and imports it internally; it should be
wrapped in a try/except block within packages that do not depend on
`matplotlib` (including `~lsst.utils`).

Definition at line 544 of file tests.py.

544 def plotImageDiff(lhs, rhs, bad=None, diff=None, plotFileName=None):
545  """Plot the comparison of two 2-d NumPy arrays.
546 
547  Parameters
548  ----------
549  lhs : `numpy.ndarray`
550  LHS values to compare; a 2-d NumPy array
551  rhs : `numpy.ndarray`
552  RHS values to compare; a 2-d NumPy array
553  bad : `numpy.ndarray`
554  A 2-d boolean NumPy array of values to emphasize in the plots
555  diff : `numpy.ndarray`
556  difference array; a 2-d NumPy array, or None to show lhs-rhs
557  plotFileName : `str`
558  Filename to save the plot to. If None, the plot will be displayed in
559  a window.
560 
561  Notes
562  -----
563  This method uses `matplotlib` and imports it internally; it should be
564  wrapped in a try/except block within packages that do not depend on
565  `matplotlib` (including `~lsst.utils`).
566  """
567  from matplotlib import pyplot
568  if diff is None:
569  diff = lhs - rhs
570  pyplot.figure()
571  if bad is not None:
572  # make an rgba image that's red and transparent where not bad
573  badImage = numpy.zeros(bad.shape + (4,), dtype=numpy.uint8)
574  badImage[:, :, 0] = 255
575  badImage[:, :, 1] = 0
576  badImage[:, :, 2] = 0
577  badImage[:, :, 3] = 255*bad
578  vmin1 = numpy.minimum(numpy.min(lhs), numpy.min(rhs))
579  vmax1 = numpy.maximum(numpy.max(lhs), numpy.max(rhs))
580  vmin2 = numpy.min(diff)
581  vmax2 = numpy.max(diff)
582  for n, (image, title) in enumerate([(lhs, "lhs"), (rhs, "rhs"), (diff, "diff")]):
583  pyplot.subplot(2, 3, n + 1)
584  im1 = pyplot.imshow(image, cmap=pyplot.cm.gray, interpolation='nearest', origin='lower',
585  vmin=vmin1, vmax=vmax1)
586  if bad is not None:
587  pyplot.imshow(badImage, alpha=0.2, interpolation='nearest', origin='lower')
588  pyplot.axis("off")
589  pyplot.title(title)
590  pyplot.subplot(2, 3, n + 4)
591  im2 = pyplot.imshow(image, cmap=pyplot.cm.gray, interpolation='nearest', origin='lower',
592  vmin=vmin2, vmax=vmax2)
593  if bad is not None:
594  pyplot.imshow(badImage, alpha=0.2, interpolation='nearest', origin='lower')
595  pyplot.axis("off")
596  pyplot.title(title)
597  pyplot.subplots_adjust(left=0.05, bottom=0.05, top=0.92, right=0.75, wspace=0.05, hspace=0.05)
598  cax1 = pyplot.axes([0.8, 0.55, 0.05, 0.4])
599  pyplot.colorbar(im1, cax=cax1)
600  cax2 = pyplot.axes([0.8, 0.05, 0.05, 0.4])
601  pyplot.colorbar(im2, cax=cax2)
602  if plotFileName:
603  pyplot.savefig(plotFileName)
604  else:
605  pyplot.show()
606 
607 
608 @inTestCase
def plotImageDiff(lhs, rhs, bad=None, diff=None, plotFileName=None)
Definition: tests.py:544

◆ run()

def lsst.utils.tests.run (   suite,
  exit = True 
)
Run a test suite and report the test return status to caller or shell.

.. note:: Deprecated in 13_0
          Use `unittest.main()` instead, which automatically detects
          all tests in a test case and does not require a test suite.

Parameters
----------
suite : `unittest.TestSuite`
    Test suite to run.
exit : `bool`, optional
    If `True`, Python process will exit with the test exit status.

Returns
-------
status : `int`
    If ``exit`` is `False`, will return 0 if the tests passed, or 1 if
    the tests failed.

Definition at line 85 of file tests.py.

85 def run(suite, exit=True):
86  """Run a test suite and report the test return status to caller or shell.
87 
88  .. note:: Deprecated in 13_0
89  Use `unittest.main()` instead, which automatically detects
90  all tests in a test case and does not require a test suite.
91 
92  Parameters
93  ----------
94  suite : `unittest.TestSuite`
95  Test suite to run.
96  exit : `bool`, optional
97  If `True`, Python process will exit with the test exit status.
98 
99  Returns
100  -------
101  status : `int`
102  If ``exit`` is `False`, will return 0 if the tests passed, or 1 if
103  the tests failed.
104  """
105 
106  warnings.warn("lsst.utils.tests.run() is deprecated; please use unittest.main() instead",
107  DeprecationWarning, stacklevel=2)
108 
109  if unittest.TextTestRunner().run(suite).wasSuccessful():
110  status = 0
111  else:
112  status = 1
113 
114  if exit:
115  sys.exit(status)
116  else:
117  return status
118 
119 
def run(suite, exit=True)
Definition: tests.py:85

◆ sort_tests()

def lsst.utils.tests.sort_tests (   tests)
Sort supplied test suites such that MemoryTestCases are at the end.

`lsst.utils.tests.MemoryTestCase` tests should always run after any other
tests in the module.

Parameters
----------
tests : sequence
    Sequence of test suites.

Returns
-------
suite : `unittest.TestSuite`
    A combined `~unittest.TestSuite` with
    `~lsst.utils.tests.MemoryTestCase` at the end.

Definition at line 120 of file tests.py.

120 def sort_tests(tests):
121  """Sort supplied test suites such that MemoryTestCases are at the end.
122 
123  `lsst.utils.tests.MemoryTestCase` tests should always run after any other
124  tests in the module.
125 
126  Parameters
127  ----------
128  tests : sequence
129  Sequence of test suites.
130 
131  Returns
132  -------
133  suite : `unittest.TestSuite`
134  A combined `~unittest.TestSuite` with
135  `~lsst.utils.tests.MemoryTestCase` at the end.
136  """
137 
138  suite = unittest.TestSuite()
139  memtests = []
140  for test_suite in tests:
141  try:
142  # Just test the first test method in the suite for MemoryTestCase
143  # Use loop rather than next as it is possible for a test class
144  # to not have any test methods and the Python community prefers
145  # for loops over catching a StopIteration exception.
146  bases = None
147  for method in test_suite:
148  bases = inspect.getmro(method.__class__)
149  break
150  if bases is not None and MemoryTestCase in bases:
151  memtests.append(test_suite)
152  else:
153  suite.addTests(test_suite)
154  except TypeError:
155  if isinstance(test_suite, MemoryTestCase):
156  memtests.append(test_suite)
157  else:
158  suite.addTest(test_suite)
159  suite.addTests(memtests)
160  return suite
161 
162 
def sort_tests(tests)
Definition: tests.py:120

◆ suiteClassWrapper()

def lsst.utils.tests.suiteClassWrapper (   tests)

Definition at line 163 of file tests.py.

163 def suiteClassWrapper(tests):
164  return unittest.TestSuite(sort_tests(tests))
165 
166 
167 # Replace the suiteClass callable in the defaultTestLoader
168 # so that we can reorder the test ordering. This will have
169 # no effect if no memory test cases are found.
170 unittest.defaultTestLoader.suiteClass = suiteClassWrapper
171 
172 
def suiteClassWrapper(tests)
Definition: tests.py:163
def sort_tests(tests)
Definition: tests.py:120

Variable Documentation

◆ dafBase

lsst.utils.tests.dafBase = None

Definition at line 49 of file tests.py.

◆ memId0

int lsst.utils.tests.memId0 = 0

Definition at line 54 of file tests.py.

◆ nleakPrintMax

int lsst.utils.tests.nleakPrintMax = 20

Definition at line 55 of file tests.py.

◆ open_files

lsst.utils.tests.open_files = set()

Definition at line 58 of file tests.py.

◆ psutil

lsst.utils.tests.psutil = None

Definition at line 44 of file tests.py.