如何通过管道对作为子过程一起工作的模块进行单元测试?

时间:2014-08-24 21:03:43

标签: python unit-testing testing subprocess integration-testing

我正在编写一个充当脚本管理器的程序。它由3部分组成:

  1. 客户端 - 接收要从服务器运行的脚本名称。
  2. Manager - 管理运行脚本。使用管道中传输的json从客户端接收它们。
  3. 在项目的.py目录下找到的scrips - addons脚本。
  4. 需要注意的重要一点是,所有3个组件同时作为进程运行(因为我可以在接受并执行播放音乐脚本时运行警报脚本。< / p>

    因为它由3个相互作用的独立部分组成,所以我不知道如何为它编写适当的单元测试。

    所以我的问题是:

    1. 我怎样才能为此编写好的单元测试?
    2. 这是一个设计问题吗?如果是这样,我做错了什么,我应该怎么做才能解决它?
    3. 以下是上述组件的大部分代码:

      客户

      class MessageReceiver:
      
          def __init__(self):
              '''
              Connect to the AMQP broker and starts listening for messages.
              Creates the a Popen object to pass command info to the addon_manager script (which
              is in charge of managing scripts)
              '''
              addon_manager_path = configuration.addon_manager_path()
              addon_manager_path = os.path.join(addon_manager_path,'addon_manager.py')
              execute = "python " + addon_manager_path
              self.addon_manager = subprocess.Popen(execute, stdin=subprocess.PIPE, shell=True)
      
      
              self.component_name= configuration.get_attribute("name")
      
              if len(sys.argv)>1:
                  host_ip = sys.argv[1]
              else:
                  host_ip = 'localhost'
      
              #Start a connection to the AMQP server
              self.connection = pika.BlockingConnection(pika.ConnectionParameters(host=host_ip))
      
              #Create a channel to the server
              self.channel = self.connection.channel()
      
              self.channel.queue_declare(queue="example")
      
              #callback method to be called when data is received
              #It sends the data that is received by the client to the addon_manager
              def data_received(ch, method, properties, body):
                  ##TODO: Might want to add some checks. Is body a JSON? etc.
                  print("GOT IT")
                  self.addon_manager.communicate(body)
      
      
              self.channel.basic_consume(data_received,queue='example',no_ack=True)
      
              self.channel.start_consuming()
      

      经理

      class AddonManager:
      
          def __init__(self):
              self.command_analyzer = analyzer.Analyzer(configuration.get_attribute("commands"))
              self.active_addons = {}
      
      
          def activate_addon(self,command,json_data):
              child_popen = self.command_analyzer.execute_command(command,json_data)
              self.active_addons[analyzer.intent(json_data)] = child_popen
      
      
          def communicate_with_addon(self,command,json_data,json_string):
              child_popen = self.active_addons[analyzer.intent(json_data)]
      
              #Child process hasn't finished running
              if child_popen.returncode is None:
                  #Send data to child to process if he wants to
                  child_popen.stdin.write(json_string)
      
              else:
                  #Process finished running. Can't send it anything. delete it. (deleting the Popen instance also kills zombie process)
                  del self.active_addons[analyzer.intent(json_data)]
                  self.activate_addon(command,json_data)
      
      
          def get_input(self):
              """
              Reads command from stdin, returns its JSON form
              """
              json_string = sys.stdin.read()
              json_data =json.loads(json_string)
              print(json_data)
              return json_data
      
      
          def accept_commands(self):
              while True:
                  json_data = self.get_input()
                  command = self.command_analyzer.is_command(json_data) # Check wether the command exists. Return it if it does
                  #The command exists
                  if command is not None:
                      #The addon is not currently active
                      if analyzer.intent(json_data) not in self.active_addons:
                          self.activate_addon(command,json_data)
      
                      #The addon is active and so we need to send the data to the subprocess
                      else:
                          self.communicate_with_addon(command,json_data,json_string)
      
      
      manager = AddonManager()
      manager.accept_commands()
      

0 个答案:

没有答案