Python unit testing framework (inheritance, unittest parameterization, assertions, test reporting)

1. Inheritance

What problems can inheritance solve?

Each module of unittest needs preconditions and cleaning. If there are hundreds of modules, we need to change the domain name and browser, which will be a lot of work and troublesome. At this time, we can use the idea of ​​inheritance to only change it once

We can put the premise and cleanup into a separate file, the specific code is as follows

from selenium import webdriver
import unittest

class Init(unittest.TestCase):
    @classmethod
    def setUpClass(cls) -> None:
        cls.driver=webdriver.Chrome()
        cls.driver.maximize_window()
        cls.driver.get('http://www.baidu.com')
        cls.driver.implicitly_wait(30)

    @classmethod
    def tearDownClass(cls) -> None:
        cls.driver.quit()

Then we can inherit it when we write test cases, the specific code is as follows

from selenium import webdriver
import unittest

from 单元测试框架.test.init import Init
class BaiduTest(Init):
    def test_baidu_title(self):
        '''百度测试:验证百度首页的title'''
        # assert self.driver.title=='百度一下,你就知道'
        self.assertEqual(self.driver.title,'百度一下,你就知道')

    def test_baidu_url(self):
        '''百度测试:验证百度首页的url'''
        assert self.driver.current_url=='https://www.baidu.com/'

    def test_baidu_video(self):
        '''百度测试:验证点击视频后跳转到视频的页面'''
        nowhandler=self.driver.current_window_handle
        self.driver.find_element_by_link_text('视频').click()
        allhandlers=self.driver.window_handles
        for handler in allhandlers:
            if handler!=nowhandler:
                self.driver.switch_to.window(handler)
                self.assertTrue(self.driver.current_url,'https://haokan.baidu.com/?sfrom=baidu-top')
                self.driver.close()
        self.driver.switch_to.window(nowhandler)

    def test_baidu_map(self):
        '''百度测试:验证点击地图后跳转到地图的页面'''
        nowhandler=self.driver.current_window_handle
        self.driver.find_element_by_link_text('地图').click()
        allhandlers=self.driver.window_handles
        for handler in allhandlers:
            if handler!=nowhandler:
                self.driver.switch_to.window(handler)
                self.assertTrue(self.driver.current_url.startswith('https://map.baidu'))
                self.driver.close()
        self.driver.switch_to.window(nowhandler)

if __name__ == '__main__':
    unittest.main()
现在我也找了很多测试的朋友,做了一个分享技术的交流群,共享了很多我们收集的技术文档和视频教程。
如果你不想再体验自学时找不到资源,没人解答问题,坚持几天便放弃的感受
可以加入我们一起交流。而且还有很多在自动化,性能,安全,测试开发等等方面有一定建树的技术大牛
分享他们的经验,还会分享很多直播讲座和技术沙龙
可以免费学习!划重点!开源的!!!
qq群号:110685036

2. Parameterization

In the unittest test framework, the library used for parameterization is: parameterized The installation method is: pip3 install parameterized

to parameterize:

We apply the same test steps to different test scenarios, then we can use parameterization

The problem that can be solved is that a small amount of test code can be used to cover more test scenarios

For example: let's test the login module of sina mailbox, the code is as follows:

from selenium import webdriver
import unittest
import time as t
class BaiduTest(unittest.TestCase):
    def setUp(self) -> None: #前提
        self.driver=webdriver.Chrome()
        self.driver.get('https://mail.sina.com.cn/')
        self.driver.maximize_window()
        self.driver.implicitly_wait(30)

    def tearDown(self) -> None: #清理
        self.driver.quit()
    def test_sina_null(self):
        '''sina邮箱验证:登录账户为空'''
        self.driver.find_element_by_class_name('loginBtn').click()
        divText=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
        self.assertEqual(divText.text,'请输入邮箱名')

    def test_sina_email_format(self):
        '''sina邮箱验证:登录邮箱格式不正确'''
        self.driver.find_element_by_id('freename').send_keys('qwert')
        self.driver.find_element_by_class_name('loginBtn').click()
        divText=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
        self.assertEqual(divText.text,'您输入的邮箱名格式不正确')

    def test_sina_username_error(self):
        '''sina邮箱验证:登录账户不匹配'''
        self.driver.find_element_by_id('freename').send_keys('[email protected]')
        self.driver.find_element_by_id('freepassword').send_keys('asdfg')
        self.driver.find_element_by_class_name('loginBtn').click()
        t.sleep(3)
        divText=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
        self.assertEqual(divText.text,'登录名或密码错误')

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

Since the login module is mainly for the verification of the input form of the user name and password and the verification of the error message, we can parameterize the verification of the user name, password, and error message. The specific implementation code is as follows:

 from selenium import  webdriver
import  unittest
import  time as t
from parameterized import  parameterized,param
class BaiduTest(unittest.TestCase):
    def setUp(self) -> None: #前提
        self.driver=webdriver.Chrome()
        self.driver.get('https://mail.sina.com.cn/')
        self.driver.maximize_window()
        self.driver.implicitly_wait(30)

    def tearDown(self) -> None: #清理
        self.driver.quit()

    @parameterized.expand([
        param('','','请输入邮箱名'),
        param('wertasd', 'asdf', '您输入的邮箱名格式不正确'),
        param('[email protected]', 'asdf', '登录名或密码错误')
    ])
    def test_sina_login(self,username,password,result):
        self.driver.find_element_by_id('freename').send_keys(username)
        t.sleep(3)
        self.driver.find_element_by_id('freepassword').send_keys(password)
        t.sleep(3)
        self.driver.find_element_by_class_name('loginBtn').click()
        t.sleep(3)
        divText=self.driver.find_element_by_xpath('/html/body/div[3]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]')
        self.assertEqual(divText.text,result)

