Python网络数据采集7-单元测试与Selenium自动化测试
Python网络数据采集7-单元测试与Selenium自动化测试
单元测试
Python中使用内置库unittest可完成单元测试。只要继承unittest.TestCase类,就可以实现下面的功能。
- 为每个单元测试的开始和结束提供
setUp和tearDown函数。 - 提供不同类型的断言让测试成功或者失败
- 所有以
test_打头的函数,都会当成单元测试来运行,他们彼此独立,互不影响。
下面来看一个简单的例子
import unittest
class TestSimple(unittest.TestCase):
def setUp(self):
print('set up')
def test_simple(self):
a = 2
l = [2, 3, 43]
self.assertIn(a, l)
def tearDown(self):
print('teardown')
if __name__ == '__main__':
unittest.main(argv=['ignored', '-v'], exit=False)
test_simple (__main__.TestSimple) ...
set up
teardown
ok
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK
在Jupyter中,main()需要填入以上参数才能运行,参数列表中第一个参数会被忽略,而exit=False则不会kill掉kernel。详见stackoverflow
但是在Pycharm中运行则不会任何参数。
测试维基百科
将Python的单元测试和网络爬虫结合起来,就可以实现简单的网站前端功能测试。
import requests
from bs4 import BeautifulSoup
import unittest
class TestWiki(unittest.TestCase):
soup = None
def setUp(self):
global soup
r = requests.get('https://en.wikipedia.org/wiki/Monty_Python')
soup = BeautifulSoup(r.text, 'lxml')
def test_title(self):
global soup
title = soup.h1.string
self.assertEqual(title, 'Monty Python')
def test_content_exists(self):
global soup
content = soup.find('div', id='mw-content-text')
self.assertIsNotNone(content)
if __name__ == '__main__':
unittest.main(argv=['ignored', '-v'], exit=False)
test_simple (__main__.TestSimple) ... ok
test_content_exists (__main__.TestWiki) ...
set up
teardown
D:\Anaconda3\lib\site-packages\bs4\builder\_lxml.py:250: DeprecationWarning: inspect.getargspec() is deprecated, use inspect.signature() or inspect.getfullargspec()
self.parser.feed(markup)
ok
test_title (__main__.TestWiki) ... ok
----------------------------------------------------------------------
Ran 3 tests in 3.651s
OK
Selenium单元测试
如果使用selenium进行网站测试呢?(它的初衷就是用来干这个的)
from selenium import webdriver
driver = webdriver.PhantomJS(executable_path=r'C:\Program Files (x86)\phantomjs\bin\phantomjs.exe')
driver.get('https://en.wikipedia.org/wiki/Monty_Python')
print(driver.title)
assert 'Monty Python' in driver.title
Monty Python - Wikipedia
from selenium import webdriver
driver = webdriver.PhantomJS(executable_path=r'C:\Program Files (x86)\phantomjs\bin\phantomjs.exe')
driver.get('http://pythonscraping.com/pages/files/form.html')
# 找到输入框和提交按钮
first_name = driver.find_element_by_name('firstname')
last_name = driver.find_element_by_name('lastname')
submit = driver.find_element_by_id('submit')
# 输入
first_name.send_keys('admin')
last_name.send_keys('Sun')
# 提交
submit.click()
print(driver.find_element_by_tag_name('body').text)
driver.close()
Hello there, admin Sun!
或者使用动作链。
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ActionChains
driver = webdriver.PhantomJS(executable_path=r'C:\Program Files (x86)\phantomjs\bin\phantomjs.exe')
driver.get('http://pythonscraping.com/pages/files/form.html')
# 找到输入框和提交按钮
first_name = driver.find_element_by_name('firstname')
last_name = driver.find_element_by_name('lastname')
submit = driver.find_element_by_id('submit')
actions = ActionChains(driver).send_keys_to_element(first_name, 'admin') \
.send_keys_to_element(last_name, 'Sun') \
.send_keys(Keys.ENTER)
# 执行动作链
actions.perform()
print(driver.find_element_by_tag_name('body').text)
driver.close()
Hello there, admin Sun!
除了简单的单击双击,发送文本到输入框,还能实现复杂的动作。比如拖放。
from selenium import webdriver
from selenium.webdriver import ActionChains
driver = webdriver.Firefox()
driver.get('http://pythonscraping.com/pages/javascript/draggableDemo.html')
print(driver.find_element_by_id('message').text)
element = driver.find_element_by_id('draggable')
target = driver.find_element_by_id('div2')
actions = ActionChains(driver).drag_and_drop(element, target)
actions.perform()
print(driver.find_element_by_id('message').text)
driver.close()
Prove you are not a bot, by dragging the square from the blue area to the red area!
You are definitely not a bot!
上面的代码用FireFox可以成功,Chrome和PhantomJs不成功,不知道为什么。先是打印了未拖拽方块时候显示的文字,当将方块拖到下面的div区域之后,页面上的文字变化了。
Selenium还有个有意思的功能--截屏。
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver import ActionChains
driver = webdriver.PhantomJS(executable_path=r'C:\Program Files (x86)\phantomjs\bin\phantomjs.exe')
driver.get('https://www.pythonscraping.com/')
driver.get_screenshot_as_file('screenshot.png')
True
保存成功就会返回打印True。
Selenium与单元测试结合
还是面拖拽的例子,加入了Python单元测试与Selenium结合使用。
from selenium import webdriver
from selenium.webdriver import ActionChains
import unittest
class TestSelenium(unittest.TestCase):
driver = None
def setUp(self):
global driver
driver = webdriver.Firefox()
driver.get('http://pythonscraping.com/pages/javascript/draggableDemo.html')
def test_drag(self):
global driver
element = driver.find_element_by_id('draggable')
target = driver.find_element_by_id('div2')
actions = ActionChains(driver).drag_and_drop(element, target)
actions.perform()
self.assertEqual('You are definitely not a bot!', driver.find_element_by_id('message').text)
if __name__ == '__main__':
unittest.main(argv=['ignored', '-v'], exit=False)
test_drag (__main__.TestSelenium) ... ok
test_simple (__main__.TestSimple) ... ok
test_content_exists (__main__.TestWiki) ...
set up
teardown
D:\Anaconda3\lib\site-packages\bs4\builder\_lxml.py:250: DeprecationWarning: inspect.getargspec() is deprecated, use inspect.signature() or inspect.getfullargspec()
self.parser.feed(markup)
ok
test_title (__main__.TestWiki) ... ok
----------------------------------------------------------------------
Ran 4 tests in 23.923s
OK
依然得使用FireFox, 以及main中加上参数argv=['ignored', '-v'], exit=False。看打印结果,上面的测试也执行了,好像在Jupyter中,虽然在一个Cell中执行单元测试,所有测试都会得到执行。普通Python代码就不是这样,每个Cell独立运行,还可以使用上面Cell定义过的变量和已经导入的库。
by @sunhaiyu
2017.7.19
Python网络数据采集7-单元测试与Selenium自动化测试的更多相关文章
- [python] 网络数据采集 操作清单 BeautifulSoup、Selenium、Tesseract、CSV等
Python网络数据采集操作清单 BeautifulSoup.Selenium.Tesseract.CSV等 Python网络数据采集操作清单 BeautifulSoup.Selenium.Tesse ...
- 笔记之Python网络数据采集
笔记之Python网络数据采集 非原创即采集 一念清净, 烈焰成池, 一念觉醒, 方登彼岸 网络数据采集, 无非就是写一个自动化程序向网络服务器请求数据, 再对数据进行解析, 提取需要的信息 通常, ...
- Python网络数据采集PDF高清完整版免费下载|百度云盘
百度云盘:Python网络数据采集PDF高清完整版免费下载 提取码:1vc5 内容简介 本书采用简洁强大的Python语言,介绍了网络数据采集,并为采集新式网络中的各种数据类型提供了全面的指导.第 ...
- Python网络数据采集6-隐含输入字段
Python网络数据采集6-隐含输入字段 selenium的get_cookies可以轻松获取所有cookie. from pprint import pprint from selenium imp ...
- Python网络数据采集4-POST提交与Cookie的处理
Python网络数据采集4-POST提交与Cookie的处理 POST提交 之前访问页面都是用的get提交方式,有些网页需要登录才能访问,此时需要提交参数.虽然在一些网页,get方式也能提交参.比如h ...
- Python网络数据采集3-数据存到CSV以及MySql
Python网络数据采集3-数据存到CSV以及MySql 先热热身,下载某个页面的所有图片. import requests from bs4 import BeautifulSoup headers ...
- Python网络数据采集2-wikipedia
Python网络数据采集2-wikipedia 随机链接跳转 获取维基百科的词条超链接,并随机跳转.可能侧边栏和低栏会有其他链接.这不是我们想要的,所以定位到正文.正文在id为bodyContent的 ...
- Python网络数据采集1-Beautifulsoup的使用
Python网络数据采集1-Beautifulsoup的使用 来自此书: [美]Ryan Mitchell <Python网络数据采集>,例子是照搬的,觉得跟着敲一遍还是有作用的,所以记录 ...
- Python网络数据采集PDF
Python网络数据采集(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/16c4GjoAL_uKzdGPjG47S4Q 提取码:febb 复制这段内容后打开百度网盘手 ...
随机推荐
- jQuery.validate 的form校验
jQuery验证框架 : 基本html代码: <script src="js/jquery-1.9.1.js"></script> <script s ...
- 【DG】[三思笔记]一步一步学DataGuard
[DG][三思笔记]一步一步学DataGuard 它有无数个名字,有人叫它dg,有人叫它数据卫士,有人叫它data guard,在oracle的各项特性中它有着举足轻理的地位,它就是(掌声)..... ...
- vue实现标签云效果
闲扯两句 最近想给自己的博客上加上一个3D标签云的效果,用来表示自己博客文章的分组,网上找到了canvas实现的,还有a元素实现的解析3D标签云,我想让标签可以选择和点击,又不想在标签数量较多时操作a ...
- WCF学习——构建第二个WCF应用程序(四)
一.WCF服务端应用程序 1.创建WCF服务端应用程序项目 打开Visual Studio 2013,在菜单上点击文件->新建->项目->WCF服务应用程序.在弹出界面的" ...
- Linux常用操作命令(一)
java程序员要学习一些linux知识 java程序员要学习一些linux知识,下面就是您要学的命令:大型J2EE应用都在建构在linux环境下的.开发环境下我们可以通过samba映射成本地的网络驱动 ...
- 最长非降子序列的O(n^2)解法
这次我们来讲解一个叫做"最长非下降子序列"的问题及他的O(n^2)解法. 首先我们来描述一下什么是"最长非下降子序列". 给你一个长度为n的数组a,在数组a中顺 ...
- MyBatis源码解析【1】准备工作
终于迎来了这一天,我觉得现在的我在经历了长时间的学习和开发之后有了一定的经验,所以准备开始学习源码. 今天我将做好充足的准备,在接下来的一个月中,努力的爬过这座大山.(可能不用一个月,但是我觉得需要仔 ...
- Watson Explorer Analytical Components 1
Introduction: IBM Watson Explorer Analytical Components(AC) which is part of the IBM Watson Explorer ...
- JFile的导入xlsx与xls
首先需要有JAVA的一些jar包 下载地址:http://download.csdn.net/detail/qq_35980546/9892511 你要先配置好路由,还有能拿到绝对路径才行 下面直接给 ...
- JavaScript创建对象的方法
显示在浏览器中的控制台中. <script type="text/javascript"> //这个工厂方法返回一个新的"范围对象" functio ...