3

I am using Python 3.6.5 with the following libraries:

  • Appium-Python-Client==0.26
  • unittest2==1.1.0
  • selenium==3.5.0
  • pytest==3.6.3

Now I need to capture the screenshot in case of test failure, So intentionally I did put a false statement self.driver.find_element_by_css_selector('test') .

I am using sys.exc_info(). But when I executing below code using a command: py.test untitled.py or python3 -m unittest untitled.py it does not capturing it.

Code:

import sys, time, unittest2
from selenium import webdriver

class FB360(unittest2.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()

    def test_user_can_login(self):
            self.driver.get('https://www.google.co.in')
            self.driver.find_element_by_css_selector('test')

    def tearDown(self):
        print(sys.exc_info())
        if sys.exc_info()[0]:
            test_method_name = self._testMethodName
            self.driver.save_screenshot(test_method_name + str(time.time()) + '.png')
        self.driver.quit()

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

O/P:

(None, None, None)

E

====================================================================== ERROR: test_user_can_login (untitled.FB360)


Traceback (most recent call last): File "/Volumes/Harry/Projects/pythonScreenshots/untitled.py", line 11, in test_user_can_login self.driver.find_element_by_css_selector('test') File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 498, in find_element_by_css_selector return self.find_element(by=By.CSS_SELECTOR, value=css_selector) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 832, in find_element 'value': value})['value'] File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/selenium/webdriver/remote/webdriver.py", line 297, in execute self.error_handler.check_response(response) File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response raise exception_class(message, screen, stacktrace) selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"test"} (Session info: chrome=67.0.3396.99) (Driver info: chromedriver=2.40.565386 (45a059dc425e08165f9a10324bd1380cc13ca363),platform=Mac OS X 10.13.5 x86_64)

My Foundings:

  • print(sys.exc_info()) prints: (None, None, None). That means my test case is passed even if I am receiving below exception:

selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: {"method":"css selector","selector":"test"}

  • As sys.exc_info()) returns (None, None, None) execution won't done under if condition

So my major concern is why sys.exc_info()) returns (None, None, None) even if I am receiving NoSuchElementException ?

Pratik Patel
  • 2,209
  • 3
  • 23
  • 30
  • Possible duplicate of [Getting Python's unittest results in a tearDown() method](https://stackoverflow.com/questions/4414234/getting-pythons-unittest-results-in-a-teardown-method) – hoefling Jul 20 '18 at 19:08
  • The `sys.exc_info()` trick won't work in Python 3, so skip the accepted answer in the linked question and read through the rest. You could get much better solutions using `pytest`s fixtures, but it looks like you're writing pure `unittest` tests and only using `pytest` as test runner. – hoefling Jul 20 '18 at 19:11
  • Thanks. Yes, exactly I have written pure unittest and using pytest as test runner. Could you suggest me the best library for Python3 to make UI testcases with selenium ? – Pratik Patel Jul 21 '18 at 04:28
  • I don't think that any library will supersede `selenium`; most of the routine code around tests is too project-specific. – hoefling Jul 21 '18 at 12:27

1 Answers1

6

I use this to take screenshots of failed tests

@pytest.fixture()
def browser(request):
    options = Options()
    options.add_argument("--headless")  # Runs Chrome in headless mode.
    _chrome = webdriver.Chrome(options=options)
    failed_before = request.session.testsfailed
    yield _chrome
    if request.session.testsfailed != failed_before:
        test_name = request.node.name
        take_screenshot(_chrome, test_name)
    _chrome.close()


def take_screenshot(browser, test_name):
    screenshots_dir = "path_to/functional_tests/failure_screenshots"
    screenshot_file_path = "{}/{}.png".format(screenshots_dir, test_name)
    browser.save_screenshot(
        screenshot_file_path
    )
Javed
  • 5,904
  • 4
  • 46
  • 71
  • The tests have to use this same fixture for browsing, right? Otherwise I get all blank screenshots. – Noumenon Oct 24 '19 at 14:21