题记
本文主要讲述不在框架下和在pytest框架下selenium如何解决用例之间的依赖问题。
问题情境
有这样一种现象,想要发布文章或者删除文章内容,必须通过登录后才可以对具体功能操作,那么我们就必须解决用例依赖问题。
或者你可能会想到传url地址直接传入发布文章地址不可以么。我这样操作后,前端返回的页面还是登录页面,可见这样操作是不可以的。
非框架下用例依赖
下面我们来看看不在框架内怎么实现用例之间的依赖,有两个地方需要注意。
初始化函数和main()函数
main函数用例设计时,根据用例前后顺序设计:
实例化登录类->调用登录成功函数-》实例化文章发布类(login作为参数传入)。
if __name__ == '__main__': #实例化登录类 login = Test_admin_login() #调用登录成功函数 login.login_success() #实例化文章发布类 testArticle = TestArticle(login) #调用发布文章成功函数 testArticle.test_add_ok() |
初始化函数:传入login而非driver
初始化函数:
def __init__(self, login): self.login = login |
pytest框架下用例依赖
主要借助于@pytest.mark.dependency函数实现。
使用方法:
1.首先在被依赖函数前标记@pytest.mark.dependency();
2.然后再依赖函数前@pytest.mark.dependency(depends=["‘被依赖函数名称’"])。
import pytest @pytest.mark.dependency() def test_01(test): assert False @pytest.mark.dependency(depends=["test_01"]) def test_02(test): print("执行测试2") |
下面我们看看登录及文章分类的用例:
被依赖函数登录功能
使用@pytest.mark.dependency(name='admin_login')标记依赖函数:test_admin.py。
import time import pytest from selenium import webdriver #将webdriver驱动导入selenium框架中 from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.support.wait import WebDriverWait from util.util import * class Test_admin_login(object): def setup_class(self): self.driver=webdriver.Chrome() self.driver.get('http://localhost:8888/jpress/admin/login') self.driver.maximize_window() login_data=[('wx','123456','666','验证码不正确,请重新输入'), ('wx','123456','234','JPress后台')] @pytest.mark.dependency(name='admin_login') @pytest.mark.parametrize('username,pwd,captcha,expect',login_data) def test1(self,username,pwd,captcha,expect): #测试数据 #正确用户名 self.driver.find_element_by_name('user').clear() self.driver.find_element_by_name('user').send_keys(username) # 正确密码 self.driver.find_element_by_name('pwd').clear() self.driver.find_element_by_name('pwd').send_keys(pwd) if captcha!='666': # 正确的验证码 js = "document.getElementsByTagName('img')[0].setAttribute('id','captchaimg')" self.driver.execute_script(js) captcha = get_code(self.driver, id='captchaimg', uname='luoditao', pwd='xinsheng2', ) self.driver.find_element_by_name('captcha').clear() self.driver.find_element_by_name('captcha').send_keys(captcha) # 登录按钮 self.driver.find_element_by_class_name('btn-flat').click() WebDriverWait(self.driver, 5).until(EC.title_is(expect)) assert expect == self.driver.title time.sleep(3) else: #错误的验证码 self.driver.find_element_by_name('captcha').clear() self.driver.find_element_by_name('captcha').send_keys(captcha) #登录按钮 self.driver.find_element_by_class_name('btn-flat').click() WebDriverWait(self.driver,20).until(EC.alert_is_present()) alert=self.driver.switch_to.alert assert alert.text==expect alert.accept() time.sleep(2) if __name__ == '__main__': pytest.main(['test_admin_login.py']) |
依赖函数
1.首先导入登录的用例from ddt.testadminlogin import *;
2.初始化函数self.login = Testadminlogin();
3.标记调用依赖的函数名@pytest.mark.dependency(name='admin_login')注意,每个函数前面都加上标记,比如下面有3条case就写3个。
from selenium.webdriver import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.support.wait import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from time import sleep import pytest from selenium import webdriver from ddt.test_admin_login import * login_data=[('我的文章', '我的文章内容','文章保存成功。')] class TestArticle(object): def setup_class(self): self.login = Test_admin_login() # 测试添加文章 @pytest.mark.dependency(name='admin_login') @pytest.mark.parametrize('title,content,expected',login_data) def test_add_ok(self,title,content,expected): #定位左侧文章列表 #文章 self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/a/span[1]').click() sleep(1) #文章管理 self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/ul/li[1]/a').click() sleep(1) #新建 self.login.driver.find_element_by_xpath('/html/body/div/div/section[3]/div/div/div/div[1]/div/div/a').click() sleep(1) #定位文章区域 #标题 self.login.driver.find_element_by_id('article-title').send_keys(title) sleep(1) #进入iframe frame1=self.login.driver.find_element_by_xpath('//*[@id="cke_1_contents"]/iframe') self.login.driver.switch_to.frame(frame1) sleep(1) #文章内容 self.login.driver.find_element_by_xpath('/html/body').send_keys(content) #退出frame self.login.driver.switch_to.default_content() #发布按钮 self.login.driver.find_element_by_class_name('btn-primary').click() loc=(By.CLASS_NAME,"toast-message") WebDriverWait(self.login.driver,5).until(EC.visibility_of_element_located(loc)) message=self.login.driver.find_element(*loc).text assert message==expected # 测试删除单篇文章 @pytest.mark.dependency(name='admin_login') def test_delete_one_article_ok(self): # 文章管理 self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/ul/li[1]/a').click() sleep(1) #删除前文章数 beforenumber=len(self.login.driver.find_elements_by_class_name('jp-actiontr')) #鼠标悬停文章内容 a=self.login.driver.find_element_by_xpath('/html/body/div/div/section[3]/div/div/div/div[2]/table/tbody/tr[2]/td[2]/strong/a') ActionChains(self.login.driver).move_to_element(a).perform() #删除 self.login.driver.find_element_by_xpath('/html/body/div/div/section[3]/div/div/div/div[2]/table/tbody/tr[2]/td[2]/div/div/a[3]').click() sleep(1) #删除后文章数 afternumber=len(self.login.driver.find_elements_by_class_name('jp-actiontr')) #验证删除后文章数=删除前文章数-1 assert beforenumber==afternumber+1 # 测试删除所有文章 @pytest.mark.dependency(name='admin_login') def test_delete_all_article_ok(self): #文章管理 self.login.driver.find_element_by_xpath('//*[@id="sidebar-menu"]/li[4]/ul/li[1]/a').click() #点击全部复选框 self.login.driver.find_element_by_xpath('/html/body/div/div/section[3]/div/div/div/div[2]/table/tbody/tr[1]/th[1]/input').click() sleep(1) self.login.driver.find_element_by_id('batchDel').click() sleep(1) WebDriverWait(self.login.driver,5).until(EC.alert_is_present()) alert = self.login.driver.switch_to.alert alert.accept() sleep(1) #文章数目=0 afternumber = len(self.login.driver.find_elements_by_class_name('jp-actiontr')) sleep(1) assert afternumber==0 if __name__ == '__main__': pytest.main(['test_article.py']) |
相比较而言,还是在框架下实现用例之间的调用比较简单。
记住,只需要用一个函数@pytest.mark.dependency(name='adminlogin')就可以搞定,里面的name=adminlogin 每次调用时都统一,否则系统匹配不删就会报错。
版权声明:本文出自《51测试天地》第六十一期。51Testing软件测试网及相关内容提供者拥有51testing.com内容的全部版权,未经明确的书面许可,任何人或单位不得对本网站内容复制、转载或进行镜像,否则将追究法律责任