Pruebas automatizadas: marco de prueba unitaria, que combina teoría y práctica

prueba de unidad

1. ¿Qué es el marco Unittest?

Python viene con un marco de pruebas unitarias

2. ¿Por qué utilizar el marco UnitTest?

>Casos de uso de ejecución por lotes

> Proporcionar un rico conocimiento sobre afirmaciones

>Puede generar informes

3. Elementos centrales:

1) TestCase (caso de prueba)

2) TestSuite (conjunto de pruebas)

3) TestRunner (ejecución de prueba, ejecución del conjunto de pruebas TestUite)

4) TestLoader (ejecuta casos de prueba en lotes; busca módulos que comiencen con letras específicas en la carpeta especificada) [Recomendado]

5) Accesorio (dos funciones fijas, una utilizada durante la inicialización y otra utilizada al final))

A continuación, ampliaremos los elementos centrales para comprender el marco de prueba unitaria:

Primero, introduzcamos las reglas de casos de uso de unittest:

1. El archivo de prueba debe importar el paquete: importar prueba unitaria

2. La clase de prueba debe heredar unittest.TestCase

3. El método de prueba debe comenzar con test_

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

 

1. TestCase (caso de prueba)

1. Es un archivo de código. El código del caso de uso real está escrito en el archivo de código (las impresiones en el interior son todos casos de prueba de simulación)

# 1、导包
# 2、自定义测试类
# 3、在测试类中书写测试方法 采用print 简单书写测试方法
# 4、执行用例


import unittest


# 2、自定义测试类,需要继承unittest模块中的TestCase类即可
class TestDemo(unittest.TestCase):
    # 书写测试方法,测试用例代码,书写要求,测试方法必须test_ 开头
    def test_method1(self):
        print('测试方法1-1')


    def test_method2(self):
        print('测试方法1-2')


# 4、执行测试用例
# 4.1 光标放在类后面执行所有的测试用例
# 4.2 光标放在方法后面执行当前的方法测试用例

Nota: test_ definido por def es un caso de prueba. El caso de prueba solo se ejecutará si se ejecuta __name__ == '___mian___'. Otras funciones ordinarias no se ejecutarán y se llamarán y ejecutarán a través de self.

2. TestSuite (conjunto de pruebas) y TestRunner (ejecución de pruebas)

1. TestSuite (conjunto de pruebas): se utiliza para ensamblar, empaquetar y administrar múltiples archivos TestCase (casos de prueba)

2. TestRunner (ejecución de prueba): se utiliza para ejecutar TestSuite (conjunto de pruebas)

Código: Primero, se deben preparar varios archivos de casos de prueba para implementar TestSuite y TestRunner. El siguiente código ha preparado dos archivos de casos de prueba unittest_Demo2 y unittest_Demo1.

# 1、导包
# 2、实例化(创建对象)套件对象
# 3、使用套件对象添加用例方法
# 4、实例化对象运行
# 5、使用运行对象去执行套件对象


import unittest


from unittest_Demo2 import TestDemo
from unittest_Demo1 import Demo


suite = unittest.TestSuite()


# 将⼀个测试类中的所有⽅法进⾏添加
# 套件对象.addTest(unittest.makeSuite(测试类名))
suite.addTest(unittest.makeSuite(TestDemo))
suite.addTest(unittest.makeSuite(Demo))


# 4、实例化运行对象
runner = unittest.TextTestRunner();
# 5、使用运行对象去执行套件对象
# 运⾏对象.run(套件对象)
runner.run(suite)

3. TestLoader (carga de prueba)

ilustrar:

  1. Agregar métodos de prueba calificados al conjunto de pruebas

2. Busque los métodos que comienzan con la prueba en los archivos del módulo que comienzan con la letra especificada en el archivo del directorio especificado, agregue estos métodos al conjunto de pruebas y finalmente devuelva el conjunto de pruebas.

3. Igual que la función Testsuite, es un complemento de otras funciones y se utiliza para ensamblar casos de prueba.

Generalmente, los casos de prueba se escriben en la carpeta Casos. Cuando hay demasiados casos de prueba, puede considerar TestLoader.

写法:
1. suite = unittest.TestLoader().discover("指定搜索的目录文件","指定字母开头模块文件")
2. suite = unittest.defaultTestLoader.discover("指定搜索的目录文件","指定字母开头模块文件") 【推荐】
注意:
  如果使用写法1,TestLoader()必须有括号。
