Repository: Qiskit/qiskit-ibmq-provider (language: python)

Issue:
Add way to automatically install qiskit-requirements as dependency

### What is the expected enhancement?

Add `qiskit-experiments` to an `extras` install for something like `pip install qiskit-ibmq-provider[experiments]` or just to requirements-dev.txt to make it simpler to get that installed for running these tests:

https://github.com/Qiskit/qiskit-ibmq-provider/blob/5c11f797cd0fcbb91e1acc38e9bda6b97218dff1/test/ibmq/experiment/test_experiment_data_integration.py#L43

Right now I have to remember to manually pip install `qiskit-experiments`.
Use QE_DEVICE_STAGING in TestExperimentServerIntegration

### What is the expected enhancement?

The test is hard-coding to `ibmq_qasm_simulator` here:

https://github.com/Qiskit/qiskit-ibmq-provider/blob/0937e8a6c9b9150b1f809698d7931fd7c1492c9c/test/ibmq/experiment/test_experiment_server_integration.py#L43

But that might not be available to the provider being used to run those tests.

The experiments integration tests are being run setting `QE_STAGING_DEVICE=backend1` here:

https://github.com/Qiskit/qiskit-ibmq-provider/blob/0937e8a6c9b9150b1f809698d7931fd7c1492c9c/.github/workflows/cron-staging.yml#L48

So it seems we should be able to replace that hard-coding with reading from that environment variable but default to `ibmq_qasm_simulator` if not set.


Discussion / hints:
Note that the `experiment-integration` tests in `cron-staging` aren't running as a result:

https://github.com/Qiskit/qiskit-ibmq-provider/runs/3178330068?check_suite_focus=true

![image](https://user-images.githubusercontent.com/3237936/127398301-6ab71838-6e16-4e8e-bbde-89c3e27526d5.png)

I guess this is technically blocked on getting a released version of qiskit-experiments:

https://github.com/Qiskit/qiskit-experiments/tags

We could install from the `main` branch but that's probably not wise.
Apparently have the same issue here for TestExperimentDataIntegration:

https://github.com/Qiskit/qiskit-ibmq-provider/blob/master/test/ibmq/experiment/test_experiment_data_integration.py#L57

Fix patch:
diff --git a/.github/workflows/cron-staging.yml b/.github/workflows/cron-staging.yml
index db43b0d84..5f27acc13 100644
--- a/.github/workflows/cron-staging.yml
+++ b/.github/workflows/cron-staging.yml
@@ -45,7 +45,7 @@ jobs:
     env:
       QE_STAGING_TOKEN: ${{ secrets.QE_STAGING_TOKEN }}
       QE_STAGING_URL: ${{ secrets.QE_STAGING_URL }}
-      QE_STAGING_DEVICE: "backend1"
+      QE_STAGING_DEVICE: "ibmq_qasm_simulator"
       USE_STAGING_CREDENTIALS: True
       LOG_LEVEL: DEBUG
       STREAM_LOG: True
diff --git a/requirements-dev.txt b/requirements-dev.txt
index de415c045..72670669f 100644
--- a/requirements-dev.txt
+++ b/requirements-dev.txt
@@ -25,3 +25,5 @@ qiskit_rng
 qiskit-aer
 websockets>=8
 scikit-quant;platform_system != 'Windows'
+# TODO: Use released qiskit-experiments when it's released
+git+https://github.com/Qiskit/qiskit-experiments.git ; python_version > '3.6'


Test patch:
diff --git a/test/ibmq/experiment/test_experiment_data_integration.py b/test/ibmq/experiment/test_experiment_data_integration.py
index e4b9995c7..a63c5843a 100644
--- a/test/ibmq/experiment/test_experiment_data_integration.py
+++ b/test/ibmq/experiment/test_experiment_data_integration.py
@@ -53,7 +53,7 @@ def setUpClass(cls):
         if not cls.provider.has_service('experiment'):
             raise SkipTest("Not authorized to use experiment service.")
 
-        cls.backend = cls.provider.get_backend('ibmq_qasm_simulator')
+        cls.backend = cls._setup_backend()  # pylint: disable=no-value-for-parameter
         cls.device_components = cls.provider.experiment.device_components(cls.backend.name())
         if not cls.device_components:
             raise SkipTest("No device components found.")
@@ -137,7 +137,7 @@ def test_new_experiment_data(self):
         exp_data.save()
         self.experiments_to_delete.append(exp_data.experiment_id)
 
-        credentials = self.provider.credentials
+        credentials = self.backend.provider().credentials
         rexp = DbExperimentData.load(exp_data.experiment_id, self.experiment)
         self._verify_experiment_data(exp_data, rexp)
         self.assertEqual(credentials.hub, rexp.hub)  # pylint: disable=no-member
diff --git a/test/ibmq/experiment/test_experiment_server_integration.py b/test/ibmq/experiment/test_experiment_server_integration.py
index 8480d73c9..f8ba2a2b7 100644
--- a/test/ibmq/experiment/test_experiment_server_integration.py
+++ b/test/ibmq/experiment/test_experiment_server_integration.py
@@ -28,7 +28,7 @@
                                               IBMExperimentEntryNotFound)
 
 from ...ibmqtestcase import IBMQTestCase
-from ...decorators import requires_provider
+from ...decorators import requires_provider, requires_device
 from .utils import ExperimentEncoder, ExperimentDecoder
 
 
@@ -42,7 +42,7 @@ def setUpClass(cls):
         # pylint: disable=arguments-differ
         super().setUpClass()
         cls.provider = cls._setup_provider()  # pylint: disable=no-value-for-parameter
-        cls.backend = cls.provider.get_backend('ibmq_qasm_simulator')
+        cls.backend = cls._setup_backend()  # pylint: disable=no-value-for-parameter
         try:
             cls.device_components = cls.provider.experiment.device_components(cls.backend.name())
         except Exception:
@@ -54,6 +54,12 @@ def _setup_provider(cls, provider):
         """Get the provider for the class."""
         return provider
 
+    @classmethod
+    @requires_device
+    def _setup_backend(cls, backend):
+        """Get a backend for the class."""
+        return backend
+
     def setUp(self) -> None:
         """Test level setup."""
         super().setUp()