当前位置:网站首页>[test development] automated test selenium (III) -- unittest framework analysis
[test development] automated test selenium (III) -- unittest framework analysis
2022-06-13 03:39:00 【Bryant tapping the code】
【 Test Development 】 automated testing selenium( 3、 ... and )——unittest Framework analysis
unittest Framework analysis
unittest yes python The unit test framework of , stay python In the official documents of , Yes unittest There is a detailed introduction , Students who want to further study can go to https://www.python.org/doc/ To understand .
unittest Unit testing provides the ability to create test cases , Test suite and batch execution scheme , unittest In the installation pyhton I'll bring it myself , direct import unittest You can use .
As a framework for unit testing , unittest It is also an agile test of the smallest module of the program . In automated testing , We don't need to do a white box test , But you need to know the unit test framework of the language you use . Using unit test framework , Create a class , Inheritance of such kind unittest Of TestCase, So that we can case As a minimum unit , Organized by test containers , When the time comes, execute directly , At the same time, the test report is introduced .
unittest The relationship of each component is :
- test fixture: Test firmware , Initialize and clean up the test environment , Like creating a temporary database , Files and directories, etc , among
setUp() and setDown()Is the most commonly used method - test case: Unit Test Case ,TestCase It is the most commonly used class for writing unit test cases
- test suite: test suite ,
A collection of unit test cases ,TestSuite Is the most commonly used class - test runner: Perform unit tests
- test report: Generate test reports
unittest and Junit The difference betweenTesting firmware is simple :
import time
from selenium import webdriver
import unittest
class Test(unittest.TestCase):
# Test Inherited from unittest.TestCase
# Test firmware setup and tearDown
# there self It is equivalent to an example
def setUp(self):
self.driver = webdriver.Chrome()
self.url = "http://www.baidu.com/"
self.driver.maximize_window()
def tearDown(self):
self.driver.quit()
# The test method name must be test_ Otherwise, it will not be carried out
def test_baidu(self):
driver = self.driver
driver.get(self.url)
driver.find_element_by_id("kw").send_keys("kobe")
driver.find_element_by_id("su").click()
time.sleep(3)
if __name__ == "__main__":
unittest.main(2)
''' Can increase verbosity Parameters , for example unittest.main(verbosity=2) In the main function , Call directly main() , stay main Add verbosity=2 , In this way, the test results will be displayed in more detail . there verbosity It's an option , Represents the information complexity of the test results , There are three values : 0 ( silent mode ): You can only get the total number of test cases and total results, such as a total of 100 A failure ,20 success 80 1 ( The default mode ): It's very similar to the silent mode, except that there is a... In front of each successful use case “ . ” Each failed use case is preceded by a “F” 2 ( Detailed mode ): The test results show all the relevant information for each test case '''

Batch script execution
Build test suite
Complete unit tests rarely execute only one test case , Developers usually need to write multiple test cases to test a software function completely , These related test cases are called a test case set , stay unittest Medium used TestSuite Class .
Suppose we have written testbaidu1.py,testbaidu2.py Two documents , So how can we execute these two files at the same time ?
addTest() Application
When there are multiple or hundreds of test cases , This requires a test container ( test suite ) , Put the test case in the container for execution ,unittest Module provides TestSuite Class to generate the test suite , Using the constructor of this class, you can generate an instance of the test suite , This class provides addTest To add each test case to the test suite .
take testbaidu1.py、testbaidu2.py、runall.py Put it in the same directory testcase in
runall.py The contents are as follows
import time
# Import test_baidu1,test_baidu2
import test_baidu1
import test_baidu2
import unittest
# Manually add cases to the suite ,
def createsuite():
suite = unittest.TestSuite()
# Add test cases to the test container ( Kit ) in
suite.addTest(test_baidu1.Baidu1("test_baidu1"))
suite.addTest(test_baidu2.Baidu2("test_baidu2"))
return suite
if __name__ == "__main__":
suite = createsuite()
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)

