python3.8 删除文件单元测试

huangapple go评论69阅读模式
英文:

python3.8 delete file unittests

问题

我有一个用于删除文件的实用函数如下。
我打算为它编写单元测试用例。

    """
    删除给定的文件名
    """
    try:
        os.remove(file_name)
        logger.info("已删除文件:%s", file_name)
    except FileNotFoundError:
        logger.error("错误:找不到文件%s", file_name)
    except PermissionError:
        logger.error("删除时无效权限:%s", file_name)
    except OSError as exc:
        logger.error("删除%s时出错:%s", exc.filename, exc.strerror)

我应该如何编写测试用例?
考虑到这些异常实际上并未引发,而是通过日志消息处理。
关于断言,有何指示?

尝试下面的代码,但它显示引发了一个错误。

def test_file_delete_with_os_error(self, mock_remove):
    mock_remove.side_effect = OSError
    with self.assertRaises(OSError):
        delete_file_name('abc.txt', logging.getLogger('test'))```

<details>
<summary>英文:</summary>

I have a utility function for removing a file as below. 
And I intend to write unittest cases for it. 

def delete_file_name(file_name, logger):
"""
Deletes given file name
"""
try:
os.remove(file_name)
logger.info("Deleted file: %s", file_name)
except FileNotFoundError:
logger.error("Error: File not found %s", file_name)
except PermissionError:
logger.error("Invalid permissions while deleting: %s", file_name)
except OSError as exc:
logger.error("Error while deleting %s: %s", exc.filename, exc.strerror)


How do I go about writing test cases? 
Considering that these exceptions are not really raised but handled by a log message.
Any pointers on how the assertions would be? 

Tried below but it shows an error that exception is not raised. 
@patch(&#39;os.remove&#39;)
def test_file_delete_with_os_error(self, mock_remove):
    mock_remove.side_effect = OSError
    with self.assertRaises(OSError):
        delete_file_name(&#39;abc.txt&#39;, logging.getLogger(&#39;test&#39;))

</details>


# 答案1
**得分**: 2

因为您控制传递给被测试函数的记录器,所以您可以将输出重定向到自定义的 `io.StringIO` 对象:

```python
import logging
import unittest
from unittest.mock import patch

# 模拟的部分,请根据您的需求进行调整
from my_module import delete_file_name

class TestSomething(unittest.TestCase):
   def setUp(self):
       self.stream = io.StringIO()
       self.logger = logging.getLogger('test')
       self.stream_handler = logging.StreamHandler(self.stream)
       self.logger.addHandler(self.stream_handler)

   def tearDown(self):
       self.logger.removeHandler(self.stream_handler)

   @patch('os.remove')
   def test_delte_file_os_error(self, mock_remove):
       mock_remove.side_effect = OSError
       delete_file_name('abc.txt', self.logger)

       self.stream.seek(0)
       self.assertEqual(self.stream.read(), 'Error while deleting None: None\n')

正如您所看到的,然后您可以检索记录器的输出并检查它是否等于您的预期结果。
(在这个示例中,我将 Error while deleting None: None 放在那里,因为这是您目前已经放置的 side_effect 所产生的输出。)

英文:

Because you control the logger that's passed to the tested function, you can redirect the output to a custom io.StringIO object:

import logging
import unittest
from unittest.mock import patch

# simulated, adjust to your needs
from my_module import delete_file_name

class TestSomething(unittest.TestCase):
    def setUp(self):
        self.stream = io.StringIO()
        self.logger = logging.getLogger(&#39;test&#39;)
        self.stream_handler = logging.StreamHandler(self.stream)
        self.logger.addHandler(self.stream_handler)

    def tearDown(self):
        self.logger.removeHandler(self.stream_handler)

    @patch(&#39;os.remove&#39;)
    def test_delte_file_os_error(self, mock_remove):
        mock_remove.side_effect = OSError
        delete_file_name(&#39;abc.txt&#39;, self.logger)

        self.stream.seek(0)
        self.assertEqual(self.stream.read(), &#39;Error while deleting None: None\n&#39;)

As you can see, you can then retrieve the output of the logger and check if it is equal to what you expect.
(In this example I put Error while deleting None: None as this is the output the side_effect you currently have in place gives)

huangapple
  • 本文由 发表于 2023年6月8日 04:36:23
  • 转载请务必保留本文链接:https://go.coder-hub.com/76426946.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定