0
点赞
收藏
分享

微信扫一扫

selenium - 数据驱动应用(parameterized、DDT)

1. parameterized

parameterized是python的一个参数化库,同时支持unittest、nose、pytest单元测试框架

安装:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests parameterized

import unittest
import time
from selenium import webdriver
from parameterized import parameterized


class TestBaidu(unittest.TestCase):
  # 参数化后,要将setup和teardown修改为类方法,不然每个参数被认为一个测试用例,浏览器会随之每次都打开关闭
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()
cls.base_url = 'http://www.baidu.com'

def baidu_search(self, search_key):
self.driver.get(self.base_url)
self.driver.find_element_by_id('kw').send_keys(search_key)
self.driver.find_element_by_id('su').click()
time.sleep(3)

# 通过parameterized实现参数化
@parameterized.expand([ # 每个元组都被认为是一条测试用例。测试用例中,通过参数来取每个元组中的数据
('case1', 'selenium'),
('case2', 'unittest'),
('case3', 'parameterized'),
])
def test_search(self, name, search_key): # name对应元组中的第一列数据,search_key对应第二列
self.baidu_search(search_key)
self.assertEqual(self.driver.title, search_key + '_百度搜索')

@classmethod
def tearDownClass(cls):
cls.driver.quit()


if __name__ == '__main__':
unittest.main(verbosity=2) # verbosity设置为2,表示输出更详细的日志

运行结果如下:

test_search_0_case1 (__main__.TestBaidu) ... ok
test_search_1_case2 (__main__.TestBaidu) ... ok
test_search_2_case3 (__main__.TestBaidu) ... ok

----------------------------------------------------------------------
Ran 3 tests in 15.239s

OK

test_search是测试用例的名称,参数化会自动加上0、1、2用来区分每条测试用例,元组中的case1后缀在名称上

 

2. DDT

 DDT(data-driven tests)是针对unittest单元测试框架设计的扩展库。允许使用不同的测试数据来运行一个测试用例,并将其展示为多个测试用例。

 安装:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple requests ddt

from selenium import webdriver
import unittest
import time
from ddt import ddt, data, file_data, unpack


@ddt # 测试类需要通过@ddt装饰器进行装饰
class TestBaidu(unittest.TestCase):
@classmethod
def setUpClass(cls):
cls.driver = webdriver.Chrome()

def search_baidu(self, keyword):
self.driver.get('http://www.baidu.com')
self.driver.find_element_by_id('kw').send_keys(keyword)
self.driver.find_element_by_id('su').click()
time.sleep(3)

# ddt提供了不同形式的参数化
@data(['case1','selenium'], ['case2', 'python']) # 列表
@unpack
def test_baidu1(self, name, keyword):
print('第一组测试用例', name)
self.search_baidu(keyword)
self.assertEqual(self.driver.title, keyword + '_百度搜索')

@data(('case1', 'selenium'), ('case2', 'pyton')) # 元组
@unpack
def test_baidu2(self, name, keyword):
print('第二组测试用例', name)
self.search_baidu(keyword)
self.assertEqual(self.driver.title, keyword + '_百度搜索')

@data({'keyword':'selenium'}, {'keyword':'python'}) # 字典
@unpack
def test_baidu3(self, keyword):
print('第三组测试用例', keyword)
self.search_baidu(keyword)
self.assertEqual(self.driver.title, keyword + '_百度搜索')

@classmethod
def tearDownClass(cls):
cls.driver.quit()


if __name__ == '__main__':
unittest.main(verbosity=2)

 DDT同样支持json文件的读取,让我们更关注于数据文件的内容,及在测试用例中的使用。而不需要关心数据文件是如何被读取进来的

keyword.json

selenium - 数据驱动应用(parameterized、DDT)_json

 使用json文件参数化测试用例

'./data/keyword.json')    # 读取json文件
def test_baidu(self, keyword):
self.search_baidu(keyword)
self.assertEqual(self.driver.title, keyword + '_百度搜索')

测试结果如下:

test_baidu_00001_case1 (__main__.TestBaidu)
test_baidu_00001_case1 ... ok
test_baidu_00002_case2 (__main__.TestBaidu)
test_baidu_00002_case2 ... ok
test_baidu_00003_case3 (__main__.TestBaidu)
test_baidu_00003_case3 ... FAIL

 


 

ps:

参数化中使用全局变量需注意,如果全局变量的赋值和使用在同一个文件中,则不能使用

原因:代码执行顺序

执行时,先走parameterized中的代码,后走业务代码,所以全局变量的值在赋值之前已经获取,为空,会报错,如下123为执行顺序:

class Test_0001(TestBase):
def test_1(self):
phone = 123
set_assistant_phone_id(phone) # 2


class Test_0011(TestBase):
@parameterized.expand([
('随机手机号', get_assistant_phone_id()) # 1 先执行。还未赋值,所以获取不到数据
])
def test_1(self, casename, phone): # 3

解决方案:不使用参数化,将全局变量放在test用例中即可

class Test_0011(TestBase):
def test_1(self):
func(get_assistant_phone_id())

def test_2(self):
func(phone2)

 



举报

相关推荐

0 条评论