# 1. 导包
# 2. 实例化测试加载对象并添加用例 ---> 得到的是 suite 对象
# 3. 实例化 运行对象
# 4. 运行对象执行套件对象


import unittest


# 实例化测试加载对象并添加用例 ---> 得到的是 suite 对象
# unittest.defaultTestLoader.discover('用例所在的路径', '用例的代码文件名')
# 测试路径:相对路径
# 测试文件名:可以使用 * 通配符,可以重复使用
suite = unittest.defaultTestLoader.discover('./Case', 'cs*.py')
runner = unittest.TextTestRunner()
runner.run(suite)
TestSuite与TestLoader区别:
  共同点:都是测试套件
  不同点:实现方式不同
    TestSuite: 要么添加指定的测试类中所有test开头的方法,要么添加指定测试类中指定某个test开头的方法
    TestLoader: 搜索指定目录下指定字母开头的模块文件中以test字母开头的方法并将这些方法添加到测试套件中,最后返回测试套件

4. Accesorio (accesorio de prueba)

Es una estructura de código que se ejecutará automáticamente bajo determinadas circunstancias.

4.1 Nivel de método

Una estructura que se llama automáticamente antes y después de que se ejecute cada método de prueba (código de caso de uso).

def setUp(), se ejecutará antes de que se ejecute cada método de prueba (inicialización)

def tearDown(), se ejecutará (liberará) después de que se ejecute cada método de prueba

Características: varias funciones de prueba, ejecutadas varias veces. SetUp se ejecutará antes de ejecutar cada función de prueba y TearDwon se ejecutará después de la ejecución.

# 初始化
def setUp(self):
    # 每个测试方法执行之前执行的函数
    pass


# 释放
def tearDown(self):
    # 每个测试方法执行之后执行的函数
    pass
场景:当你要登录自己的用户名账户的时候,都会输入网址,当你准备不用这个页面了,都会关闭当前页面;
  1、输入网址 (方法级别)
  2、关闭当前页面 (方法级别)

4.2 Nivel de clase

Una estructura que se llamará automáticamente antes y después de que se ejecuten todos los métodos en cada clase de prueba (una vez antes y después de la ejecución en toda la clase)

def setUpClass(), antes de todos los métodos de la clase

def tearDownClass(), después de todos los métodos de la clase

Características: Ejecute setUpClass una vez antes de que se ejecute la clase de prueba y ejecute TearDownClass una vez después de que se ejecute la clase.

Nota: los métodos de clase deben estar decorados con @classmethod

@classmethod
    def setUpClass(cls):
        print('-----------1.打开浏览器')


    @classmethod
    def tearDownClass(cls):
        print('------------5、关闭浏览器')
场景:你上网的整个过程都首先需要打开浏览器,关闭浏览器,而他们整个过程都需要执行一次,那么就可以用类级别。

Plantilla de caso: una combinación de implementación a nivel de clase y a nivel de método

(Error en la transferencia de la imagen del enlace externo. El sitio de origen puede tener un mecanismo anti-leeching. Se recomienda guardar la imagen y cargarla directamente (
img-GBxQV2uP-1647245316010) (C:/Users/15277/AppData/Roaming/Typora/ typora-user-images/ image-20220303153824329.png)]

提示:
  无论使用函数级别还是类级别,最后常用场景为:
    初始化:
      1. 获取浏览器实例化对象
      2. 最大化浏览器
      3. 隐式等待
    结束:
      关闭浏览器驱动对象

5. Afirmación ☆

1. ¿Qué es una afirmación?

Deje que el programa reemplace el trabajo manual y juzgue automáticamente si los resultados esperados son consistentes con los resultados reales.

El resultado de la afirmación:

1), Es cierto, el caso de uso pasa

2), Falso, el código genera una excepción y el caso de uso falla.

3) Para usar afirmaciones en unittest, debe pasar el método self.assert

2. ¿Por qué deberíamos afirmar:

Los scripts de automatización se ejecutan sin supervisión y se necesitan afirmaciones para determinar si la ejecución del script de automatización se realiza.

Nota: Los scripts de automatización no escriben aserciones, lo que equivale a no ejecutar la prueba.

3. Afirmaciones de uso común:

self.assertEqual(ex1, ex2) # 判断ex1 是否和ex2 相等
self.assertIn(ex1, ex2) #  ex2是否包含 ex1   注意:所谓的包含不能跳字符
self.assertTrue(ex) #  判断ex是否为True


