简体   繁体   中英

How do I capture a screenshot if my nosetests fail?

I am running selenium webdriver tests with nosetests. I want to capture a screenshot whenever nosetests fail. How can I do it in the most effective way, either by using webdriver, python or nosetests features?

My solution

import sys, unittest
from datetime import datetime

class TestCase(unittest.TestCase):

    def setUp(self):
        some_code

    def test_case(self):
        blah-blah-blah

    def tearDown(self):
        if sys.exc_info()[0]:  # Returns the info of exception being handled 
            fail_url = self.driver.current_url
            print fail_url
            now = datetime.now().strftime('%Y-%m-%d_%H-%M-%S-%f')
            self.driver.get_screenshot_as_file('/path/to/file/%s.png' % now) # my tests work in parallel, so I need uniqe file names
            fail_screenshot_url = 'http://debugtool/screenshots/%s.png' % now
            print fail_screenshot_url
        self.driver.quit()

First of all, webdriver has the command:

driver.get_screenshot_as_file(screenshot_file_path)

I'm not an expert in nose (actually this is the first time I've looked into it), however I use py.test framework (which is similar, however superior over nose IMHO).

Mostly likely you'll have to create the "plugin" for nose where you'll have to implement the hook addFailure(test, err) which is "Called when a test fails".

In this addFailure(test, err) you can get the test name from Test object and generate the path for the file.

After that call driver.get_screenshot_as_file(screenshot_file_path) .

In py.test I create my plugin with implementation of def pytest_runtest_makereport(item, call): hook. Inside I analyze call.excinfo and create the screenshot if necessary.

在Python中,您可以使用以下代码:

driver.save_screenshot('/file/screenshot.png')

Perhaps you have set up your tests differently, but in my experience you need to manually build in this type of functionality and repeat it at the point of failure. If you're performing selenium tests, chances are that like me, you're using a lot of find_element_by_ something . I've written the following function to allow me to tackle this type of thing:

def findelement(self, selector, name, keys='', click=False):

    if keys:
        try:
            self.driver.find_element_by_css_selector(selector).send_keys(keys)
        except NoSuchElementException:
            self.fail("Tried to send %s into element %s but did not find the element." % (keys, name))
    elif click:
        try:
            self.driver.find_element_by_css_selector(selector).click()
        except NoSuchElementException:
            self.fail("Tried to click element %s but did not find it." % name)
    else:
        try:
            self.driver.find_element_by_css_selector(selector)
        except NoSuchElementException:
            self.fail("Expected to find element %s but did not find it." % name)

In your case, the screenshot code (self.driver.get_screenshot_as_file(screenshot_file_path)) would go before the self.fail.

With this code, every time you want to interact with an element, you would call self.findelement('selector', 'element name')

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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