如何对下载功能进行单元测试?

时间:2013-07-26 09:44:42

标签: python unit-testing

我有一个python函数可以下载一些文件。

e.g。

def downloader():
    file_list=['fileone.htm','filetwo.htm','filethree.htm']
    for f in file_list:
        (filename,headers) = urllib.urlretrieve(f,'c:\\temp\\'+f)

单元测试功能的正确方法是什么?它是否有效取决于urlretrieve函数的行为方式,这取决于外部因素。

2 个答案:

答案 0 :(得分:2)

如果要测试的是函数调用file_list中所有元素的urlretrieve,则可以修改函数以将retrieve-function作为参数:

def downloder(urlretrieve):
  file_list=['fileone.htm','filetwo.htm','filethree.htm']
  for f in file_list:
    (filename,headers) = urlretrieve(f,'c:\\temp\\'+f)

然后在您的单元测试中,您可以创建一个自定义函数,并使用正确的参数检查所谓的正确次数。

calls = []
def retrieve(url, local) :
  calls.append([url,local])

assert(len(calls) == 3)
assert(calls[0][0] == 'fileone.html')
assert(calls[0][2] == 'c:\\temp\\fileone.html')
...

您可以使用库Mock来简化为单元测试创​​建自己的检索功能的部分。

答案 1 :(得分:0)

基本上,如果您需要测试逻辑如何响应urlretrieve函数的行为,则需要将模拟行为注入到程序流中。执行此操作的一种方法是将urllib功能包装在运行单元测试时生成此行为的模块或类中。例如,如果您的下载功能在其自己的模块中,您可以执行以下操作(简化的伪代码):

file:dowloader.py

class UrllibWrapper:
    # thin wrapper for urllib

class Downloader:
    def __init__(self, urllib_class=None):
        if urllib_class is None:
            self.ul = UrllibWrapper()
        else:
            self.ul = urllib_class

    def download(self, f, dest):
        self.ul.urlretrieve(f, dest)

if __name__ == '__main__':
    class FakeUrllibWrapper:
        # implement desired behaviour of urrlib

    ul = FakeUrllibWrapper()
    dl = Downloader(ul)
    # do unit tests

在你的程序中你会这样做:

# ...
from downloader import Downloader
dl = Downloader()
for f in files:
    dl.download(f, dest)