class_docstr: Class to test the shape of Jacobian with different return types.
  
  The return types have the following major cases:
  
  1. 1 trainable param, 1 measurement
  2. 1 trainable param, >1 measurement
  3. >1 trainable param, 1 measurement
  4. >1 trainable param, >1 measurement
class_docstr_tok: ["Class","to","test","the","shape","of","Jacobian","with","different","return","types",".","The","return","types","have","the","following","major","cases",":","1",".","1","trainable","param",",","1","measurement","2",".","1","trainable","param",",",">","1","measurement","3",".",">","1","trainable","param",",","1","measurement","4",".",">","1","trainable","param",",",">","1","measurement"]
docstr: Test multi-param multi-measurement case
docstr_tok: ["Test","multi-param","multi-measurement","case"]
code: def test_N_N(self, shot_vec, op_wires):
      """Test multi-param multi-measurement case"""
      dev = qml.device("default.qubit", wires=6, shots=shot_vec)
      params = np.random.random(6)
  
      with qml.queuing.AnnotatedQueue() as q:
          for idx, w in enumerate(op_wires):
              qml.RY(
                  params[idx], wires=[w]
              )  # Op acts either on wire 0-4 (non-zero grad) or wire 5 (zero grad)
  
          # The following asserts that there actually is a w defined, or raises an
          # error if op_wires was empty
          w = op_wires[-1]
          # Extra op - 5 measurements in total
          qml.RY(
              params[5], wires=[w]
          )  # Op acts either on wire 0-4 (non-zero grad) or wire 5 (zero grad)
  
          # 4 measurements
          qml.expval(qml.PauliZ(wires=0))
          qml.probs(wires=[2, 1])
          qml.var(qml.Projector([1], wires=3))
          qml.var(qml.Hermitian(A, wires=4))
  
      grad_transform_shots = Shots(shot_vec)
      tape = qml.tape.QuantumScript.from_queue(
          q, shots=grad_transform_shots
      )
      # Multiple trainable params
      tape.trainable_params = {0, 1, 2, 3, 4}
  
      tapes, fn = qml.gradients.finite_diff(tape)
      all_res = fn(dev.execute(tapes))
  
      assert len(all_res) == grad_transform_shots.num_copies
      assert isinstance(all_res, tuple)
  
      expected_shapes = [(), (4,), (), ()]
      for meas_res in all_res:
          assert len(meas_res) == 4
          for idx, param_res in enumerate(meas_res):
              assert len(param_res) == 5
              for res in param_res:
                  assert isinstance(res, np.ndarray)
                  assert res.shape == expected_shapes[idx]
  
imports: import numpy
  import pytest
  from pennylane import numpy
  import pennylane
  from pennylane.gradients import finite_diff
  from pennylane.devices import DefaultQubitLegacy
  from pennylane.measurements import Shots
  from pennylane.operation import Observable, AnyWires
label_desc: Use image node_id 4 for calling the TestReturn obj's underlying member method code with example usage: obj.test_N_N(shot_vec, op_wires) without return types