重点讲前两个assertEqual 和 assertIn
方法:
assertEqual:self.assertEqual(预期结果,实际结果) 判断的是预期是否相等实际
assertIn:self.assertIn(预期结果,实际结果) 判断的是预期是否包含实际中
assertIn('admin', 'admin') # 包含
assertIn('admin', 'adminnnnnnnn') # 包含
assertIn('admin', 'aaaaaadmin') # 包含
assertIn('admin', 'aaaaaadminnnnnnn') # 包含
assertIn('admin', 'addddddmin') # 不是包含
# Login 函数我已经封装好了,这里直接导包调用就可以了。


import unittest


from login import Login


class TestLogin(unittest.TestCase):
    """正确的用户名和密码: admin, 123456, 登录成功"""


    def test_success(self):
        self.assertEqual('登录成功', Login('admin', '123456'))


    def test_username_error(self):
        """错误的用户名: root, 123456, 登录失败"""
        self.assertEqual('登录失败', Login('root', '123456'))


    def test_password_error(self):
        """错误的密码: admin, 123123, 登录失败"""
        self.assertEqual('登录失败', Login('admin', '123123'))


    def test_error(self):
        """错误的用户名和错误的密码: aaa, 123123, 登录失败"""
        # self.assertEqual('登录失败',Login('登陆失败','123123'))
        self.assertIn('失败', Login('登录失败', '123123'))

6. Saltar

Para algunas funciones de prueba y clases de prueba inacabadas que no cumplen con las condiciones de prueba y no desean ejecutarse, puede usar skip

"""
使用方法,装饰器完成
代码书写在 TestCase 文件
"""
# 直接将测试函数标记成跳过
@unittest.skip('跳过条件')
# 根据条件判断测试函数是否跳过 , 判断条件成立, 跳过
@unittest.skipIf(判断条件,'跳过原因')
import unittest


version = 20


class TestDemo1(unittest.TestCase):
    
    @unittest.skip('直接跳过')
    def test_method1(self):
        print('测试用例1-1')


    @unittest.skipIf(version > 19, '版本大于19,测试跳过')
    def test_method2(self):
        print('测试用例1-2')

resultado

7. Basado en datos (ddt de prueba unitaria) ☆

ddt: pruebas de controlador de datos

Basado en datos: los datos impulsan la ejecución de todo el caso de prueba, es decir, los datos de la prueba determinan los resultados de la prueba.

Los problemas que resuelven las soluciones basadas en datos son:

1) Código y datos separados para evitar la redundancia de código

2) No escriba lógica de código repetida;

Necesita instalar el paquete ddt en el intérprete de Python para usarlo:

Para verificar si está instalado, ingrese la lista de pip en cmd y asígnele un nombre. Si hay ddt, significa que la instalación se realizó correctamente.

gramática:

1. Para utilizar el controlador de datos, agregue el modificador @ddt antes de la clase.

Nota: en el método se utiliza la impresión. Por conveniencia, los casos de prueba se simulan, principalmente para aprender basado en datos. En la práctica, el código del caso de prueba está escrito en el método.

import unittest
from ddt import ddt, data


@ddt  
class TestDemo(unittest.TestCase):
    # 单一参数
    @data('17611110000', '17611112222')
    def test_1(self, phone):
        print('测试一电话号码:', phone)
        
if __name__ == '__main__':
    unittest.main()
else:
    pass

1), use ddt con selenio

"""
unittest + selenium
"""
import unittest
from time import sleep


from ddt import ddt, data
from selenium import webdriver


@ddt
class TestBaidu(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.driver.get('https://www.sogou.com/')


    def tearDown(self) -> None:
        sleep(3)
        self.driver.quit()
  
    # 单一参数
    @data('易烊千玺', '王嘉尔')
    def test_01(self, name):
        self.driver.find_element_by_id('query').send_keys(name)
        self.driver.find_element_by_id('stb').click()


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

self: equivalente a esto en java, una referencia al objeto actual, self.driver define la variable del controlador.

2. En la práctica, es imposible pasar un solo parámetro y se utilizarán varios parámetros:

注意事项:
1)、多个数据传参的时候@data里面是要用列表形式
2)、会用到 @unpack 装饰器 进行拆包,把对应的内容传入对应的参数;
import unittest
from ddt import ddt, data, unpack


@ddt
class TestDemo(unittest.TestCase):
    # 多参数数据驱动
    @data(['admin', '123456'])
    # unpack 是进行拆包,不然会把列表里面的数据全部传到username这个一个参数,我们要实现列表中的两个数据分别传入对应的变量中
    @unpack
    def test_2(self, username, password):
        print('测试二:', username, password)




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

