简体   繁体   English

用yield编写功能的unittest

[英]Write unittest for function with yield

I am trying to write a unittest for a function that utilizes a generator. 我正在尝试为使用生成器的函数编写单元测试。 Below is my code: 下面是我的代码:

def extract_data(body):
    for i in body:
        a = re.sub('<[^<]+?>', '', str(i))
        b = re.sub('view\xc2\xa0book\xc2\xa0info', '', str(a))
        c = re.sub('key', '', str(b))
        d = re.sub('\xc2', ' ', str(c))
        e = re.sub('\xa0', '', str(d))
        yield e

My unittest code: 我的单元测试代码:

    def test_extract_data(self):
        sample_input = ['<tr><h1>keyThis</h1><h2>\xc2</h2><h3>\xa0</h3><h4>view\xc2\xa0book\xc2\xa0info</h4><h5>Test Passes</h5></tr>']
        expected_res = 'This Test Passes'
        res = extract_data(sample_input)

        self.assertEqual(expected_res, res)

This test passes without issue if the extract_data function uses a return instead of yield. 如果extract_data函数使用return而不是yield,则该测试顺利通过。 How do I write the test for the generator? 如何编写生成器的测试?

I figured out what I needed to do. 我想出了我需要做的。 I needed to make the res into a list. 我需要将res放入列表中。 and that was it. 就是这样。 A lot simpler than I expected. 比我预期的要简单得多。 so this is what it looks like now: 所以这是现在的样子:

class TestScrapePage(unittest.TestCase):

    def test_extract_data(self):
        sample_input = ['<tr><h1>keyThis</h1><h2>\xc2</h2><h3>\xa0</h3><h4>view\xc2\xa0book\xc2\xa0info</h4><h5>Test Passes</h5></tr>']
        expected_res = ['This Test Passes']
        res = list(extract_data(sample_input))

    self.assertEqual(expected_res, res)

if __name__ == '__main__':
    unittest.main()

Your code, slightly altered to not require unittest: 您的代码稍作改动就不需要进行单元测试:

import re

def extract_data(body):
    for i in body:
        a = re.sub('<[^<]+?>', '', str(i))
        b = re.sub('view\xc2\xa0book\xc2\xa0info', '', str(a))
        c = re.sub('key', '', str(b))
        d = re.sub('\xc2', ' ', str(c))
        e = re.sub('\xa0', '', str(d))
        yield e

def test_extract_data():
    sample_input = ['<tr><h1>keyThis</h1><h2>\xc2</h2><h3>\xa0</h3><h4>view\xc2\xa0book\xc2\xa0info</h4><h5>Test Passes</h5></tr>']
    expected_res = 'This Test Passes'
    res = extract_data(sample_input)
    return expected_res == res

print(test_extract_data())

This prints False 此打印False

The problem is that when you do return , the function, in your case, returns a str . 问题在于,当您return ,函数(根据您的情况)将返回str However, when you do yield , it returns a generator type object whose next() function returns a str . 但是,当您执行yield ,它将返回一个generator类型的对象,其next()函数将返回一个str So, for example: 因此,例如:

import re

def extract_data(body):
    for i in body:
        a = re.sub('<[^<]+?>', '', str(i))
        b = re.sub('view\xc2\xa0book\xc2\xa0info', '', str(a))
        c = re.sub('key', '', str(b))
        d = re.sub('\xc2', ' ', str(c))
        e = re.sub('\xa0', '', str(d))
        yield e

def test_extract_data():
    sample_input = ['<tr><h1>keyThis</h1><h2>\xc2</h2><h3>\xa0</h3><h4>view\xc2\xa0book\xc2\xa0info</h4><h5>Test Passes</h5></tr>']
    expected_res = 'This Test Passes'
    res = extract_data(sample_input)
    return expected_res == next(res)

print(test_extract_data())

This prints True . 这将输出True

To illustrate, at the Python command prompt : 为了说明,在Python命令提示符下

>>> type("hello")
<class 'str'>
>>> def gen():
...     yield "hello"
... 
>>> type(gen())
<class 'generator'>

Your other option (possibly better, depending on your use case), is to test that are all of the results of the generator are correct by converting the generator object's results into a list or tuple , and then compare for equality: 您的另一个选择(可能更好,具体取决于您的用例)是通过将generator对象的结果转换为listtuple ,然后比较是否相等来测试generator所有结果是否正确:

import re

def extract_data(body):
    for i in body:
        a = re.sub('<[^<]+?>', '', str(i))
        b = re.sub('view\xc2\xa0book\xc2\xa0info', '', str(a))
        c = re.sub('key', '', str(b))
        d = re.sub('\xc2', ' ', str(c))
        e = re.sub('\xa0', '', str(d))
        yield e

def test_extract_data():
    sample_input = ['<tr><h1>keyThis</h1><h2>\xc2</h2><h3>\xa0</h3><h4>view\xc2\xa0book\xc2\xa0info</h4><h5>Test Passes</h5></tr>', '<tr><h1>keyThis</h1><h2>\xc2</h2><h3>\xa0</h3><h4>view\xc2\xa0book\xc2\xa0info</h4><h5>Test Passes Too!</h5></tr>']
    expected_res = ['This Test Passes', 'This Test Passes Too!']
    res = extract_data(sample_input)
    return expected_res == list(res)

print(test_extract_data())

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM