Web登录测试是很常见的测试!但是对于我这个测试新手来说,自动化却是一头雾水。最近在看python+selenium相关的内容,也开始尝试自己写脚本,遇到各种各种的问题,经过参照了好多大神的帖子,终于完成了一个简单的且有测试报告的登陆脚本。
1.本脚本基于Python3.6.0+selenium-3.0.2+HTMLTestRunner,所以第一步就是先下载Python3.6.0官网传送门
2.安装完Python后,如果环境变量没有添加成功,手动添加环境变量C:\Python36;C:\Python36\Scripts;C:\Python36\Lib\site-packages(根据实际安装目录相应修改)
3.打开cmd运行 pip install selenium 安装selenium-3.0.2或者官网传送门
4.下载driver调用浏览器,将chromedriver.exe或者geckodriver.exe复制到安装目录下C:\Python36
注意:下方两个下载地址都是32位的,需要64位的驱动需另行下载
chrmoedriver(点击下载)是用来调用谷歌浏览器;geckodriver(点击下载)用来调用火狐浏览器;
IE好像会有点问题所有没下载,如需要去网上下载即可(对应的driver必须要有该浏览器才能调用开启)
5.下载HTMLTestRunner.py(点击下载),该文件可以直接使用(已被我参照其他大神的帖子汉化,且适合Python3.X,及修复其他显示问题。也就可以按照本文最后几个参照网址自行修改)
6.将HTMLTestRunner.py复制到C:\Python36\lib 目录下(根据实际安装目录相应修改)
7.在开始菜单找Pyhton IDLE(可以快捷方式到桌面),打开python脚本,或者Ctrl+N新建脚本,F5执行脚本。一切准备工作做完后,可以开始创建测试脚本了,脚本如下:
# -*- coding:utf-8 -*-
'''
jpg登录测试,分下面几种情况:
(1)用户名、密码正确
(2)用户名正确、密码不正确
(3)用户名正确、密码为空
(4)用户名错误、密码正确
(5)用户名为空、密码正确
(还有其他情况,如无权限用户,被锁定用户等,就不出来了)
'''
'''
加入需要的python库:
unittest为python的测试框架
webdriver为python的selenium下的库
sleep为睡眠时间,类似于lr的思考时间,页面停留,也可以直接写import time,但是用法就是time.sleep()
os是为了创建目录time获取日期和时间
'''
import unittest
from selenium import webdriver
from time import sleep
import os
import time
#定义打开浏览器的方法,这里用的是Chrome,火狐为Firfox,IE为Ie,必须在根目录下对应的driver才能调用
dr = webdriver.Chrome()
#浏览器最大化
dr.maximize_window()
#创建测试类LoginCase,用unittest的测试框架的格式
class LoginCase(unittest.TestCase):
#定义登录方法,被测试用例调用
def login(self, username, password):
#需要测试的网页
dr.get('https://passport.cnblogs.com/user/signin')
#需要输入的用户名,变量名和方法中的一致,find_element_by_id('input1')为抓取到的用户名的输入框,用谷歌或者火狐F12可以抓取到
dr.find_element_by_id('input1').send_keys(username)
#需要输入的密码,变量名和方法中的一致,find_element_by_id('input2')为抓取到的密码的输入框
dr.find_element_by_id('input2').send_keys(password)
#点击登陆按钮,find_element_by_id('signin')为抓取到的登陆按钮,click()为点击事件
dr.find_element_by_id('signin').click() #点击登陆按钮
#定义测试方法,框架中测试方法以test_开头,底下引号中的中文会在报告中显示,利于清楚的知道测试目的
def test_login_success(self):
'''用户名、密码正确'''
self.login('xxxx', 'xxxxx') #调用定义的login方法,传入正确用户名和密码
sleep(1)
#可以用get_screenshot_as_file方法用来截图,可自定义截图后的保存位置和图片命名
dr.get_screenshot_as_file(path+"login_success.jpg")
#定义了一个实际值,用谷歌或者火狐F12可以抓取到登陆后显示的用户名,.text是获取地址的文本值
#assert先判断需要的实际值是否正确,正确,继续运行用例;如果不正确,不继续运行该用例并返回错误
assert dr.find_element_by_id('lnk_current_user').text,'判断的元素错误,请确认!'
#将实际值赋值给一个变量link,方便比较,可自定义
link = dr.find_element_by_id('lnk_current_user').text
#用assertTrue(x)方法来断言,登录成功后预期的值是否和定义的实际值一致
self.assertTrue('星辰_test' in link)
def test_login_pwd_error(self):
'''用户名正确、密码不正确'''
self.login('1', '1') #正确用户名,错误密码
sleep(1)
dr.get_screenshot_as_file(path+"login_password_error.jpg")
assert dr.find_element_by_id("tip_btn").text,'提示信息类型错误!'
error_message = dr.find_element_by_id('tip_btn').text
self.assertIn('用户名或密码错误',error_message) #用assertIn(a,b)方法来断言
def test_login_pwd_null(self):
'''用户名正确、密码为空'''
self.login('1', '') #密码为空
sleep(1)
dr.get_screenshot_as_file(path+"login_password_null.jpg")
assert dr.find_element_by_id("tip_input2").text,'提示信息类型错误!'
error_message = dr.find_element_by_id('tip_input2').text
self.assertEqual(error_message,'请输入密码') #用assertEqual(a,b)方法来断言
def test_login_user_error(self):
'''用户名错误、密码正确'''
self.login('1', '1') #密码正确,用户名错误
sleep(1) dr.get_screenshot_as_file(path+"login_username_error.jpg")
assert dr.find_element_by_id("tip_btn").text,'提示信息类型错误!'
error_message = dr.find_element_by_id('tip_btn').text
self.assertIn('该用户不存在',error_message) #用assertIn(a,b)方法来断言 a in b
def test_login_user_null(self):
'''用户名为空、密码正确'''
self.login('', '1') #用户名为空,密码正确
sleep(1)
dr.get_screenshot_as_file(path+"login_username_null.jpg")
assert dr.find_element_by_id("tip_input1").text,'提示信息类型错误!'
error_message = dr.find_element_by_id('tip_input1').text
self.assertEqual(error_message,'请输入登录用户名') #用assertEqual(a,b)方法来断言
#每个test_执行完执行一次tearDown()方法
def tearDown(self):
sleep(1)
#refresh()方法为刷新浏览器
dr.refresh()
if __name__ == '__main__':
#导入HTMLTestRunner库,这句也可以放在脚本开头
from HTMLTestRunner import HTMLTestRunner
#定义脚本标题,加u为了防止中文乱码
report_title = u'登陆模块测试报告'
#定义脚本内容,加u为了防止中文乱码
desc = u'博客园登陆模块测试报告详情:'
#定义date为日期,time为时间
date=time.strftime("%Y%m%d")
time=time.strftime("%Y%m%d%H%M%S")
#定义path为文件路径,目录级别,可根据实际情况自定义修改
path= 'D:/Python_test/'+ date +"/login/"+time+"/"
#定义报告文件路径和名字,路径为前面定义的path,名字为report(可自定义),格式为.html
report_path = path+"report.html"
#判断是否定义的路径目录存在,不能存在则创建
if not os.path.exists(path):
os.makedirs(path)
else:
pass
#定义一个测试容器
testsuite = unittest.TestSuite()
#将测试用例添加到容器
testsuite.addTest(LoginCase("test_login_success"))
testsuite.addTest(LoginCase("test_login_pwd_error"))
testsuite.addTest(LoginCase("test_login_pwd_null"))
testsuite.addTest(LoginCase("test_login_user_error"))
testsuite.addTest(LoginCase("test_login_user_null"))
#将运行结果保存到report,名字为定义的路径和文件名,运行脚本
with open(report_path, 'wb') as report:
runner = HTMLTestRunner(stream=report, title=report_title, description=desc)
runner.run(testsuite)
#关闭report,脚本结束
report.close()
#关闭浏览器
dr.quit()
注:该脚本只需要修改正确的帐号密码输入就能跑通,或者将自己要测试url,抓取到元素,和帐密修改,就是一个新的登陆脚本。报告输出地址可以自修改,脚本运行后,自动创建目录和报告。
运行后,IDLE也会显示正在执行的用例和用例通过的状态,OK为通过,F为失败,E为错误
最后可以在脚本中可以适当的添加一些print,会写入到html报告中,报告会更直观。不知道为什么看了好多大神处理验证码的帖子,也跟着做了,还是搞不定,所以该脚本不适合需要验证码的登陆,不过可以找开发兄弟屏蔽验证码或者设置万能验证码。
完成该脚本参照了以下网址的内容进行整合修改而成:
登陆脚本参照:传送门
报告中文化及界面调整参照:传送门
执行测试用例的过程中,不打印运行的用例参照:传送门
HTMLTestRunner.py的python2.X版改3.X版参照:传送门
完美解决HTMLTestRunner错误日志显示出界面问题:传送门