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

Python 如何通过管道对作为子流程一起工作的模块进行单元测试?,python,unit-testing,testing,subprocess,integration-testing,Python,Unit Testing,Testing,Subprocess,Integration Testing,我正在写一个作为脚本管理器的程序。它由3部分组成: 客户端-接收要从服务器运行的脚本名称 管理器-管理正在运行的脚本。使用管道中传输的json从客户端接收它们 scrips-.py脚本,可在项目中的插件目录下找到 需要注意的重要一点是,所有3个组件都作为进程同时运行(因为我可以在接受和执行播放音乐脚本的同时运行报警脚本) 因为它由3个相互作用的独立部分组成,我不知道如何为它编写适当的单元测试 因此,我的问题是: 我如何才能为此编写好的单元测试 这是一个设计问题吗?如果是的话,我做错了什么?我应该

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

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

    因为它由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()
    

    什么是集成测试还是单元测试?这两种类型相差甚远。单元测试不需要任何其他部分;测试代码之外的任何内容都会被模拟、编写脚本以产生特定的响应。@MartijnPieters-你说得对。我的错。我对单元测试感兴趣。我认为集成测试更接近acc在这种情况下,接受测试(从某种意义上说,我只需要运行它,看看它是否有效)me认为两者都做一点是有用的。(不熟悉python)为了编写适当的单元测试,您需要模拟stdin和stdout。或者(我通常更喜欢)将有趣的代码放在外部没有DEP的方法中进行测试。