code: def test_unbatched(self):
      self.start_tests(name="unbatched")
  
      agent = self.agent_spec()
      environment = self.environment_spec()
  
      # default
      runner = Runner(
          agent=agent, environment=environment, num_parallel=2
      )
      runner.run(num_episodes=3, use_tqdm=False)
      runner.close()
      self.finished_test()
  
      # episode callback
      runner = Runner(
          agent=agent, environments=[environment, environment]
      )
      callback_episode_frequency = 2
      self.num_callbacks = 0
  
      def callback(r, p):
          self.num_callbacks += 1
          if self.num_callbacks % 2 == 0:
              self.assertEqual(min(r.episode_timestep), 0)
          self.assertEqual(
              r.episodes,
              self.num_callbacks * callback_episode_frequency,
          )
  
      runner.run(
          num_episodes=5,
          callback=callback,
          callback_episode_frequency=callback_episode_frequency,
          use_tqdm=False,
          sync_episodes=True,
      )
      self.finished_test()
  
      # timestep callback
      callback_timestep_frequency = 3
  
      def callback(r, p):
          self.assertEqual(
              r.episode_timestep[p] % callback_timestep_frequency, 0
          )
  
      runner.run(
          num_episodes=2,
          callback=callback,
          callback_timestep_frequency=callback_timestep_frequency,
          use_tqdm=False,
      )
      runner.close()
      self.finished_test()
  
      # evaluation synced
      runner = Runner(
          agent=agent,
          environment=environment,
          num_parallel=2,
          evaluation=True,
      )
      self.num_evaluations = 0
  
      def evaluation_callback(r):
          self.num_evaluations += 1
  
      runner.run(
          num_episodes=1,
          use_tqdm=False,
          evaluation_callback=evaluation_callback,
          sync_episodes=True,
      )
      self.finished_test(assertion=(self.num_evaluations == 1))
  
      # evaluation non-synced
      runner.run(
          num_episodes=1,
          use_tqdm=False,
          evaluation_callback=evaluation_callback,
      )
      runner.close()
      self.finished_test(assertion=(self.num_evaluations >= 2))
  
file_path: tensorforce/test/test_runner.py
imports: import unittest
  from tensorforce import Runner
  from test.unittest_base import UnittestBase
label_desc: Use image node_id 2 for calling the TestRunner obj's underlying member method code with example usage: obj.test_unbatched() without return types