[英]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
对象的结果转换为list
或tuple
,然后比较是否相等来测试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.