3. Assertion

assertEqual

assertEqual() is to verify that two values ​​are equal, and the data type and content of the value are also equal, see the example code:

from selenium import webdriver
import unittest
class BaiduTest(unittest.TestCase):
    def setUp(self) -> None:
        self.driver=webdriver.Chrome()
        self.driver.get('http://www.baidu.com')
        self.driver.maximize_window()
        self.driver.implicitly_wait(30)

    def tearDown(self) -> None:
        self.driver.quit()

    def test_baidu_title(self):
        '''百度测试:验证百度首页的title'''
        # assert self.driver.title=='百度一下,你就知道'
        self.assertEqual(self.driver.title,'百度一下,你就知道')

assertTrue

The return type is bool, that is, to verify the object under test. If the return type is boolean and true, then the result verification is passed. Then the method assertFlase() verifies that the content returned by the object under test is false. See the example code:

from selenium import webdriver
import unittest
import time as t
class BaiduTest(unittest.TestCase):
    def setUp(self) -> None: #前提
        self.driver=webdriver.Chrome()
        self.driver.get('https://mail.sina.com.cn/')
        self.driver.maximize_window()
        self.driver.implicitly_wait(30)

    def tearDown(self) -> None: #清理
        self.driver.quit()

    def test_sina_isLogin(self):
        '''sina邮箱验证,判断自动登录是否勾选'''
        isLogin=self.driver.find_element_by_id('store1')
        self.assertTrue(isLogin.is_selected())

assertIn

The value of assertIn() is whether a value is included in another value. Here I would like to emphasize that in the assertIn() method, there are two parameters, so the inclusion of a value is actually the first The second actual parameter contains the first actual parameter. The opposite method is assertNotIn(), see the example code:

import unittest
from selenium import webdriver
class UiTest(unittest.TestCase):
def setUp(self) -> None:
self.driver=webdriver.Chrome()
self.driver.maximize_window()
self.driver.get('http://www.baidu.com')
self.driver.implicitly_wait(30)
def tearDown(self) -> None:
self.driver.quit()
def test_baidu_title_001(self):
self.assertIn('百度',self.driver.title)
def test_baidu_title_002(self):
self.assertIn('百度⼀下,你就知道',self.driver.title)
if __name__ == '__main__':
unittest.main()

4. Test report

In the framework of unittest, HTMLTestRunner is required to generate test reports

import unittest
import os
from 单元测试框架.HTMLTestRunner import HTMLTestRunner #从HTMLTestRunner模块调用HTMLTestRunner类

def getTests():
    '''加载所有的测试模块'''
    suite=unittest.TestLoader().discover(
        #找到被执行模块的路径
        start_dir=os.path.dirname(__file__),
        #加载路径下所有以test_开头的测试模块的文件
        pattern='test_*.py' #正则表达式
    )
    return suite

def runSuite():
    unittest.TextTestRunner().run(getTests())

def base_dir():
    return os.path.dirname(os.path.dirname(__file__))#获取当前目录的上级目录

def run():
    fp=open(os.path.join(base_dir(),'report','report.html'),'wb')#拼接report.html的路径 wb 二进制的方式写入
    runner=HTMLTestRunner(
        stream=fp,  #流 执行一个写入一个
        title='UI自动化测试报告',
        description='' 
    )
    runner.run(getTests())

if __name__ == '__main__':
    run()

How to solve the problem that the test report generated each time does not cover the previous test report and is retained at the same time:

Solution: introduce the time library to obtain the timestamp

code show as below:

import time
import unittest
import os
from HTMLTestRunner import HTMLTestRunner

def getTests():
    '''加载所有的测试模块'''
    suite=unittest.TestLoader().discover(
        #找到被执行模块的路径
        start_dir=os.path.dirname(__file__),
        #加载路径下所有以test_开头的测试模块的文件
        pattern='test_*.py' #正则表达式
    )
    return suite

def getNowTime():
    return time.strftime('%y-%m-%d %H-%M-%S',time.localtime(time.time()))

def base_dir():
    return os.path.dirname(os.path.dirname(__file__))

def run():
    fp=open(os.path.join(base_dir(),'report',getNowTime()+'report.html'),'wb')
    runner=HTMLTestRunner(
        stream=fp,
        title='UI自动化测试报告',
        description=''
    )
    runner.run(getTests())

if __name__ == '__main__':
    run()

In this way, a test report will be generated each time it is executed:

The following are supporting learning materials. For friends who do [software testing], it should be the most comprehensive and complete preparation warehouse. This warehouse also accompanied me through the most difficult journey. I hope it can help you too!

Software testing interview applet

The software test question bank maxed out by millions of people! ! ! Who is who knows! ! ! The most comprehensive quiz mini program on the whole network, you can use your mobile phone to do the quizzes, on the subway or on the bus, roll it up!

The following interview question sections are covered:

1. Basic theory of software testing, 2. web, app, interface function testing, 3. network, 4. database, 5. linux

6. web, app, interface automation, 7. performance testing, 8. programming basics, 9. hr interview questions, 10. open test questions, 11. security testing, 12. computer basics

Information acquisition method:

Guess you like

Origin blog.csdn.net/IT_LanTian/article/details/132286849