如果派生类'可靠地杀死在setUpClass中启动的phantomjs。 setUpClass失败

时间:2016-11-08 04:27:11

标签: unit-testing selenium-webdriver test-suite resource-cleanup teardown

我写了一个SeleniumTestCase类,在其setUpClass中启动PhantomJS并在其tearDownClass中杀死它。但是,如果派生类' setUpClass引发错误,因为SeleniumTestCase.tearDownClass没有被调用,所以PhantomJS进程处于悬空状态。

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

输出(请注意"拆除"不打印)

$ ./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? 我知道我可以切换到使用setUpaddCleanup,但我希望在每次测试之前避免重新启动PhantomJS(并使用它重新登录我的应用程序)。

1 个答案:

答案 0 :(得分:0)

我决定使用setUpModule and tearDownModule启动并杀死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