十、UI自动化unittest插件工具

unittest插件工具

unittest在线安装

在线安装命令

pip install parameterized
pip install HTMLTestReport

以管理员运行命令提示符安装

image

image

安装完成后打开PyCharm点击设置

image

验证查看是否安装成功

image

测试用例(TestCase)

  • 测试用例所在的类, 必须继承自unittest.TestCase
  • 每一个测试用例名称, 必须小写的test开头

断言

self.assertEqual(预期结果, 实际结果) # 断言预期结果与实际结果是否相同
# 等同于语法: assert 预期结果 == 实际结果
self.assertIn(预期结果, 实际结果) # 断言预期结果是在实际结果中包含
# 等同于语法: assert 预期结果 in 实际结果

setup和teardown

  • setUp和tearDown
    • 每个测试用例执行前会自动调用setUp
    • 每个测试用例执行后会自动调用tearDown
  • setUpClass和tearDownClass
    • 这两个方法必须是类方法
    • 所有测试用例执行前会自动调用setUpClass
    • 所有测试用例执行后会自动调用tearDownClass
# test_01.py
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import unittest

class TestLogin(unittest.TestCase): # 如果使用unittest, 测试用例所在的类, 一定要继承自TestCase
    def setUp(self): # 等同于pytest中的setup, 每个测试用例执行前会自动调用setUp
        print("setUp")

    def tearDown(self): # 等同于pytest中的teardown, 每个测试用例执行后会自动调用tearDown
        print("tearDown")

    @classmethod
    def setUpClass(cls): # 等同于pytest中的setup_class, 所有测试用例执行前, 自动调用setUpClass
        print("setUpClass")

    @classmethod
    def tearDownClass(cls): # 等同于pytest中的teardown_class, 所有测试用例执行后, 自动调用tearDownClass
        print("tearDownClass")

    def test_01(self):  # 强制规定测试用例的名称, 必须是test开头
        driver = webdriver.Chrome()
        driver.get("http://hmshop-test.itheima.net/Home/user/login.html")
        driver.find_element(By.ID, "username").send_keys("13912121212")
        driver.find_element(By.ID, "password").send_keys("111111")
        driver.find_element(By.ID, "verify_code").send_keys("8888")
        driver.find_element(By.NAME, "sbtbutton").click()
        time.sleep(2)
        text = driver.find_element(By.CLASS_NAME, "layui-layer-content").text
        self.assertEqual("密码错误!", text) # 断言text的值是否为"密码错误!"
        driver.quit()

    def test_02(self):  # 强制规定测试用例的名称, 必须是test开头
        driver = webdriver.Chrome()
        driver.get("http://hmshop-test.itheima.net/Home/user/login.html")
        driver.find_element(By.ID, "username").send_keys("13912121212")
        driver.find_element(By.ID, "password").send_keys("123456")
        driver.find_element(By.ID, "verify_code").send_keys("1234")
        driver.find_element(By.NAME, "sbtbutton").click()
        time.sleep(2)
        text = driver.find_element(By.CLASS_NAME, "layui-layer-content").text
        self.assertEqual("验证码错误", text) # 断言text的值是否为"验证码错误!"
        driver.quit()
  • 执行测试用例的代码
import unittest
'''
loader = unittest.TestLoader()  # 可以自动的查找符合条件的测试用例
suite = loader.discover(".", "test*.py") # 在当前目录查找测试用例, 文件名test开头, 扩展名为py的文件中找
runner = unittest.TextTestRunner() # runner对象的作用是执行测试用例
runner.run(suite) # run方法的作用是执行括号里测试套件中的测试用例
'''
if __name__ == "__main__":
    unittest.TextTestRunner().run(unittest.TestLoader().discover(".", "test*.py")) # run方法的作用是执行括号里测试套件中的测试用例

参数化

  • 导包from parameterized import parameterized
  • 在需要参数化的测试用例前
@parameterized.expand([(参数化用到的实参), (......)])
# test_02.py
from selenium import webdriver
from selenium.webdriver.common.by import By
import time
import unittest
from parameterized import parameterized

class TestLogin(unittest.TestCase):
    @parameterized.expand([("13912121212", "111111", "8888", "密码错误!"),
                           ("13912121212", "123456", "1234", "验证码错误")])
    def test_01(self, username, password, verify_code, expect):
        driver = webdriver.Chrome()
        driver.get("http://hmshop-test.itheima.net/Home/user/login.html")
        driver.find_element(By.ID, "username").send_keys(username)
        driver.find_element(By.ID, "password").send_keys(password)
        driver.find_element(By.ID, "verify_code").send_keys(verify_code)
        driver.find_element(By.NAME, "sbtbutton").click()
        time.sleep(2)
        text = driver.find_element(By.CLASS_NAME, "layui-layer-content").text
        self.assertEqual(expect, text) # 断言expect与实际结果是否相同
        driver.quit()

生成测试报告

import unittest
from htmltestreport import HTMLTestReport

# 实例化TestLoader类为对象loader
loader = unittest.TestLoader()
# 调用loader对象的discover方法, 返回一个测试套件suite, suite中存放的是discover方法找到的所有测试用例
suite = loader.discover(".", "test_02.py")
# 实例化HTMLTestReport类为对象runner, 括号里面是生成测试报告的文件名
runner = HTMLTestReport("./report.html")
# 调用runner对象的run方法, 执行suite中的测试用例
runner.run(suite)

运行测试用例

import unittest 
from htmltestreport import HTMLTestReport
suite = unittest.TestLoader().discover("./scripts", "test*.py")
HTMLTestReport("report.html").run(suite)

log处理

import logging
from logging import handlers

class LogTools:
    @classmethod
    def init_log(cls):
        logger = logging.getLogger()  # 初始化日志对象
        logger.setLevel(logging.INFO)  # 设置日志器对应的日志级别
		'''
            asctime 时间
            levelname log级别
            name 用户名, 如果在windows上执行, 一般都是root
            filename 生成log的py文件名  
            lineno 在py文件中第几行生成的log信息
            message log信息的内容
            '''
        # 定义控制台处理器
		# 在屏幕输出log信息
        sh = logging.StreamHandler()
        # 定义文件处理器, 下面括号中是log文件的文件名和字符集编码格式
		# 把log写入到文件
        fh = logging.handlers.TimedRotatingFileHandler("./log/a.log", encoding="UTF-8")
        # 定义格式
        fmt = "%(asctime)s %(levelname)s %(name)s %(filename)s %(lineno)d %(message)s"
        formatter = logging.Formatter(fmt)
        # 设置处理器格式
		# 把log的格式设置到屏幕对象中
        sh.setFormatter(formatter)
        fh.setFormatter(formatter)
        # 把处理器添加到handler中
        logger.addHandler(sh)
		# 把log的格式设置到文件对象中
        logger.addHandler(fh)

# 输出相对应的级别日志
logger.log_error("error测试")
logger.log_info("info测试")

    # 写日志
    @classmethod
    def log(cls, msg):
        logging.info(msg)
posted @ 2022-05-27 20:10  鬼谷仙生  阅读(202)  评论(0编辑  收藏  举报