Sin embargo, los pasos anteriores tienen que ver con los datos en el código. Si desea probar datos como n números de teléfonos móviles, será muy problemático escribirlos todos en el decorador @data, lo que provocará la separación del código y los datos. en el controlador de datos.

3. Coloque los datos en un archivo de texto y lea los datos del archivo, como JSON, excel, xml, txt y otros archivos de formato. El tipo de archivo json se demuestra aquí.

procesamiento de archivos json, este enlace presenta las operaciones básicas de los archivos json y los archivos Python

(1), impulsado por archivo json

[
  {
    "username": "admin",
    "password": "123456"
  },
  {
    "username": "normal",
    "password": "45678"
  }
]

(2) Lea el archivo json en el código de prueba

import json
import unittest
from ddt import ddt, data, unpack


# 用json多个参数读取
def reads_phone():
    with open('user.json', encoding='utf-8') as f:
        result = json.load(f)  # 列表
        return result
    
@ddt
class TestDemo(unittest.TestCase):
    # 多参数数据驱动
    @data(*reads_phone())
    # unpack 是进行拆包,不然会把列表里面的数据全部传到username这个一个参数,我们要实现列表中的两个数据分别传入对应的变量中
    @unpack
    def test_2(self, username, password):
        print('测试二:', username, password)




if __name__ == '__main__':
    unittest.main()
else:
    pass
注意事项:
1、with open里面默认是 ”r“ 
2、@data 里面的 * 含义是实现每个json对象单个传入方法执行,不然会吧json文件里面所用数据全部传入 
  > * 是元祖;
  > ** 是字典;
3、参数不能传错,要对应

Resultados de:

(3), controlador de archivo txt

Una línea representa un grupo:

admin,123456
normal,456789
import unittest
def read():
    lis = []
    with open('readtext.txt', 'r', encoding='utf-8') as f:
        for line in f.readlines():
            # lis.append(line) #  ['admin,123456\n', 'normal,456789\n']
            # lis.append(line.strip('\n'))  ['admin,123456', 'normal,456789'] 两个字符串
            lis.append(line.strip('\n').split(','))  # [['admin', '123456'], ['normal', '456789']]
    return lis


class TestDome(unittest.TestCase):
    def test_01(self):
        li = read()
        print(li)




if __name__ == '__main__':
    unittest.main()
"""
split():一个字符串里面用某个字符分割,返回列表
strip():去掉两边的字符或者字符串,默认删除空白符(包括'\n', '\r',  '\t',  ' ')
"""

(3), controlador de archivo csv

供应商名称,联系人,移动电话
英业达,张三,13261231234
阿里巴巴,李四,13261231231
日立公司,王五,13261231233

Método de escritura uno:

"""
编写 csvv.py脚本读取csv中的测试数据
"""
import csv
class ReadCsv():
    def read_csv(self):
        lis = []
        # 用csv的API的reader方法!!!!
        data = csv.reader(open('testdata.csv', 'r'))  #!!!!
        next(data, None)
        for line in data:
            lis.append(line)
            # lis.append(line[0])  # 二维数组可以省略行,列不可以省略
            # lis.append(line[1])


        return lis


# 实例化类
readCsv = ReadCsv()
# 打印类中的方法
print(readCsv.read_csv())

Método de escritura dos: recomendado

def csvTest():
    li = []
    with open('user.csv', 'r', encoding='utf-8') as f:
        filename = csv.reader(f)
        next(filename, None)
        for r in filename:
            li.append(r)
        return li

(4), controlador de archivos yaml

-
  username: admin9
  password: 123456
-
  username: normal
  password: 789456

Archivo json correspondiente

[
  {
    "username": "admin9",
    "password": 123456
  },
  {
    "username": "normal",
    "password": 7894
  }
]

Método de escritura:

"""
使用yaml数据驱动
"""


import unittest
from time import sleep


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




