当前位置:网站首页>Different data-driven code executes the same test scenario
Different data-driven code executes the same test scenario
2022-07-06 09:01:00 【Automated test seventh uncle】
Preface
The concept of cyber theft ^-^ The same test script uses different test data to execute , Test data and test behavior are completely separated , Such a test script design pattern is called data driven .( End of cyber theft ) When we test the login function of a website , We often use different user names and passwords to verify the impact of the login module on the system , So if we write a test case for each piece of data , This is undoubtedly increasing the amount of code , Duplicate code , And look so bloated ( Who doesn't like the one with good figure ? You'll see ), At this time, we can use different data-driven code to execute the same use case to test different scenarios .
One 、 Implement data-driven steps
Let's talk about the steps of implementing data-driven testing :
1. establish / Prepare test data
2. Encapsulate the method of reading data , Keep the interface called by the test script / attribute ( What parameters do we need to pass to the script )
3. Write automated test scripts
4. In the script, the module that encapsulates the data file is invoked and the test data is introduced
5. Execute test scripts and analyze test results
Two 、 Data driven test environment preparation
1. install python3.x development environment ( All who can see this article should have this environment , No self Baidu Bar )
2. Install the data driver module ddt
Installation mode 1:cmd Give orders pip install ddt
Installation mode 2:https://pypi.org/simple/ddt/ download And extract any directory ,cmd Run the command python setup.py install
3. Verify the installation pycharm newly build python File and type import ddt Running without error message indicates that the installation is successful or cmd The commands are entered in sequence python enter import ddt enter No saved information indicates successful installation
4.unittest The framework and ddt Data driven
3、 ... and 、 testing procedure
1. Access address :https://mail.sohu.com/fe/#/login
2. Enter your username and password
3. Click the login button
4. Determine whether the login is successful
Four 、 data storage
The data is in the current script
Data preparation
What we want to achieve is the user login operation , So user name and password are required , Expected results can be or can not be . See the source code for data type !
5、 ... and 、 The sample code
1 from selenium import webdriver
2 from ddt import ddt, data, unpack
3 import unittest
4 import time
5 from selenium.common.exceptions import NoSuchWindowException
6 '''
7 Simple data driven testing
8 '''
9 @ddt
10 class ddtTest(unittest.TestCase):
11 # data It can be the ancestor of the Yuan Dynasty , list , Dictionaries ( Iteratable object )
12 value = [['[email protected]', 'xiacha11520','https://mail.sohu.com/fe/#/homepage'],
13 ['[email protected]', 'xiacha11520','https://mail.sohu.com/fe/#/homepage']]
14 # value = [{'uname':'******@sohu.com', 'password':'xiacha11520','expected':'https://mail.sohu.com/fe/#/homepage'},
15 # {'uname':'******@sohu.com', 'password':'xiacha11520','expected':'https://mail.sohu.com/fe/#/homepage'}]
16 def setUp(self):
17 self.testUrl = 'https://mail.sohu.com/fe/#/login'
18 self.driver = webdriver.Firefox()
19 self.driver.get(self.testUrl)
20
21 @data(*value) # * Parsing data
22 @unpack# To unpack , Pass the first data of each group of data to uname By analogy , When the data is a dictionary , Parameters and fields key Same value
23 def test_case1(self, uname, password, expected):
24 try:
25 username = self.driver.find_element_by_xpath("//input[@placeholder=' Please enter your email ']")
26 username.send_keys(uname)
27 time.sleep(1)
28 userpassword = self.driver.find_element_by_xpath("//input[@placeholder=' Please enter your password ']")
29 userpassword.send_keys(password)
30 self.driver.find_element_by_xpath("//input[@type='submit']").click()
31 time.sleep(2)
32 currenturl = self.driver.current_url
33 self.assertEqual(expected, currenturl,' Login failed ')
34 except NoSuchWindowException as e:
35 print(e)
36 raise
37 except AssertionError:
38 print(' The expectation is {}, The actual value is {}'.format(expected,currenturl))
39 raise
40 except Exception:
41 raise
42 def tearDown(self):
43 self.driver.quit()
44 # pass
45 if __name__ == '__main__':
46 unittest.main()
6、 ... and 、 Source code analysis
[email protected] To decorate the test class (ddt Data driven standard writing , Remember ok)
[email protected](*value) Decorate test cases ( It's also a norm , This is also related to decorators , Don't understand can baidu , No more details here , I can't say a word or two clearly ) remember :*value The purpose is to break up the data , For example, the above code uses a large list to store two small lists to store data , that *value You get two little lists , Each small list is a set of test data
[email protected] analysis *value data , Each data in the two small lists will be taken out and passed to the parameters of our test case respectively
The way 1 shortcoming
When storing large amounts of data , Need to check the source code , Not conducive to script maintenance
7、 ... and 、json File read test data for data-driven test
Data preparation
Create a new one json file ( It can also be txt file ), Write the two sets of test data we need in the form of a list json In file , Each parameter of each group of data is divided by the same symbol ( Easy for scripts to read data )
The sample code
{
"value1":"******@sohu.com||xiacha11520||https://mail.sohu.com/fe/#/homepage",
"value2":"******@sohu.com||xiacha11520||https://mail.sohu.com/fe/#/homepage"
}
1 from selenium import webdriver
2 from ddt import ddt, file_data
3 import unittest, time
4 from selenium.common.exceptions import NoSuchWindowException
5 import HTMLTestRunner
6 '''
7 Read test data from file
8 '''
9
10 @ddt # ddt Decoration test class
11 class Testdata(unittest.TestCase):
12
13 def setUp(self):
14 self.driver = webdriver.Firefox()
15 self.driver.get('https://mail.sohu.com/fe/#/login')
16
17 @file_data('test_data.json') # Read the file The data in the file can be a list , It can also be a dictionary
18 def test_data(self,value):
19 uname, password, expected = tuple(value.strip().split('||')) # value Is a string
20 # print(type(value),value)
21 try:
22 username = self.driver.find_element_by_xpath("//input[@placeholder=' Please enter your email ']")
23 username.send_keys(uname)
24 time.sleep(1)
25 userpassword = self.driver.find_element_by_xpath("//input[@placeholder=' Please enter your password ']")
26 userpassword.send_keys(password)
27 self.driver.find_element_by_xpath("//input[@type='submit']").click()
28 time.sleep(2)
29 currenturl = self.driver.current_url
30 self.assertEqual(expected, currenturl,' Login failed ')
31 except NoSuchWindowException as e:
32 raise e
33 except AssertionError:
34 print(' The expectation is {}, The actual value is {}'.format(expected,currenturl))
35 raise
36 except Exception:
37 raise
38
39 def tearDown(self):
40 self.driver.quit()
41 if __name__ == '__main__':
42 unittest.main()
43 # import os
44 # from datetime import date
45 # currentPath = os.path.dirname(os.path.abspath(__file__))# Get the current file directory
46 # reportPath = os.path.join(currentPath,'report') # Create a report Catalog
47 # if not os.path.exists(reportPath):
48 # os.mkdir(reportPath) # Determine whether the directory exists , Create... If it doesn't exist
49 # reportName = os.path.join(reportPath, str(date.today())+'report.html') # Splicing html The report
50 # with open(reportName,'wb') as f:
51 # suite = unittest.TestLoader().loadTestsFromTestCase(Testdata)
52 # runner = HTMLTestRunner.HTMLTestRunner(stream=f,verbosity=1, title=' Data driven test report ', description=' Data driven ')
53 # runner.run(suite)
Source code analysis
1. Relative to the last example , It's used here @file_data( File path ), Parameter must be a file , Here is a json file , The data can be a list , It can also be a dictionary
# Tabular form
[
"*******@sohu.com||xiacha11520||https://mail.sohu.com/fe/#/homepage",
"*******@sohu.com||xiacha11520||https://mail.sohu.com/fe/#/homepage"
]
2. The test case receives a string , The string needs to be processed , Put the user name , password , The expectation is parsed out
The way 2 Advantages and disadvantages
The test data is in the file , Easy to manage changes , Add data , Easy to maintain , What about the disadvantages ?emmm I think this is the best way !
8、 ... and 、 from xml Read data for data-driven testing
Data preparation
Create a new one xml File format , according to xml The grammatical requirements of format , Fill in data (xml I don't know much about documents , Simple display of a text or something can be ^-^!)
<?xml version="1.0"?>
<bookList type="technolog">
<book>
<uname>******@sohu.com</uname>
<password>xiaochao11520</password>
<expected>https://mail.sohu.com/fe/#/homepage</expected>
</book>
<book>
<uname>******@sohu.com</uname>
<password>xiaochao11520</password>
<expected>https://mail.sohu.com/fe/#/homepage</expected>
</book>
</bookList>
The sample code
1 from xml.etree import ElementTree
2
3 class ParseXml(object):
4 def __init__(self, xmlpath):
5 self.xmlpath = xmlpath
6
7 # Get root node
8 def getRoot(self):
9 tree = ElementTree.parse(self.xmlpath)
10 root = tree.getroot()
11 return root
12
13 # Find the child node according to the root node
14 def findNodeByName(self, parentNode, nodeName):
15 nodes = parentNode.findall(nodeName)
16 return nodes
17
18 def getNodeOfChildText(self, node):
19 # Access to the node node The node names of all child nodes below are used as key
20 # This node serves as value The dictionary object of composition
21 childrenTextDict = {}
22 for i in list(node.iter())[1:]: # node A list of all nodes under a node
23 childrenTextDict[i.tag] = i.text
24 # print(list(node.iter())[1:])
25 return childrenTextDict
26
27 # Access to the node node All data for the following nodes
28 def getDataFromXml(self, node):
29 root = self.getRoot()
30 books = self.findNodeByName(root, node)
31 dataList=[]
32 for book in books:
33 childrentext = self.getNodeOfChildText(book)
34 dataList.append(childrentext)
35 return dataList
36 if __name__=='__main__':
37 xml = ParseXml('./xmlData.xml')
38 root = xml.getRoot()
39 print(root.tag)
40 books = xml.findNodeByName(root, 'book') # Find all book node
41 for book in books:
42 # print(book[0].tag, book[0].text)
43 print(xml.getNodeOfChildText(book))
44 print(xml.getDataFromXml('book'))
1 from dataDdt.doXML import ParseXml
2 from selenium import webdriver
3 from selenium.common.exceptions import NoSuchWindowException, TimeoutException
4 import unittest
5 from ddt import ddt, data,unpack
6 import time
7 from selenium.webdriver.support import expected_conditions as EC
8 from selenium.webdriver.support.ui import WebDriverWait
9 from selenium.webdriver.common.by import By
10 values = ParseXml('./xmlData.xml')
11 @ddt
12 class xmltest(unittest.TestCase):
13
14 def setUp(self):
15 self.driver = webdriver.Firefox()
16 self.driver.get('https://mail.sohu.com/fe/#/login')
17 @data(*values.getDataFromXml('book'))
18 @unpack
19 def test_xml(self,uname, password, expected):
20 try:
21 wait = WebDriverWait(self.driver,5)
22 wait.until(EC.element_to_be_clickable((By.XPATH, "//input[@type='submit']")))
23 username = self.driver.find_element_by_xpath("//input[@placeholder=' Please enter your email ']")
24 username.send_keys(uname)
25 time.sleep(1)
26 userpassword = self.driver.find_element_by_xpath("//input[@placeholder=' Please enter your password ']")
27 userpassword.send_keys(password)
28 self.driver.find_element_by_xpath("//input[@type='submit']").click()
29 time.sleep(2)
30 currenturl = self.driver.current_url
31 self.assertEqual(expected, currenturl, ' Login failed ')
32 except TimeoutException as e:
33 raise e
34 except NoSuchWindowException as e:
35 raise e
36 except AssertionError as e:
37 print(' The expectation is {}, The actual value is {}'.format(expected, currenturl))
38 raise e
39 except Exception:
40 raise
41 def tearDown(self):
42 self.driver.quit()
43
44 if __name__=='__main__':
45 unittest.main()
Source code analysis
1.xml Documentation ( In depth understanding needs Baidu ) It's kind of like html, But it's different ,xml The node in can be any name , Each node also appears in pairs
2. Added doXML.py file , Used to resolve xml file , It's easy for scripts to get data ( The notes are very detailed , I don't know how to debug slowly , Where don't know print Where? )
3. The test script is roughly the same as the example above
The way 3 Advantages and disadvantages
The advantage is the separation of data and test , Easy data maintenance , The disadvantages are obvious , Need to be right xml The document has a certain understanding of
summary
The above data-driven test steps are my own summary , Looking at the above example, the steps should be reasonable , Here are the data-driven test steps I found online ( I feel official ! You can refer to )
1. Write test script , Scripts need to support slave objects , file , Or the database reads in data .( Personal view : If the script is finished first , The test data is not ready , Later, we need to make changes )
2. Store the test data used by the test script into the program object , file , Or database and other external media .( Personal view : This stage is actually the stage of data preparation , That's where our data is going to be , It should be the first step )
3. During the script run , Cycle test data stored in external media .( Personal view : Here's how we read , Using data )
4. Verify that all test results are in accordance with the expected results
Finally, that's all for today's article , If you like, you can like your collection and pay attention .
边栏推荐
- I-BERT
- 如何正确截取字符串(例:应用报错信息截取入库操作)
- 不同的数据驱动代码执行相同的测试场景
- TP-LINK enterprise router PPTP configuration
- 什么是MySQL?MySql的学习之路是怎样的
- 在QWidget上实现窗口阻塞
- After reading the programmer's story, I can't help covering my chest...
- MongoDB 的安装和基本操作
- ant-design的走马灯(Carousel)组件在TS(typescript)环境中调用prev以及next方法
- Cesium draw points, lines, and faces
猜你喜欢
vb. Net changes with the window, scales the size of the control and maintains its relative position
Advanced Computer Network Review(4)——Congestion Control of MPTCP
BMINF的後訓練量化實現
MYSQL卸载方法与安装方法
Advanced Computer Network Review(5)——COPE
UML diagram memory skills
Selenium+Pytest自动化测试框架实战(下)
SAP ui5 date type sap ui. model. type. Analysis of the parsing format of date
[OC]-<UI入门>--常用控件-UIButton
[embedded] print log using JLINK RTT
随机推荐
[today in history] February 13: the father of transistors was born The 20th anniversary of net; Agile software development manifesto was born
R language ggplot2 visualization: place the title of the visualization image in the upper left corner of the image (customize Title position in top left of ggplot2 graph)
Leetcode: Jianzhi offer 03 Duplicate numbers in array
UML diagram memory skills
Revit secondary development Hof method calls transaction
超高效!Swagger-Yapi的秘密
CUDA implementation of self defined convolution attention operator
力扣每日一题(二)
LeetCode:498. Diagonal traversal
LeetCode:剑指 Offer 03. 数组中重复的数字
R language ggplot2 visualization, custom ggplot2 visualization image legend background color of legend
Intel Distiller工具包-量化实现3
Advanced Computer Network Review(3)——BBR
Advanced Computer Network Review(5)——COPE
在QWidget上实现窗口阻塞
随手记01
[MySQL] multi table query
LeetCode:673. 最长递增子序列的个数
R language uses the principal function of psych package to perform principal component analysis on the specified data set. PCA performs data dimensionality reduction (input as correlation matrix), cus
Philosophical enlightenment from single point to distributed