1.一个用例为一个完整的场景,从用户登陆系统到最终退出并关闭浏览器。

2.一个用例只验证一个功能点,不要试图在用户登陆系统后把所有的功能都验证一遍。

3.尽可能少的编写逆向逻辑用例。一方面因为逆向逻辑的用例很多(例如。手机号输错有十几种情况);另外一方面自动化本身比较脆弱,复杂的逆向逻辑用例实现起来比较麻烦且容易出错。

4.用例与用例之间尽量避免产生依赖。

5.一条测试用例完成测试后需要对测试场景进行还原,以避免影响其他测试用例的执行。

driver.py

 from selenium.webdriver import Remote
from selenium import webdriver # 启动浏览器驱动
def browser():
# driver = webdriver.Firefox()
host = '127.0.0.1:4444' # 运行主机:端口号(本机默认:127.0.0.1:4444)
dc = {'browserName': 'firefox'} # 指定浏览器('chrome','firefox')
driver = Remote(command_executor = 'http://' + host + '/wd/hub,desired_capabilities = dc')
return driver
if __name__ == '__main__':
dr = browser()
dr.get('http://www.baidu.com')
dr.quit()

定义浏览器驱动函数browser()该函数可以进行配置,根据我们的需求,配置测试用例在不同的主机及浏览器下运行。

2.自定义测试框架类:

 from selenium import webdriver
from .driver import browser
import unittest
import os class MyTest (unittest.TestCase):
def setUp(self):
self.driver = browser ()
self.driver.implicitly_wait (10)
self.driver.maximize_window () def tearDown(self):
self.driver.quit ()

定义MyTest()类用于继承unittest.TestCase类,因为创建的所有测试类中setUp()与tearDown()方法所做的事情相同。所以将他们抽象为MyTest()类,好处就是编写测试用例不再去考虑这两个方法的实现。

3.定义截图函数

获取路径参考:https://www.cnblogs.com/wuxie1989/p/5623435.html

from selenium import webdriver
import os # 截图函数
def insert_img(driver, file_name):
# 获取路径名:os.path.dirname() 获取文件所在目录的完整路径:os.path.dirname(__file__)
base_dir = os.path.dirname(os.path.dirname(__file__))
print(base_dir)
base_dir = str(base_dir) # 将地址转为字符串
print(base_dir)
base_dir = base_dir.replace('/', '\\')
print(base_dir)
base = base_dir.split('/test_case')[0] # 以/test_case为分隔符,取第一个分割的部分
print(base)
file_path = base + "\\report\\image\\" + file_name
print(file_path)
driver.save_screenshot(file_path) if __name__ == '__main__':
driver = webdriver.Firefox()
driver.get("https://www.baidu.com")
insert_img(driver, 'baidu.png')
driver.quit()

创建截图函数insert_img(),为了保持自动化项目的移植性,采用相对路径的方法hi将测试截图保存到.\report\image\目录中

注:运行代码没有错,但是却无法获得截图保存路径?????(望知道原因的留言指点)

编写Page Object

首先创建基础类:E:\python\mztestpro\bbs\test_case\page_obj\base.py

class Page (object):
"""
页面基础类,用于所有页面的继承
"""
bbs_url = 'http://bbs.meizu.cn' def __init__(self, selenium_driver, base_url=bbs_url, parent=None):
self.base_url = base_url
self.driver = selenium_driver
self.timeout = 30
self.parent = parent def __open(self, url):
url = self.base_url + url
self.driver.get(url)
assert self.on_page(), 'did not land on %s' % url def find_element(self, *loc):
return self.driver.find_element(*loc) def open(self):
self.__open(self.url) def on_page(self):
return self.driver.current_url == (self.base_url + self.url) def script(self, src):
return self.driver.execute_script(src)

创建页面基础类,通过_init_()方法初始化参数:浏览器驱动,URL地址,超时时长等。定义的基本方法:open()用于打开BBS地址;find_element()和find_element()分别用来定位单个与多个

元素;创建script()方法可以更简便的调用JavaScript代码。

创建BBS登录对象类:

E:\python\mztestpro\bbs\test_case\page_obj\loginPage.py

 from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.by import By