There are two aspects of the above approach , Hinder the rapid execution of scripts , Must be modified every time runall.py:
1) You need to import all py file , such as import testbaidu1, Each new one needs to be imported
2)addTest Need to add all testcase, If one py In file 10 individual case, It needs to be increased 10 Time
makeSuite() and TestLoader() Application
stay unittest The framework provides makeSuite() Methods ,makeSuite It can realize all the tests in the test case class case Test suite composed of TestSuite ,unittest call makeSuite When , Just pass in the test class name .
TestLoader Test suite for creating classes and modules
In general , send TestLoader().loadTestsFromTestCase(TestClass) To load the test class .
runall.py The contents are as follows
import time
# Import test_baidu1,test_baidu2
import test_baidu1
import test_baidu2
import unittest
# Manually add cases to the suite ,
def createsuite():
suite = unittest.TestSuite()
# Add test cases to the test container ( Kit ) in
suite.addTest(unittest.makeSuite(test_baidu1.Baidu1))
suite.addTest(unittest.makeSuite(test_baidu2.Baidu2))
return suite
''' suite1 = unittest.TestLoader().loadTestsFromTestCase(test_baidu1.Baidu1) suite2 = unittest.TestLoader().loadTestsFromTestCase(test_baidu2.Baidu2) suite = unittest.TestSuite([suite1, suite2]) return suite '''
if __name__ == "__main__":
suite = createsuite()
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)

after makeSuite() and TestLoader() The introduction of , We don't need one py File test class , You only need to import it once .
So can you test classes without adding specifications every time ?
discover() Application
discover Is recursively to its subdirectory, starting from the specified directory , Find all test modules and return an object containing them TestSuite , Then load the only test file matching the pattern ,discover The parameters are discover(dir,pattern,top_level_dir=None)
runall.py— Pay attention to the path
# -*- coding: utf-8 -*-
import unittest,csv
import os,sys
import time
# Manually add cases to the suite ,
def createsuite():
discover=unittest.defaultTestLoader.discover('../test',pattern='test*.py',top_level_dir=None)
print discover
return discover
if __name__=="__main__":
suite=createsuite()
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)
Use case execution sequence
unittest By default, the order in which the framework loads test cases is based on ASCII The order of the codes , The order of numbers and letters is : 09,AZ,a~z
therefore , TestAdd Class will take precedence over TestBdd Class is found , test_aaa() Method will take precedence over test_ccc() Be performed .
For test directories and test files , unittest The framework also loads test cases according to this rule .addTest() Methods are executed in increasing order .
Ignore use case execution
@unittest.skip("skipping")
Adding this comment before the test method is to ignore the use case execution
unittest Assertion
Automated testing , For each individual case Come on , One case In the execution result of , There must be expected results and actual results , To judge the right case Pass or fail , stay unittest The library provides a number of practical ways to check expected and actual values , To verify case Result , Generally speaking , The inspection conditions are roughly divided into equivalence , Logical comparison and other , If the given assertion passes , The test will continue to the next line of code , If the assertion fails , Corresponding case The test will stop immediately or generate an error message ( Generally, you can print error messages ) , But don't affect others case perform .
unittest The unit test library provides a standard xUnit assert methods . Here are some common assertions
| Serial number | assert methods | Assertion description |
|---|---|---|
| 1 | assertEqual(arg1, arg2, msg=None) | verification arg1=arg2, If you don't wait fail |
| 2 | assertNotEqual(arg1, arg2, msg=None) | verification arg1 != arg2, Equal is equal fail |
| 3 | assertTrue(expr, msg=None) | verification expr yes true, If false, be fail |
| 4 | assertFalse(expr,msg=None) | verification expr yes false, If true, be fail |
| 5 | assertIs(arg1, arg2, msg=None) | verification arg1、arg2 Is the same object , Not so fail |
| 6 | assertIsNot(arg1, arg2, msg=None) | verification arg1、arg2 Not the same object , it is then fail |
| 7 | assertIsNone(expr, msg=None) | verification expr yes None, Not so fail |
| 8 | assertIsNotNone(expr, msg=None) | verification expr No None, it is then fail |
| 9 | assertIn(arg1, arg2, msg=None) | verification arg1 yes arg2 The string of , Not so fail |
| 10 | assertNotIn(arg1, arg2, msg=None) | verification arg1 No arg2 The string of , it is then fail |
| 11 | assertIsInstance(obj, cls, msg=None) | verification obj yes cls Example , Not so fail |
| 12 | assertNotIsInstance(obj, cls, msg=None) | verification obj No cls Example , it is then fail |
import time
from selenium import webdriver
import unittest
class Baidu1(unittest.TestCase):
# Test Inherited from unittest.TestCase
# Test firmware setup and tearDown
# there self It is equivalent to an example
def setUp(self):
self.driver = webdriver.Chrome()
self.url = "http://www.baidu.com/"
self.driver.maximize_window()
def tearDown(self):
self.driver.quit()
# The test method name must be test_ Otherwise, it will not be carried out
def test_baidu1(self):
driver = self.driver
driver.get(self.url)
driver.find_element_by_id("kw").send_keys("kobe")
driver.find_element_by_id("su").click()
# Add assertions
self.assertEqual("kobe", driver.find_element_by_link_text(" Kobe · Bryant - Baidu Encyclopedia ").text,msg="kobe!= Kobe · Bryant - Baidu Encyclopedia ")
time.sleep(3)
if __name__ == "__main__":
unittest.main(2)
''' Can increase verbosity Parameters , for example unittest.main(verbosity=2) In the main function , Call directly main() , stay main Add verbosity=2 , In this way, the test results will be displayed in more detail . there verbosity It's an option , Represents the information complexity of the test results , There are three values : 0 ( silent mode ): You can only get the total number of test cases and total results, such as a total of 100 A failure ,20 success 80 1 ( The default mode ): It's very similar to the silent mode, except that there is a... In front of each successful use case “ . ” Each failed use case is preceded by a “F” 2 ( Detailed mode ): The test results show all the relevant information for each test case '''

