-1

我写了一个SeleniumTestCase类,它在其中启动 PhantomJSsetUpClass并在它的tearDownClass. 但是,如果派生类setUpClass引发错误,PhantomJS 进程将挂起,因为SeleniumTestCase.tearDownClass没有被调用。

from django.test import LiveServerTestCase
import sys, signal, os
from selenium import webdriver

errorShots = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', "errorShots")

class SeleniumTestCase(LiveServerTestCase):
    @classmethod
    def setUpClass(cls):
        """
        Launches PhantomJS
        """
        super(SeleniumTestCase, cls).setUpClass()
        cls.browser = webdriver.PhantomJS()

    @classmethod
    def tearDownClass(cls):
        """
        Saves a screenshot if the test failed, and kills PhantomJS
        """
        print 'Tearing down...'

        if cls.browser:
            if sys.exc_info()[0]:
                try:
                    os.mkdir(errorShots)
                except:
                    pass

                errorShotPath = os.path.join(
                    errorShots, 
                    "ERROR_phantomjs_%s_%s.png" % (cls._testMethodName, datetime.datetime.now().isoformat())
                )
                cls.browser.save_screenshot(errorShotPath)
                print 'Saved screenshot to', errorShotPath
            cls.browser.service.process.send_signal(signal.SIGTERM)
            cls.browser.quit()


class SetUpClassTest(SeleniumTestCase):
    @classmethod
    def setUpClass(cls):
        print 'Setting Up'
        super(SetUpClassTest, cls).setUpClass()
        raise Error('gotcha!')

    def test1(self):
        pass

输出(注意“Tearing Down”没有被打印出来)

$ ./manage.py test
Creating test database for alias 'default'...
Setting Up
E
======================================================================
ERROR: setUpClass (trucks.tests.SetUpClassTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/andy/leased-on/trucks/tests.py", line 1416, in setUpClass
    raise Error('gotcha!')
NameError: global name 'Error' is not defined

----------------------------------------------------------------------
Ran 0 tests in 1.034s

FAILED (errors=1)
Destroying test database for alias 'default'...

setUpClass套件失败后如何杀死 PhantomJS ?我知道我可以切换到使用setUpand addCleanup,但我想避免在每次测试之前重新启动 PhantomJS(并使用它重新登录我的应用程序)。

4

1 回答 1

0

我决定使用setUpModuletearDownModule启动并杀死 PhantomJS。我把截图保存代码放在一个addCleanup钩子里。

from django.test import LiveServerTestCase
from selenium import webdriver
import sys
import signal
import os
import unittest

errorShots = os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', "errorShots")

browser = None

def setUpModule():
    """
    Launches PhantomJS
    """
    global browser
    sys.stdout.write('Starting PhantomJS...')
    sys.stdout.flush()
    browser = webdriver.PhantomJS()
    print 'done'

def tearDownModule():
    """
    kills PhantomJS
    """
    if browser:
        sys.stdout.write('Killing PhantomJS...')
        sys.stdout.flush()
        browser.service.process.send_signal(signal.SIGTERM)
        browser.quit()
        print 'done'

class SeleniumTestCase(LiveServerTestCase):
    def setUp(self):
        self.addCleanup(self.cleanup)

    def cleanup(self):
        """
        Saves a screenshot if the test failed
        """
        if sys.exc_info()[0]:
            try:
                os.mkdir(errorShots)
            except:
                pass

            errorShotPath = os.path.join(
                errorShots, 
                "ERROR_phantomjs_%s_%s.png" % (self._testMethodName, datetime.datetime.now().isoformat())
            )
            browser.save_screenshot(errorShotPath)
            print '\nSaved screenshot to', errorShotPath
于 2016-11-08T08:52:09.317 回答