Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从配置文件读取configparser的单元测试python代码_Python_Unit Testing_Pytest - Fatal编程技术网

从配置文件读取configparser的单元测试python代码

从配置文件读取configparser的单元测试python代码,python,unit-testing,pytest,Python,Unit Testing,Pytest,我是python单元测试新手。我学习并做了示例单元测试,其中方法接受输入并返回输出 但是对于下面提到的代码,我有一些问题 如何在unittest中模拟init方法的configparser?路径/config/program.cfg位于生产服务器上,不在dev目录中。program.cfg文件存在于代码目录中的其他位置。有没有办法在unittest中处理这个问题 如何发送或跳过unittest中的硬编码路径,例如/var/log/info_server.log 如果可能的话,您能告诉我如何使用p

我是python单元测试新手。我学习并做了示例单元测试,其中方法接受输入并返回输出

但是对于下面提到的代码,我有一些问题

  • 如何在unittest中模拟init方法的configparser?路径/config/program.cfg位于生产服务器上,不在dev目录中。program.cfg文件存在于代码目录中的其他位置。有没有办法在unittest中处理这个问题
  • 如何发送或跳过unittest中的硬编码路径,例如/var/log/info_server.log
  • 如果可能的话,您能告诉我如何使用pytest模块为下面的代码编写unittest吗?这将有助于理解流程,我可以用其余的代码做到这一点

    def __init__(self):
        self.setup_logger()
    
        # Read config parameters
        config = configparser.ConfigParser()
        config.read("/config/program.cfg")
        self.host_ip = config.get('default','HostIP')
        self.redis_ip = config.get('default','RedisIP')
        self.redis_port = config.get('default','RedisPort')
        self.info_port = config.get('default','InfoPort')
        self.sqlite_db_file = config.get('default','SQLiteDbFile')
    
        self.connect_redis()
    
    def setup_logger(self):
        #Initialize logger
        self.logger = logging.getLogger(__name__)
        self.logger.setLevel(logging.INFO)
    
        # Create a file handler
        handler = logging.FileHandler('/var/log/info_server.log')
        handler.setLevel(logging.INFO)
    
        # Create a logging format
        formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
        handler.setFormatter(formatter)
    
        # Add the handlers to the logger
        self.logger.addHandler(handler)
    
    def connect_redis(self):
        # Start up a Redis instance
        self.logger.info("Start Redis instance")
        self.ad_info = redis.StrictRedis(host=self.redis_ip, port=self.redis_port, db=0)
    
        if self.ad_info is None:
            self.logger.error("Failed to start Redis instance")
        else:
            self.logger.info("Started Redis instance")
    

  • 当然,我们可以模拟很多事情,但是对被测试的类进行简单的重新分解,添加config和log,将使工作变得更加轻松

    def __init__(self, cfg='/config/program.cfg', log='/var/log/info_server.log'):
    
    在不存在
    /config/program.cfg
    的开发服务器中,您可以

    TheClass(cfg='~/dev.cfg', log='/tmp/dev.log')
    
    self.server\u obj.connect\u redis()log\u mock.logger.info.assert\u调用了('Started redis instance')
    未工作


    不要一次问多个问题;有人知道三个问题的答案的可能性比知道一个问题的答案的可能性小。如果打开
    /config/program.cfg
    ,您可以模拟内置的
    open
    函数,该函数将返回带有配置文件内容的
    StringIO
    ,或者在打开
    /var/log/info\u server.log
    进行写入时写入
    StringIO
    。谢谢。这真的让生活轻松多了。但我现在面临的问题是在start\u Redis方法中调用self.logger.info(“Started Redis实例”)的次数。我尝试将补丁('scripts.server.server.logging')作为log\u mock:self.server\u obj.connect\u redis()log\u mock.logger.info.assert\u调用了('Started redis instance'),但它在connect\u redis中查看logging.info而不计算self.logging.info如何实现?假设您正在测试的脚本或模块是
    server.py
    ,如果您
    导入日志记录
    ,使用
    补丁('scripts.sever.logging.getLogger.info')作为模拟信息
    ,那么您可以
    使用('xxx')调用self.server.obj.logger.info.assert\u来快速回复。对脚本名为server.py,它有导入日志记录,我尝试了上面的建议,但得到以下错误。AttributeError:没有“info”属性,因此我添加了“getLogger.level..”并尝试使用修补程序('scripts.server.logging.getLogger.level.info')作为模拟_info:self.server_obj.logger.info.assert_调用了_('Started Redis instance'),但获取模块发现错误:没有名为'scripts.server.logging';'“scripts.server”不是一个包,我缺少什么吗?我只是想告诉您,我使用的是Python3.6。5@Amit,如果您的IDE中有一个自动完成功能,那么就更容易弄清楚要模拟什么。在这种情况下,我更新了答案,是伪代码让您知道如何模拟
    
    import logging
    logging.getLogger
    
    # <function getLogger at 0x7f3d2ed427b8>
    logger = logging.getLogger()
    type(logger)
    # <class 'logging.RootLogger'>
    logger.info
    # <bound method Logger.info of <RootLogger root (WARNING)>>
    
    with mock.patch.object(logging.RootLogger, 'info') as mock_info:
    
        server_obj = Server(cfg='sth', log='sth')
        mock_info.assert_called_with('xxx')