Can pass IDE To add assertions :
HTML Report generation
After the script is executed , Still need to see HTML The report , Let's go through HTMLTestRunner.py To generate test reports .
HTMLTestRunner Support python2.7.python3 See the code in the following website , Copy and paste between https://blog.csdn.net/liubo37/article/details/105069609/
HTMLTestRunner.py file , Download address :
http://tungwaiyip.info/software/HTMLTestRunner.html
After downloading, put it in testcase To go or put into a directory …\Python27\Lib Under the table of contents (windows).
modify runall.py
# -*- coding: utf-8 -*-
import unittest,csv
import os,sys
import time
import HTMLTestRunner
# Manually add cases to the suite ,
def createsuite():
discover=unittest.defaultTestLoader.discover('../test',pattern='test*.py',top_level_dir=None)
print discover
return discover
if __name__=="__main__":
curpath=sys.path[0]
# Solve the problem of duplicate naming
now=time.strftime("%Y-%m-%d-%H %M %S",time.localtime(time.time()))
# Under the current path resulreport Create a folder when it doesn't exist
if not os.path.exists(curpath+'/resultreport'):
os.makedirs(curpath+'/resultreport')
# The file name is the path plus the name of the file
# Get ready HTML Report output file
filename=curpath+'/resultreport/'+now+'resultreport.html'
# open HTML file ,wb In writing
with open(filename,'wb') as fp:
# Out html The report , The parameters in parentheses are HTML The parameters in the report
runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title=u' Test report ',description=u' Use case execution
situation ',verbosity=2)
suite=createsuite()
runner.run(suite)


