如何验证python的IOBase的实现?

时间:2016-07-07 23:13:20

标签: python testing io

我是否可以使用现有的测试套件来测试IOBase的实现?如果可能的话,我想详尽地测试一个新的实现,但是有很多测试需要手动编写。

例如,假设我有一个不可搜索,不可写的流。我想验证我的read的实现是否合规,并且所有其他方法都会引发正确的错误。这样的类看起来像这样:

import io


class NonSeekableReader(io.RawIOBase):
    def __init__(self, b=b''):
        super(NonSeekableReader, self).__init__()
        self._data = io.BytesIO(b)

    def seekable(self):
        return False

    def writable(self):
        return False

    def readable(self):
        return True

    def read(self, n=-1):
        return self._data.read(n)

也许阅读按照我最初的预期工作,但也许有一些边缘情况我会错过更复杂的实现。实验表明,对于预期的行为,文档至少令人困惑。

根据python docs我可以看到,通过定义writeable来返回Falsewrite应该引发OSError(在Python 3.5中)。实际情况并非如此,当从NotImplementedError继承时,从RawIOBaseAttributeError继承时会引发IOBaseseekable中没有重复此行为,即调用.tell()会引发正确的错误。要解决此问题,请按以下方式定义write

def write(self, b):
    raise io.UnsupportedOperation("write")

值得注意的是,使用'r'打开的文件会产生预期的错误类。

由于在链接的doc页面之外没有关于实现这些接口(我已经找到)的一般指导,我甚至不必考虑检查问题。预先存在的测试套件可以解决这个问题。或者以其他方式描述必要的测试或边缘情况会引导我解决这些问题。

这些指导是否存在于我尚未找到的地方?

1 个答案:

答案 0 :(得分:2)

  • Python文档是唯一官方的,权威的来源,其中包含有关股票实施行为的承诺/保证 - 其他任何正式发布的内容都没有。如果没有记录某些内容,则不应依赖不存在

    • 源回购中有io模块test_io.py的单元测试(您也可以选择使用解释器安装测试套件)。根据您在下一段中的回答,请注意特定于实现的详细信息。
      • 还要注意特定于基类的io实现的详细信息:as Andrea Corbellini noted,有一个基类的规范,并且有一个关于它的派生的规范。
  • 某些行为是特定于实现的,并且确实在Python实现之间存在差异(例如,在IronPython中,sys.maxsize是非常大的,因为在.NET和所有字符串中没有这样的机制即使它实现了Python 2)也是Unicode。

    • 这里的问题是:您的目标是否与规范具体实施??答案取决于多少(以及如何 - (或者说更糟) ,即不可能的)书面的)您希望与之兼容的代码。
      • 由于我们在这里谈论抽象类,因此没有特定的实现"真的除了相关实体中的小默认/非抽象代码。所以差别很小。
  • 现在,确实存在一些规范忽略或模糊一些关键细节的情况(我个人在ctypes中遇到至少两个案例)。这是因为它是用户而不是实施者的指南。

    • 除了坚持规范并在遇到问题时解决问题,你无能为力。在模糊的情况下,您可以检查实现,但一定要找出基本原理 概念用途要做什么)以确定适合您的情况。毕竟,如果您要更换内部模块,您怎么知道其他内部模块依赖的未记录行为?
      • 对Python开发者来说'值得赞扬的是,后者的情况应该非常罕见,因为他们确实遵守松散耦合原则,并努力在模块间交互中坚持规范(有规范)。