2016-05-05 5 views
1

私はScrapy XMLFeedSpiderを持っていると私は、次のparse_node機能をテストしようとしています:ScrapyスパイダーPythonジェネレーター関数を正しくテストするにはどうすればよいですか?

def parse_node(self, response, selector): 
    date = selector.xpath('pubDate/text()').extract_first() 
    url = selector.xpath('link/text()').extract_first()    
    if date < self.cutoff_date: # TEST VALIDITY OF THE DATE 
     print "Invalid date" 
     self.log("Article %s before crawler start date" % url) 
    else: 
     print "Valid date" 
     yield scrapy.Request(url, self.parse_post) 

Iが有効と無効な日付の両方の機能をテストしようとしています:

@mock.patch('my_spiders.spiders.myspider.scrapy.Request')    
def test_parse_node(self, scrapy_request):          
    scrapy_request.return_value = mock.MagicMock()        
    self.spider.log = mock.MagicMock()           
    mock_response = mock.MagicMock()            
    mock_selector = mock.MagicMock()            
    date = self.spider.start_date.strftime("%c")         
    url = "https://google.com"             
    mock_selector.xpath.return_value.extract_first = mock.MagicMock(   
     side_effect=[date, url]             
    )                   
    parsed_node = self.spider.parse_node(mock_response, mock_selector)   
    self.assertEqual(tuple(parsed_node)[0], scrapy_request.return_value)   
    self.spider.log.assert_not_called()           
    scrapy_request.assert_called_once_with(url, self.spider.parse_post)   

@mock.patch('my_spiders.spiders.myspider.scrapy.Request')    
def test_parse_node_invalid_date(self, scrapy_request):       
    scrapy_request.return_value = mock.MagicMock()        
    self.spider.log = mock.MagicMock()           
    mock_response = mock.MagicMock()            
    mock_selector = mock.MagicMock()            
    date_object = self.spider.start_date - datetime.timedelta(days=1)   
    date = date_object.strftime("%c")           
    url = "https://google.com"             
    mock_selector.xpath.return_value.extract_first = mock.MagicMock(   
     side_effect=[date, url]             
    )                   

    parsed_node = self.spider.parse_node(mock_response, mock_selector)   
    # TODO: figure out why this doesn't work          
    # self.spider.log.assert_called_once()         
    scrapy_request.assert_not_called() 

最初のテストtest_parse_nodeが期待どおりに実行されます。問題は、test_parse_node_invalid_date関数にあります。 parse_node関数にデバッガを置くと呼び出されません。 print関数も呼び出されません。

これはyieldステートメント/ジェネレータで問題が発生すると思われますが、何が起きているのか把握できません。私が期待しているように、なぜ2回目のテストがparse_nodeの機能を実行していないのですか?

答えて

0

pythonジェネレータ関数は単にイテレータを返します。実際にそのイテレータをデバッグするには、私はnext()メソッドを呼び出すことによって、反復プロセスを開始しなければならなかった:私はまた、発電機が一つだけ時間をかけて繰り返すことができるので、各テストは、新しい発電機をインスタンス化していることを確認しなければならなかった

parsed_node = self.spider.parse_node(mock_response, mock_selector).next() 

次に、必要に応じてステップを踏んで、デバッグ/テストを完了することができました。

関連する問題