32、Selenium + Python 实现 UI 自动化测试-正片4
再来写几条用例吧。
创建一个新文件test_new_bug.py文件,用来新建bug
from selenium import webdriver import unittest class TestNewBug(unittest.TestCase): def setUp(self): self.driver = webdriver.Chrome() self.driver.implicitly_wait(20) self.driver.maximize_window() self.driver.get("http://localhost:81/redmine/login") self.driver.find_element_by_id('username').clear() self.driver.find_element_by_id('username').send_keys('admin') self.driver.find_element_by_id('password').clear() self.driver.find_element_by_id('password').send_keys('test1234') self.driver.find_element_by_id('login-submit').click() def test_new_bug(self): self.driver.find_element_by_xpath('//*[@id="top-menu"]/ul/li[3]/a').click() self.driver.find_element_by_xpath('//*[@id="projects-index"]/ul/li[1]/div/a').click() self.driver.find_element_by_xpath('//*[@id="main-menu"]/ul/li[4]/a').click() #点击新建问题按钮 self.driver.find_element_by_xpath('//*[@id="content"]/div[1]/a').click() #输入bug简要描述 self.driver.find_element_by_id('issue_subject').send_keys('【RedMine系统测试】【新建Bug模块】:问题简要描述') js1 = "window.scrollTo(0,document.body.scrollHeight)" self.driver.execute_script(js1) #点击创建 self.driver.find_element_by_name('commit').click() ele = self.driver.find_element_by_id('flash_notice') self.assertIn('已创建',ele.text) def tearDown(self): self.driver.quit() if __name__ == '__main__': TestNewBug()
运行结果:pass (单条用例调试通过)
尝试运行下run.py,看下是否能将之前的2条case,加上今天新写的case,一起运行完成,然后看下测试报告,是否包含3条用例执行结果。
执行成功(大家注意下自动化运行的过程:先执行的login,然后执行的new_bug,最后执行的new_pj),HTML报告结果如下图:
现在我们的框架目录文件:
用例排序是按照字母的升序进行的。执行顺序是按照用例顺序依次执行的。
虽然本次运行没有错误,这是因为我们之前已经有项目了,而我们新建bug,只是随便选了个项目,在其下面新建的bug。如果第一次运行,没有项目,势必会报错。
意思就是,我们创建的用例,某些情况下,会有前后逻辑关系,需要依次执行。如何解决该问题?
那我们就修改下用例名命名规则吧,如下:
运行,成功,按照我们期望的顺序执行。
在写第三条用例的时候,再setup里面又写了一遍登录过程,
每次都写这么多代码,让我很不爽,就算复制粘贴也“难消心头之恨”。是否可以将这部分“公共”的东西拿出来呢?
好,我们再次调整下框架目录结构,新建一个common目录,用来存放这些“公共”部分,如下
新建一个login.py文件,写一个登录函数,直接导入该文件,就可以调用该函数,内容如下:
from selenium import webdriver def Login(): driver = webdriver.Chrome() driver.implicitly_wait(20) driver.maximize_window() driver.get("http://localhost:81/redmine/login") driver.find_element_by_id('username').clear() driver.find_element_by_id('username').send_keys('admin') driver.find_element_by_id('password').clear() driver.find_element_by_id('password').send_keys('test1234') driver.find_element_by_id('login-submit').click() return driver if __name__ == '__main__': Login()
然后调整一下 test_001_new_pj 和 test_002_new_bug 文件,内容如下:
import unittest from selenium import webdriver import time from time import sleep from first.common import login class TestNewProject(unittest.TestCase): def setUp(self): self.driver = login.Login() def test_new_pj(self): project_name = time.strftime("%Y%m%d%H%M%S", time.localtime(time.time())) project_id = "bs" + project_name # 标识要求以字母开头 self.driver.find_element_by_xpath('//*[@id="top-menu"]/ul/li[3]/a').click() # 点击左上角“项目” self.driver.find_element_by_xpath('//*[@id="content"]/div[1]/a').click() # 点击新建项目 self.driver.find_element_by_id('project_name').send_keys(project_name) # 输入项目名称 self.driver.find_element_by_id('project_identifier').send_keys(project_id) # 输入项目标识 js1 = "window.scrollTo(0,document.body.scrollHeight)" self.driver.execute_script(js1) # 创建按钮不在当前屏幕内,需要先滑动滚动条 self.driver.find_element_by_name('commit').click() # 点击创建按钮 sleep(2) ele1 = self.driver.find_element_by_id('flash_notice') self.assertEqual(ele1.text,'创建成功') def tearDown(self): self.driver.quit() if __name__ == '__main__': TestNewProject()
可以看到setup 里面的一大坨内容,变成了一句话,清爽了许多。
简单总结一下:
1、我们在写新的case时,发现case在目录中的存储顺序是按照字母先后排列的,执行顺序也是如此;但有的时候这并不是我们想要的,于是我们稍微调整了一下case名称。
2、在写新case的时候,我们setup里面代码是从前面粘过来的,为了简化代码,我们将登录部分写成了一个函数,需要的时候调用函数就行。