- 7 Tem 2013
- 8,188
- 637
PhantomJS is a headless Webkit, which has a number of uses. In this example, well be using it, in conjunction with Selenium WebDriver, for conducting basic system tests directly from the command line. Since PhantomJS eliminates the need for a graphical browser, tests run much faster.
Setup
Install Selenium with Pip and PhantomJS with Homebrew:
Examples
Now lets look at two quick examples.
DuckDuckGo
In the first example, were just going to search DuckDuckGo for the keyword realpython to find the URL of the search results.
You can see the outputted URL in the terminal.
Heres a look at the same thing using Firefox to display the results.
Did you notice how we had to create a dummy browser size on the Phantom script? This is a workaround to a bug thats currently an issue in Github. Try the script without it: Youll get an ElementNotVisibleException exception.
Now we can write a quick test to assert that the URL brought up by the search results is correct.
The test passed.
RealPython.com
Finally, lets look at a real world example that I run daily. Navigate to RealPython.com and Ill show you what well be testing. Essentially, I want to ensure that the bottom Download Now button has the correct product associated with it.
Heres a look at the basic unittest:
Setup
Install Selenium with Pip and PhantomJS with Homebrew:
Kod:
$ pip install selenium
$ brew install phantomjs
Examples
Now lets look at two quick examples.
DuckDuckGo
In the first example, were just going to search DuckDuckGo for the keyword realpython to find the URL of the search results.
Kod:
from selenium import webdriver
driver = webdriver.PhantomJS()
driver.set_window_size(1120, 550)
driver.get("https://duckduckgo.com/")
driver.find_element_by_id('search_form_input_homepage').send_keys("realpython")
driver.find_element_by_id("search_button_homepage").click()
print(driver.current_url)
driver.quit()
Heres a look at the same thing using Firefox to display the results.
Kod:
from selenium import webdriver
driver = webdriver.Firefox()
driver.get("https://duckduckgo.com/")
driver.find_element_by_id('search_form_input_homepage').send_keys("realpython")
driver.find_element_by_id("search_button_homepage").click()
driver.quit()
Did you notice how we had to create a dummy browser size on the Phantom script? This is a workaround to a bug thats currently an issue in Github. Try the script without it: Youll get an ElementNotVisibleException exception.
Now we can write a quick test to assert that the URL brought up by the search results is correct.
Kod:
import unittest
from selenium import webdriver
class TestOne(unittest.TestCase):
def setUp(self):
self.driver = webdriver.PhantomJS()
self.driver.set_window_size(1120, 550)
def test_url(self):
self.driver.get("http://duckduckgo.com/")
self.driver.find_element_by_id(
'search_form_input_homepage').send_keys("realpython")
self.driver.find_element_by_id("search_button_homepage").click()
self.assertIn(
"https://duckduckgo.com/?q=realpython", self.driver.current_url
)
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main()
RealPython.com
Finally, lets look at a real world example that I run daily. Navigate to RealPython.com and Ill show you what well be testing. Essentially, I want to ensure that the bottom Download Now button has the correct product associated with it.
Heres a look at the basic unittest:
Kod:
import unittest
from selenium import webdriver
class TestTwo(unittest.TestCase):
def setUp(self):
self.driver = webdriver.PhantomJS()
def test_url(self):
self.driver.get("https://app.simplegoods.co/i/IQCZADOY") # url associated with button click
button = self.driver.find_element_by_id("payment-submit").get_attribute("value")
self.assertEquals(u'Pay - $60.00', button)
def tearDown(self):
self.driver.quit()
if __name__ == '__main__':
unittest.main()
Benchmarking
One main advantage of using PhantomJS over a browser is that tests are usually much faster. In this next example, well benchmark the previous test using both PhantomJS and Firefox.
import unittest
from selenium import webdriver
import time
class TestThree(unittest.TestCase):
def setUp(self):
self.startTime = time.time()
def test_url_fire(self):
time.sleep(2)
self.driver = webdriver.Firefox()
self.driver.get("https://app.simplegoods.co/i/IQCZADOY") # url associated with button click
button = self.driver.find_element_by_id("payment-submit").get_attribute("value")
self.assertEquals(u'Pay - $60.00', button)
def test_url_phantom(self):
time.sleep(1)
self.driver = webdriver.PhantomJS()
self.driver.get("https://app.simplegoods.co/i/IQCZADOY") # url associated with button click
button = self.driver.find_element_by_id("payment-submit").get_attribute("value")
self.assertEquals(u'Pay - $60.00', button)
def tearDown(self):
t = time.time() - self.startTime
print("%s: %.3f" % (self.id(), t))
self.driver.quit()
if __name__ == '__main__':
suite = unittest.TestLoader().loadTestsFromTestCase(TestThree)
unittest.TextTestRunner(verbosity=0).run(suite)
You can see just how much faster PhantomJS is:
$ python test.py -v
__main__.TestThree.test_url_fire: 19.801
__main__.TestThree.test_url_phantom: 10.676
----------------------------------------------------------------------
Ran 2 tests in 30.683s
OK