欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

unittest中更高效的执行测试用例一个类只需要打开一次浏览器

程序员文章站 2024-03-15 19:16:36
...

示例代码

baidu.py

# _*_ coding:utf-8 _*_
import csv,unittest #导入csv模块
from time import sleep
from selenium import webdriver
from module import baidumodule
class baidu(unittest.TestCase):
    def setUp(self):
        self.driver = webdriver.Chrome()
        self.driver.maximize_window()#最大化窗口
        self.driver.implicitly_wait(10)#隐式等待
        self.search = baidumodule(self.driver) #将driver传给aidumodule这个类
        with open("file.csv","r") as name:
            self.lines = name.readlines()#以行读取整个文件
    def tearDown(self):
        self.driver.quit()

    def test_search(self):
        search = self.search
        lines = self.lines
        driver = self.driver
        search.login(lines[0])
        sleep(1)
        title = driver.title
        self.assertEqual(title,'selenium_百度搜索2')
        sleep(2)
    def test_search1(self):
        search = self.search
        lines = self.lines
        driver = self.driver
        search.login(lines[1])
        sleep(1)
        title = driver.title
        self.assertEqual(title,'selenium2_百度搜索')
        sleep(2)
    def test_search2(self):
        search = self.search
        lines = self.lines
        driver = self.driver
        search.login(lines[2])
        sleep(1)
        title = driver.title
        self.assertEqual(title,'selenium3_百度搜索')
        sleep(2)
    def test_search3(self):
        search = self.search
        lines = self.lines
        driver = self.driver
        search.login(lines[3])
        sleep(1)
        title = driver.title
        self.assertEqual(title,'webdriver_百度搜索')
        sleep(2)

if __name__ == "__main__": #如果直接执行将执行以下代码,调用不执行以下代码
    unittest.main()

module.py

class baidumodule():
    def __init__(self,driver,):
        self.dr = driver #不能在类中再次导入webdriver 两边的driver等于两个窗口,直接让调用方传入driver即可
    def login(self,values):
        login_dr = self.dr
        login_dr.get("https://www.baidu.com/")
        login_dr.find_element_by_xpath("//*[@id='kw']").send_keys(values)
        login_dr.find_element_by_xpath("//*[@id='su']").click()

baidu.py执行结果

....
----------------------------------------------------------------------
Ran 4 tests in 49.660s #运行4条耗时49.660s

OK

以上代码均可成功执行但是执行过程中每个测试用例都需要再次打开浏览器,这会大大拖延执行时间,我们可以使用@classmethod装饰器将@classmethod所装饰的方法改为类方法即setUpClasstearDownClass让每类执行只需要开启一次浏览器即可(在unittest中默认如此).

@classmethod
    def setUpClass(cls):
        "Hook method for setting up class fixture before running tests in the class."

@classmethod
    def tearDownClass(cls):
        "Hook method for deconstructing the class fixture after running all tests in the class."

更改后的baidu.py

# _*_ coding:utf-8 _*_
import csv,unittest #导入csv模块
from time import sleep
from selenium import webdriver
from module import baidumodule
class baidu(unittest.TestCase):
    @classmethod
    def setUpClass(cls):#类中最先执行
        cls.driver = webdriver.Chrome()
        cls.driver.maximize_window()  # 最大化窗口
        cls.driver.implicitly_wait(10)  # 隐式等待
        cls.search = baidumodule(cls.driver)  # 将driver传给aidumodule这个类
        with open("file.csv","r") as name:
            cls.lines = name.readlines()#以行读取整个文件
    @classmethod
    def tearDownClass(cls): #类中最后执行
        cls.driver.quit()

    def test_search(self):
        search = self.search
        lines = self.lines
        driver = self.driver
        search.login(lines[0])
        sleep(1)
        title = driver.title
        self.assertEqual(title,'selenium_百度搜索')
        sleep(2)
    def test_search1(self):
        search = self.search
        lines = self.lines
        driver = self.driver
        search.login(lines[1])
        sleep(1)
        title = driver.title
        self.assertEqual(title,'selenium2_百度搜索')
        sleep(2)
    def test_search2(self):
        search = self.search
        lines = self.lines
        driver = self.driver
        search.login(lines[2])
        sleep(1)
        title = driver.title
        self.assertEqual(title,'selenium3_百度搜索')
        sleep(2)
    def test_search3(self):
        search = self.search
        lines = self.lines
        driver = self.driver
        search.login(lines[3])
        sleep(1)
        title = driver.title
        self.assertEqual(title,'webdriver_百度搜索')
        sleep(2)

if __name__ == "__main__": #如果直接执行将执行以下代码,调用不执行以下代码
    unittest.main()

执行结果:

....
----------------------------------------------------------------------
Ran 4 tests in 23.124s#执行4条耗时23.124s

OK

可以看到每次打开浏览器再执行至少多一倍的时间。

  • setUpClass/tearDownClass: 在测试类的开始与结束时被执行。
  • setUp/tearDown : 在测试用例的开始与结束时被执行。需要注意的是,setUpClass/tearDownClass 的写法稍微有些不同。首先,需要通过@classmethod 进行装饰,其次方法的参数为 cls。其实,cls 与 self 并没有什么特别之处,都只表示类方法的第一个参数,只是大家约定俗成,习惯于这样来命名,当然也可以用 abc 来代替。

特别注意

使用@classmethod装饰器时不要把要测试的网页放置到setUpClass中那样执行完第一个用例时不会再次打开浏览器,导致参数化等第二条用例只会在原地执行,所以要把链接放置到测试用例中。
如下是错误示例:

   @classmethod
   def setUpClass(cls):
        cls.dr = webdriver.Chrome()
        cls.dr.maximize_window()
        cls.dr.implicitly_wait(10)
        cls.dr.get("https://www.baidu.com/")

unittest中更高效的执行测试用例一个类只需要打开一次浏览器

正确写法:

    def test_search(self,search_str,aa):  # 接收上面的两个参数
        '''百度测试用例'''
        self.dr.get("https://www.baidu.com/")#这样执行下个用例才会再次打开链接
        self.dr.find_element_by_id("kw").send_keys(search_str)
        self.dr.find_element_by_id("su").click()
        sleep(2)