class_docstr: Unit tests for QLearning.
class_docstr_tok: ["Unit","tests","for","QLearning","."]
docstr: Test if _update_q_periodically() can finish successfully.
docstr_tok: ["Test","if","_update_q_periodically","(",")","can","finish","successfully","."]
code: def test_update_q(self, mock_parameters, mock_replay_memory):
      """Test if _update_q_periodically() can finish successfully."""
      self._setup_parameters(mock_parameters.return_value)
      self._setup_replay_memory(mock_replay_memory.return_value)
  
      action_space = spaces.Discrete(2)
      observation_space = spaces.Box(0, 1, (1,))
      sut = QLearning("", observation_space, action_space)
      sut._trainer.train_minibatch = MagicMock()
      sut._choose_action = MagicMock(
          side_effect=[
              (1, "GREEDY"),
              (0, "GREEDY"),
              (1, "RANDOM"),
          ]
      )
  
      action, debug_info = sut.start(np.array([0.1], np.float32))
      self.assertEqual(action, 1)
      self.assertEqual(debug_info["action_behavior"], "GREEDY")
      self.assertEqual(sut.episode_count, 1)
      self.assertEqual(sut.step_count, 0)
      self.assertEqual(sut._epsilon, 0.1)
      self.assertEqual(
          sut._trainer.parameter_learners[0].learning_rate(), 0.1
      )
      self.assertEqual(sut._last_state, np.array([0.1], np.float32))
      self.assertEqual(sut._last_action, 1)
  
      action, debug_info = sut.step(1, np.array([0.2], np.float32))
      self.assertEqual(action, 0)
      self.assertEqual(debug_info["action_behavior"], "GREEDY")
      self.assertEqual(sut.episode_count, 1)
      self.assertEqual(sut.step_count, 1)
      self.assertEqual(sut._epsilon, 0.09)
      # learning rate remains 0.1 as Q is not updated during this time step.
      self.assertEqual(
          sut._trainer.parameter_learners[0].learning_rate(), 0.1
      )
      self.assertEqual(sut._last_state, np.array([0.2], np.float32))
      self.assertEqual(sut._last_action, 0)
  
      action, debug_info = sut.step(2, np.array([0.3], np.float32))
      self.assertEqual(action, 1)
      self.assertEqual(debug_info["action_behavior"], "RANDOM")
      self.assertEqual(sut.episode_count, 1)
      self.assertEqual(sut.step_count, 2)
      self.assertEqual(sut._epsilon, 0.08)
      self.assertEqual(
          sut._trainer.parameter_learners[0].learning_rate(), 0.08
      )
      self.assertEqual(sut._last_state, np.array([0.3], np.float32))
      self.assertEqual(sut._last_action, 1)
  
      sut.end(3, np.array([0.4], np.float32))
      self.assertEqual(sut.episode_count, 1)
      self.assertEqual(sut.step_count, 3)
      self.assertEqual(sut._epsilon, 0.08)
      # learning rate remains 0.08 as Q is not updated during this time step.
      self.assertEqual(
          sut._trainer.parameter_learners[0].learning_rate(), 0.08
      )
  
imports: import unittest
  import cntk.contrib.deeprl.tests.spaces
  import numpy
  from cntk.contrib.deeprl.agent.qlearning import QLearning
  from cntk.contrib.deeprl.agent.shared.cntk_utils import huber_loss
  from cntk.contrib.deeprl.agent.shared.replay_memory import _Transition
  from cntk.layers import Dense
  from cntk.losses import squared_error
  from cntk.ops import input_variable
label_desc: Use image node_id 8 for calling the QLearningTest obj's underlying member method code with example usage: obj.test_update_q(mock_parameters, mock_replay_memory) without return types