from time import sleep
import base class login (base.Page):
"""
用户登录界面
"""
url = '/'
# Action
bbs_login_user_loc = (By.XPATH, "//div[@id='mzCust']/div/img")
bbs_login_button_loc = (By.ID, "mzLogin") def bbs_login(self):
self.find_element (*self.bbs_login_user_loc).click ()
sleep (3)
self.find_element (*self.bbs_login_button_loc).click () login_username_loc = (By.ID, "account")
login_password_loc = (By.ID, "password")
bbs_login_button_loc = (By.ID, "login") # 登录用户名
def login_username(self, username):
self.find_element (*self.login_username_loc).send_keys (username) # 登录密码
def login_password(self, password):
self.find_element (*self.login_password_loc).send_keys (password) # 登录按钮
def login_button(self):
self.find_element (*self.login_password_loc).click () # 定义统一登录接口
def user_login(self, username="username", password=""):
# 获取用户名与登录密码
self.open ()
self.bbs_login ()
self.login_username (username)
self.login_password (password)
self.login_button ()
sleep (1) user_error_hint_loc = (By.XPATH, "//span[@for = 'account']")
pawd_error_hint_loc = (By.XPATH, "//span[@for = 'password']")
user_login_success_loc = (By.ID, "mzCustName") # 用户名错误提示
def user_error_hint(self):
return self.find_element (*self.user_error_hint_loc).text
# 密码错误提示 def paw_error_hint(self):
return self.find_element (*self.pawd_error_hint_loc).text # 登录成功用户名
def user_login_success(self):
return self.find_element (*self.user_login_success_loc).text 创建登录页面对象,对用户登录面上的用户名/密码输入框,登录按钮和提示信息等元素的定位进行封装。除此之外,还创建user_login()方法作为系统统一登录的入口。关于对操作步骤的封装
既可以放在page object当中,也可以放在测试用例当中。这主要根据具体需求来衡量。这里之所以存放在Page_object当中,主要考虑到还有其他用例会挑用到该登录方法。
为username和password
入参设置了默认值是为了方便其他测试y用例在调用user_login()时不用再传递登录用户信息,因为该系统大多用例的执行使用该账号即可,同时也方便了在这账号失效时的修改。

编写测试用例

编写测试用例时会集中精力考虑用例的设计和实现。

路径:E:\python\mztestpro\bbs\test_case\login_sta.py

此处注意文件名的创建。例如:假设登录页的对象名为loginPage.py,那么关于测试登录的文件应该命名为login_sta.py,方便用例报错时问题的追踪。

 import random
import sys
import unittest
from time import sleep sys.path.append("./models") import myTest
import function
from myunit import * sys.path.append("./page_obj")
from loginPage import * class loginTest(myunit.myTest):
""" 社区登录测试 """ # 测试用户登录
def user_login_verify(self, username="", password=""):
login(self.driver).user_login(username, password) def test_login(self):
"""用户名、密码为空登录"""
self.user_login_verify()
po = login(self.driver)
self.assertEqual(po.user_error_hint(), "账号不能为空")
self.assertEqual(po.pawd_error_hint(), "密码不能为空")
function.insert_img(self.driver, "user_pawd_empty.jpg") def test_login2(self):
"""用户名正确,密码为空登录"""
self.user_login_verify(username="py1test")
po = login(self.driver)
self.assertEqual(po.pawd_error_hint(), "密码不能为空")
function.insert_img(self.driver, "pawd_empty.jpg") def test_login3(self):
"""用户名为空,密码正确"""
self.user_login_verify(password="abc123456")
po = login(self.driver)
self.assertEqual(po.user_error_hint(), "账号不能为空")
function.insert_img(self.driver, "user_empty.jpg") def test_login4(self):
"""用户名与密码不匹配"""
character = random.choice('wqwertyuiop')
username = "zhangsan" + character
self.user_login_verify(username=username, password='')
po = login(self.driver)
self.assertEqual(po.pawd_error_hint(), "密码与账号不匹配")
function.insert_img(self.drive.jpg) def test_login5(self):
"""用户名、密码正确"""
self.user_login_verify(username="zhangsan", password="")
sleep(2)
po = login(self.driver)
self.assertEqual(po.user_login_success(), "张三")
function.insert_img(self.driver, "user_pawd_ture.jpg") if __name__ == "__main__":
unittest.main()

注:上面代码运行会有报错,可以引入模块换为:

import random
import sys
import unittest
from time import sleep from test_case.page_obj.loginPage import login
from test_case.models.function import insert_img
from test_case.models.myunit import MyTest
 

