PhantomJS is a headless Webkit, which has a number of uses. In this example, we will be using it, in conjunction with Selenium WebDriver, for conducting unit tests directly from the command line. Since PhantomJS eliminates the need for a graphical browser, tests run much faster.
Click here to watch the accompanying video.
Setup
- Install Selenium
pip install selenium
- Then install PhantomJS with Brew:
brew install phantomjs
Or you can grab the latest build here.
Examples
Now let’s look at two quick examples.
DuckDuckGo
In the first, I’m just going to search DuckDuckGo for the keyword “realpython” to find the URL of the search results.
from selenium import webdriver driver = webdriver.PhantomJS() driver.get("http://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
You can see the outputted URL on the terminal.
Then here’s a look at the same thing using a Firefox to display the results.
from selenium import webdriver driver = webdriver.Firefox() driver.get("http://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
Now I can write a quick unit test to assert that the URL brought up by the search results is correct.
import unittest from selenium import webdriver class TestOne(unittest.TestCase): def setUp(self): self.driver = webdriver.PhantomJS() 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()
As you can tell the test passed.
RealPython.com
Finally, let’s look at a real world example that I run daily with Jenkins. Let’s go to RealPython.com and I’ll show you what I will be testing. Essentially, I want to ensure that the Buy Now popup is for the correct product.
Here’s a look at the basic unittest:
import unittest from selenium import webdriver class TestTwo(unittest.TestCase): def setUp(self): self.driver = webdriver.PhantomJS() def test_url(self): self.driver.get("http://www.realpython.com/") self.driver.find_element_by_class_name("simple-goods-btn").click() self.driver.switch_to_frame(1) self.assertIn("https://www.simplegoods.co/embed/XDGLSALS", self.driver.current_url) 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 much faster. In this next example I benchmarked 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("http://www.realpython.com/") self.driver.find_element_by_class_name("simple-goods-btn").click() self.driver.switch_to_frame(1) self.assertIn("https://www.simplegoods.co/embed/XDGLSALS", self.driver.current_url) def test_url_phantom(self): time.sleep(1) self.driver = webdriver.PhantomJS() self.driver.get("http://www.realpython.com/") self.driver.find_element_by_class_name("simple-goods-btn").click() self.driver.switch_to_frame(1) self.assertIn("https://www.simplegoods.co/embed/XDGLSALS", self.driver.current_url) 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:
转载请注明:jinglingshu的博客 » Headless Selenium Testing with Python and PhantomJS