1616import os
1717import json
1818import pickle
19+ import sys
20+ import unittest
1921import warnings
2022from typing import Any , Callable , Optional
2123
2224import fixtures
2325import uncertainties
24- from qiskit .test import QiskitTestCase
2526from qiskit .utils .deprecation import deprecate_func
2627
28+ import qiskit_experiments .warnings
2729from qiskit_experiments .framework import (
2830 ExperimentDecoder ,
2931 ExperimentEncoder ,
3638TEST_TIMEOUT = os .environ .get ("TEST_TIMEOUT" , 60 )
3739
3840
39- class QiskitExperimentsTestCase (QiskitTestCase ):
41+ # If testtools is installed use that as a (mostly) drop in replacement for
42+ # unittest's TestCase. This will enable the fixtures used for capturing stdout
43+ # stderr, and pylogging to attach the output to stestr's result stream.
44+ if qiskit_experiments .warnings .HAS_TESTTOOLS :
45+ import testtools
46+
47+ class BaseTestCase (testtools .TestCase ):
48+ """Base test class."""
49+
50+ # testtools maintains their own version of assert functions which mostly
51+ # behave as value adds to the std unittest assertion methods. However,
52+ # for assertEquals and assertRaises modern unittest has diverged from
53+ # the forks in testtools and offer more (or different) options that are
54+ # incompatible testtools versions. Just use the stdlib versions so that
55+ # our tests work as expected.
56+ assertRaises = unittest .TestCase .assertRaises
57+ assertEqual = unittest .TestCase .assertEqual
58+
59+ else :
60+
61+ class BaseTestCase (unittest .TestCase ):
62+ """Base test class."""
63+
64+ pass
65+
66+
67+
68+
69+ # TODO: copy enforce_subclasses_call decorator?
70+ class QiskitExperimentsTestCase (BaseTestCase ):
4071 """Qiskit Experiments specific extra functionality for test cases."""
4172
73+ def __init__ (self , * args , ** kwargs ):
74+ super ().__init__ (* args , ** kwargs )
75+ self .__setup_called = False
76+ self .__teardown_called = False
77+
4278 def setUp (self ):
4379 super ().setUp ()
4480 self .useFixture (fixtures .Timeout (TEST_TIMEOUT , gentle = True ))
81+ if self .__setup_called :
82+ raise ValueError (
83+ "In File: %s\n "
84+ "TestCase.setUp was already called. Do not explicitly call "
85+ "setUp from your tests. In your own setUp, use super to call "
86+ "the base setUp." % (sys .modules [self .__class__ .__module__ ].__file__ ,)
87+ )
88+ self .__setup_called = True
4589
4690 @classmethod
4791 def setUpClass (cls ):
4892 """Set-up test class."""
4993 super ().setUpClass ()
5094
95+ warnings .filterwarnings ("error" , category = DeprecationWarning )
96+
5197 # Some functionality may be deprecated in Qiskit Experiments. If the deprecation warnings aren't
5298 # filtered, the tests will fail as ``QiskitTestCase`` sets all warnings to be treated as an error
5399 # by default.
@@ -60,6 +106,17 @@ def setUpClass(cls):
60106 for msg in allow_deprecationwarning_message :
61107 warnings .filterwarnings ("default" , category = DeprecationWarning , message = msg )
62108
109+ def tearDown (self ):
110+ super ().tearDown ()
111+ if self .__teardown_called :
112+ raise ValueError (
113+ "In File: %s\n "
114+ "TestCase.tearDown was already called. Do not explicitly call "
115+ "tearDown from your tests. In your own tearDown, use super to "
116+ "call the base tearDown." % (sys .modules [self .__class__ .__module__ ].__file__ ,)
117+ )
118+ self .__teardown_called = True
119+
63120 def assertExperimentDone (
64121 self ,
65122 experiment_data : ExperimentData ,
0 commit comments