Exception capture and error screenshot
Use cases cannot succeed every time they run , There must be some unsuccessful times when it runs . If you can catch errors , And save the error screenshot , This will be a great feature , It will also bring convenience to our wrong positioning .
For example, write a screenshot function , The key statement is driver.get_screenshot_as_file:
def savescreenshot(self,driver,file_name):
if not os.path.exists('./image'):
os.makedirs('./image')
now=time.strftime("%Y%m%d-%H%M%S",time.localtime(time.time()))
# Screenshot save
driver.get_screenshot_as_file('./image/'+now+'-'+file_name)
time.sleep(1)
A quoted example :
# -*- coding: utf-8 -*-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.common.exceptions import NoSuchElementException
from selenium.common.exceptions import NoAlertPresentException
import unittest, time, re
import os
class Baidu1(unittest.TestCase):
#test fixture, Initialization environment
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.implicitly_wait(30)
self.base_url = "http://www.baidu.com/"
self.verificationErrors = []
self.accept_next_alert = True
# The test case , Must be test start
def test_hao(self):
driver = self.driver
driver.get(self.base_url + "/")
driver.find_element_by_link_text("hao123").click()
time.sleep(2)
try:
self.assertEqual(u'hao_ Internet starts here ', driver.title)
except:
self.savescreenshot(driver,'hao.png')
# Judge element Whether there is , Deleting
def is_element_present(self, how, what):
try: self.driver.find_element(by=how, value=what)
except NoSuchElementException as e: return False
return True
# Judge alert Whether there is , Deleting
def is_alert_present(self):
try: self.driver.switch_to_alert()
except NoAlertPresentException as e: return False
return True
# close alert, Deleting
def close_alert_and_get_its_text(self):
try:
alert = self.driver.switch_to_alert()
alert_text = alert.text
if self.accept_next_alert:
alert.accept()
else:
alert.dismiss()
return alert_text
finally: self.accept_next_alert = True
#test fixture, Clear the environment
def tearDown(self):
self.driver.quit()
self.assertEqual([], self.verificationErrors)
def savescreenshot(self,driver,file_name):
if not os.path.exists('./image'):
os.makedirs('./image')
now=time.strftime("%Y%m%d-%H%M%S",time.localtime(time.time()))
# Screenshot save
driver.get_screenshot_as_file('./image/'+now+'-'+file_name)
time.sleep(1)
if __name__ == "__main__":
# Execute use cases
unittest.main()
''' Can increase verbosity Parameters , for example unittest.main(verbosity=2) In the main function , Call directly main() , stay main Add verbosity=2 , In this way, the test results will be displayed in more detail . there verbosity It's an option , Represents the information complexity of the test results , There are three values : 0 ( silent mode ): You can only get the total number of test cases and total results, such as a total of 100 A failure ,20 success 80 1 ( The default mode ): It's very similar to the silent mode, except that there is a... In front of each successful use case “ . ” Each failed use case is preceded by a “F” 2 ( Detailed mode ): The test results show all the relevant information for each test case '''
边栏推荐
- MySQL learning summary XIII: detailed explanation of if, case, loop, while & cursor of process control
- Graph data modeling tool
- 【测试开发】用例篇
- (9) Explain broadcasting mechanism in detail
- Understanding the ongdb open source map data foundation from the development of MariaDB
- Environmental pollution, enterprises, highways, fixed assets, foreign investment in all prefecture level cities in China - latest panel data
- MySQL learning summary 7: create and manage databases, create tables, modify tables, and delete tables
- Application scenarios of large arrows in Scala
- 【测试开发】文件压缩项目实战
- Installing MySQL 8.0.20 under Linux and ubuntu20.04 LTS
猜你喜欢

(九)详解广播机制

Get to know druid IO real time OLAP data analysis storage system

Domestic zynq standalone pl-ps interrupt commissioning

Understand the difference between reducebykey and groupbykey in spark

LVS四層負載均衡集群(5)LVS概述

2000-2019 enterprise registration data of all provinces, cities and counties in China (including longitude and latitude, registration number and other multi indicator information)

Carbon neutralization & Patent Innovation: multi indicator data such as patent panels (original documents) of provinces, cities and counties, and the number of low-carbon patents authorized
![[azure data platform] ETL tool (8) - ADF dataset and link service](/img/bf/d6d3a8c1139bb8d38ab9ee1ab9754e.jpg)
[azure data platform] ETL tool (8) - ADF dataset and link service

基于华为云物联网设计的浇花神器(STM32+ESP8266)

Workflow of driver of spark kernel (stage division, task division, task scheduling)
随机推荐
UDP connection map collection
Batch image Download & socket dialogue
C语言程序设计——从键盘任意输入一个字符串,计算其实际字符个数并打印输出,要求不能使用字符串处理函数strlen(),使用自定义子函数Mystrlen()实现计算字符个数的功能。
Peking University HP financial index - matching enterprise green innovation index 2011-2020: enterprise name, year, industry classification and other multi indicator data
300W pieces of MySQL data were written in the test, and they were broken between 1.6 and 2W each time. Then the following problems occurred:
P1048 [noip2005 popularization group] Drug collection
Spark core concepts: Master, worker, driver program, executor, RDDS
ip地址及分类
【测试开发】测试管理工具禅道的安装
Watering artifact based on Huawei cloud Internet of things (stm32+esp8266)
Understand the difference between reducebykey and groupbykey in spark
[azure data platform] ETL tool (2) -- azure data factory "copy data" tool (cloud copy)
Multi thread writing method and the making of slot machine
Video playback has repeatedly broken 1000w+, how to use the second dimension to create a popular model in Kwai
CXGRID keeps the original display position after refreshing the data
Solve the error in CONDA installation PyMOL
Multithreaded chat room, server and client
Use of Oracle PL-SQL
Azure SQL db/dw series (11) -- re understanding the query store (4) -- Query store maintenance
ONNX+TensorRT+YoloV5:基于trt+onnx得yolov5部署1