selenium+python之自动换测试用例执行的更多相关文章

  1. python利用unittest进行测试用例执行的几种方式

      利用python进行测试时,测试用例的加载方式有2种:  一种是通过unittest.main()来启动所需测试的测试模块:  一种是添加到testsuite集合中再加载所有的被测试对象,而tes ...

  2. Python+selenium之unittest单元测试(3)关于测试用例执行的顺序

    一.测试用例执行的顺序 用例的执行顺序涉及多个层级,在多个测试目录的情况下,先执行哪个目录?在多个测试文件的情况下,先执行哪个文件?在多个测试类的情况下,先执行哪个测试类?,在多个测试方法(用例)的情 ...

  3. selenium python bindings 写测试用例

    这章总结selenium在UI测试方面的用法 import unittest from selenium import webdriver from selenium.webdriver.common ...

  4. 7.Selenium+Python实现搜索百度的测试用例

    1.导入测试用例需要的模块,unittest是python的内置模块,它提供了组织测试用例的框架 import unittest # 导入测试用例的模块 2.测试用例继承于unittest class ...

  5. Python实现正交实验法自动设计测试用例

    1.简介 正交试验法是研究多因素.多水平的一种试验法,它是利用正交表来对试验进行设计,通过少数的试验替代全面试验,根据正交表的正交性从全面试验中挑选适量的.有代表性的点进行试验,这些有代表性的点具备了 ...

  6. Python 一键拉取Git分支源码自动解析并执行SQL语句

    基于Python实现自动拉取Git分支源码自动解析并执行SQL语句 by:授客 QQ:1033553122 1.代码用途 开发过程中,研发人员会提交SQL更新脚本到Git源码库,然后测试负责去拉取这些 ...

  7. python基础===利用unittest进行测试用例执行的几种方式

    利用python进行测试时,测试用例的加载方式有2种:  一种是通过unittest.main()来启动所需测试的测试模块:  一种是添加到testsuite集合中再加载所有的被测试对象,而tests ...

  8. Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建;学习Python语言,利用Python语言来写测试用例。加油!!!

    Python+selenium测试环境成功搭建,简单控制浏览器(firefox)接下来,继续学习其他浏览器上的测试环境搭建:学习Python语言,利用Python语言来写测试用例.加油!!!

  9. python web自动化测试框架搭建(功能&接口)——测试用例执行和结果收集

    由于unittest框架中结果收集在不同文件中,所以此处重写结果收集方法,加入执行时间,失败信息,失败截图等 TestRunner.py # coding=utf-8 import sys impor ...

随机推荐

  1. mysql的SQL_CALC_FOUND_ROWS /FOUND_ROWS()

    在很多分页的程序中都这样写: SELECT COUNT(*) from `table` WHERE ......;  查出符合条件的记录总数 SELECT * FROM `table` WHERE . ...

  2. hive-0.11.0安装

    一.安装  .        下载安装hive hive-0.11.0.tar.gz(稳定版) 目录:/data tar –zxvfhive-0.11.0.tar.gz .        配置 把所有 ...

  3. NFS资料

      Linux NFS服务器的安装与配置 http://www.cnblogs.com/mchina/archive/2013/01/03/2840040.html Linux NFS服务器的安装与配 ...

  4. 获得用户IP、城市、国家等信息的api接口

    1 这个信息比较多 https://api.ipdata.co/?api-key=test <script> $.get("https://api.ipdata.co?api-k ...

  5. Hadoop 2.7.3 HA 搭建及遇到的一些问题

    看了Hadoop的一个7天视频教程,里面给出了搭建的详细步骤,教程中是按2.4.1版本搭建的,我用的是2.7.3版本,好像没什么差别.下面是抄过来的,加了一点注释. hadoop2.0已经发布了稳定版 ...

  6. XXy

    XXy codevs1003 帮我看看 #include<iostream> #include<cstdio> using namespace std; ],map[][],n ...

  7. [Xcode 实际操作]七、文件与数据-(5 )复制、移动、删除文件和删除文件夹

    目录:[Swift]Xcode实际操作 本文将演示如何复制.移动和删除文件. 在项目导航区,打开视图控制器的代码文件[ViewController.swift] import UIKit class ...

  8. SPA单页应用前后分离微信授权

    项目基于微信公众号开发,业务完全依赖微信授权,也就是用户进入页面已经完成授权获取到用户的OpenId. 需要有一个授权中间页:author.vue 基本实现思路: 无论使用哪个url进入页面都会先触发 ...

  9. Eclipse集成Git的实践

    最近一直在研究爬虫的相关技术,网上关于爬虫的教程实在是太少了,只能靠一些零零散散的博客资料做一个浅度的学习,我们已经学习了webcollector,htmlparser,Jsoup这些爬虫技术,并也成 ...

  10. 关于setTimeout(fn,0)

    JS是单线程引擎:它把任务放到队列中,不会同步去执行,必须在完成一个任务后才开始另外一个任务. 浏览器的内核是多线程的,它们在内核制控下相互配合以保持同步,一个浏览器至少实现三个常驻线程:javasc ...