@ddt
class YamlTest(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.driver.get('file:///D:/%E6%A1%8C%E9%9D%A2/page/%E6%B3%A8%E5%86%8CA.html')
        self.driver.maximize_window()


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


    # file_data 传入多个参数的时候,@unpack 的解包不起作用
    @unittest.skip
    @file_data('../user.yaml')
    @unpack
    def test_yaml01(self, username, password):
        driver = self.driver
        driver.find_element_by_id('userA').send_keys(username)
        driver.find_element_by_id('passwordA').send_keys(password)


    # 注意:传的参数名称要与yaml文件对应
    # 在yaml数据中文件中采用对象(键值对)的方式来定义数据内容
    @file_data('../user1.yaml')
    def test_yaml02(self, username, password):
        driver = self.driver
        driver.find_element_by_id('userA').send_keys(username)
        driver.find_element_by_id('passwordA').send_keys(password)




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

Nota: el decorador file_date puede leer directamente archivos yaml y json

(4), controlador de archivos de Excel

Al crear una tabla de Excel, debe salir de pychram y crear una tabla de Excel en el directorio raíz para guardarla; de lo contrario, se informará un error.

def read_excel():
    xlsx = openpyxl.load_workbook("../excel.xlsx")
    sheet1 = xlsx['Sheet1']
    print(sheet1.max_row)  # 行
    print(sheet1.max_column)  # 列
    print('=======================================================')
    allList = []
    for row in range(2, sheet1.max_row + 1):
        rowlist = []
        for column in range(1, sheet1.max_column + 1):
            rowlist.append(sheet1.cell(row, column).value)
        allList.append(rowlist)
    return allList

Utilice Excel para iniciar sesión en la operación csdn

"""
测试excel数据驱动
"""


import unittest
from time import sleep


import openpyxl as openpyxl
from ddt import ddt, data, unpack
from selenium import webdriver




# 读取excel表中的数据,使用xlrd,openpyxl
def read_excel():
    xlsx = openpyxl.load_workbook("../excel.xlsx")
    sheet1 = xlsx['Sheet1']
    print(sheet1.max_row)  # 行
    print(sheet1.max_column)  # 列
    print('=======================================================')
    allList = []
    for row in range(2, sheet1.max_row + 1):
        rowlist = []
        for column in range(1, sheet1.max_column + 1):
            rowlist.append(sheet1.cell(row, column).value)
        allList.append(rowlist)
    return allList




@ddt
class ExcelText(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.driver.get('https://passport.csdn.net/login?code=applets')
        self.driver.maximize_window()


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


    @data(*read_excel())
    @unpack
    def test_excel01(self, flag, username, password):
        print(flag, username, password)
        driver = self.driver
        sleep(2)
        driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[2]/div[1]/div/div[1]/span[4]').click()
        driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[2]/div[1]/div/div[2]/div/div[1]/div/input').send_keys(username)
        driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[2]/div[1]/div/div[2]/div/div[2]/div/input').send_keys(password)
        driver.find_element_by_xpath('/html/body/div[2]/div/div[2]/div[2]/div[1]/div/div[2]/div/div[4]/button').click()


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

10. Operación de captura de pantalla

Es imposible que un caso de uso tenga éxito cada vez que se ejecuta, y definitivamente habrá ocasiones en las que no tendrá éxito. Si podemos capturar errores y guardar capturas de pantalla de errores, esta será
una gran característica y también nos facilitará la localización de errores.

Método de captura de pantalla:
driver.get_screenshot_as_file

"""
捕捉异常截图测试
"""
import os.path
import time
import unittest
from time import sleep


from selenium import webdriver




class ScreeshotTest(unittest.TestCase):
    def setUp(self) -> None:
        self.driver = webdriver.Chrome()
        self.driver.get('https://www.sogou.com/')
        self.driver.maximize_window()


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


    def test_01(self):
        driver = self.driver
        driver.find_element_by_id('query').send_keys("易烊千玺")
        driver.find_element_by_id('stb').click()
        sleep(3)
        print(driver.title)
        try:
            self.assertEqual(driver.title, u"搜狗一下你就知道", msg="不相等")
        except:
            self.saveScreenShot(driver, "shot.png")
        sleep(5)


    def saveScreenShot(self, driver, filename):
        if not os.path.exists("./imge"):
            os.makedirs("./imge")


        # 格式十分重要,小写大写敏感 %Y%m%d-%H%M%S
        now = time.strftime("%Y%m%d-%H%M%S", time.localtime(time.time()))
        driver.get_screenshot_as_file("./imge/" + now + "-" + filename)
        sleep(3)




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

11. Informe de prueba

Hay dos tipos de informes de prueba:

1. Informe de prueba integrado
2. Generar informe de prueba de terceros

9.1 Traiga su propio informe de prueba

Solo cuando el código de TestCase se ejecute por separado se generará un informe de prueba.

10.2 Generar informes de prueba de terceros

Aquí necesita un módulo de clase de ejecución de prueba de terceros y luego colóquelo en el directorio del código.

Al igual que estos dos módulos, colóquelos en el directorio de códigos.

步骤:
 1. 获取第三方的 测试运行类模块 , 将其放在代码的目录中
 2. 导包 unittest
 3. 使用 套件对象, 加载对象 去添加用例方法
 4. 实例化 第三方的运行对象 并运行 套件对象
   HTMLTestRunner()

Método de escritura uno:

import unittest


from HTMLTestRunner import HTMLTestRunner


suite = unittest.defaultTestLoader.discover('.', 'Uni*.py')
file = 'report1.html'
with open(file, 'wb') as f:
    runner = HTMLTestRunner(f, 2, '测试报告', 'python3.10')  # 运行对象
    # 运行对象执行套件, 要写在 with 的缩进中
    runner.run(suite)

Método de escritura dos:

"""
生成测试报告
"""
import os.path
import sys
import time
import unittest
from time import sleep


from HTMLTestRunner import HTMLTestRunner


def createsuite():
    discovers = unittest.defaultTestLoader.discover("./cases", pattern="cs*.py")
    print(discovers)
    return discovers




if __name__ == '__main__':
    # 当前路径
    # sys.path 是一个路径的集合
    curpath = sys.path[0]
    print(sys.path)
    print(sys.path[0])


    # 当前路径文件resultreport不存在时,就创建一个
    if not os.path.exists(curpath+'/resultreport'):
        os.makedirs(curpath+'/resultreport')


    # 2、解决重名问题
    now = time.strftime("%Y-%m-%d-%H %M %S", time.localtime(time.time()))
    print(time.time())
    print(time.localtime(time.time()))
    # 文件名是 路径 加上 文件的名称
    filename = curpath+'/resultreport/'+now+'resultreport.html'
    # 打开文件html,是用wb以写的方式打开
    with open(filename, 'wb') as f:
        runner = HTMLTestRunner(f, 2, u"测试报告", u"测试用例情况")
        suite = createsuite()
        runner.run(suite)

La ruta actual aquí también se puede representar por ./! ! !

"""
生成测试报告
"""
import os.path
import sys
import time
import unittest
from time import sleep
from HTMLTestRunner import HTMLTestRunner


def createsuite():
    discovers = unittest.defaultTestLoader.discover("./cases", pattern="cs*.py")
    print(discovers)
    return discovers




if __name__ == '__main__':
    # 当前路径文件resultreport不存在时,就创建一个
    if not os.path.exists('./resultreport'):
        os.makedirs('./resultreport')


    # 2、解决重名问题
    # 格式十分重要 %Y-%m-%d-%H %M %S
    now = time.strftime("%Y-%m-%d-%H %M %S", time.localtime(time.time()))
    print(time.time())
    print(time.localtime(time.time()))
    # 文件名是 路径 加上 文件的名称
    filename = './resultreport/'+now+'resultreport.html'
    # 打开文件html,是用wb以写的方式打开
    with open(filename, 'wb') as f:
        runner = HTMLTestRunner(f, 2, u"测试报告", u"测试用例情况")
        suite = createsuite()
        runner.run(suite)

Aviso:

Crear instancias de objetos en ejecución de terceros. La inicialización de HTMLTestRunner() tiene una variedad de configuraciones personalizables.

HTMLTestRunner()
 1、stream=sys.stdout, 必填,测试报告的文件对象(open ), 注意点,要使用 wb 打开
 2、verbosity=1, 可选, 报告的详细程度,默认 1 简略, 2 详细
 3、title=None, 可选, 测试报告的标题
 4、description=None 可选, 描述信息, Python 的版本, pycharm 版本

El resultado final se genera

El marco de prueba unitaria se basa básicamente en este conocimiento. Hay muchas cosas para recordar en él, por lo que es necesario escribir más código para formar una memoria ...

Finalmente, me gustaría agradecer a todos los que leyeron atentamente mi artículo. Mirando el aumento de fans y atención, siempre hay algo de cortesía. Aunque no es algo muy valioso, si puedes usarlo, ¡puedes llevarlo directamente!

Documento de entrevista de prueba de software

Debemos estudiar para encontrar un trabajo bien remunerado. Las siguientes preguntas de la entrevista provienen de los últimos materiales de entrevista de empresas de Internet de primer nivel como Alibaba, Tencent, Byte, etc., y algunos jefes de Byte han dado respuestas autorizadas. Después de terminar esto set Creo que todos pueden encontrar un trabajo satisfactorio según la información de la entrevista.
 

Insertar descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/jiangjunsss/article/details/133084774
Recomendado
Clasificación