基于pytest自动化测试框架分享

news2024/11/14 21:55:13

一、pytest运行方式与基本规范

1.简单介绍

pytest是一个非常成熟的全功能的Python测试框架,主要有以下几个特点:

  • 简单灵活,容易上手
  • 支持参数化
  • 能够支持简单的单元测试和复杂的功能测试,还可以用来做Web UI自动化测试(pytest+selenium)、接口自动化测试(pytest+requests)
  • pytest具有很多第三方插件,并且可以自定义扩展,比较好用的如pytest-ordering(用例顺序控制)、pytest-rerunfailures(失败case重复执行)、pytest-dependency(用例依赖)等
  • 测试用例的skip和xfail处理
  • 可以很好的和jenkins集成
  • report框架----allure 也支持了pytest

2.pytest用例设计原则

  • 文件名格式:test_*.py 或 *_test.py
  • 类名以 Test 开头,不能包含 init 方法
  • 函数名以 test_ 开头或 _test结尾

3.运行方式

####(1)主函数运行

  • 运行所有:pytest.main()
  • 指定参数:pytest.main([‘-vs’])
  • 指定模块:pytest.main([‘-vs’,‘xxxx.py’])
  • 指定目录:pytest.main([‘-vs’,‘./文件名称’])
  • pytest支持单个函数写法:pytest.main([‘-vs’,‘./文件名/py文件名::类名::方法名’])
    ####(2)命令行运行
  • 运行所有:pytest
  • 指定参数:pytest -vs
  • 指定模块:pytest xxxx.py
  • 指定目录:pytest testcase
  • nodeid 指定运行用例:pytest dir_name::xxx.py::TestClass::test_func
    ####(3)常用参数
  • -q:只打印测试用例的执行结果,不输出环境信息
  • -s:打印详细日志,可显示程序中的 print/logging 输出
  • -v:打印详细的用例执行日志信息
  • -x:遇到测试失败的用例则立刻停止运行
  • -k expr:按关键字表达式运行用例,如 expr 为 “test_a or test_b” 则运行 test_a 和 test_b
  • -m slow:运行使用 mark 标记的测试用例,如:-m slow 则执行所有带 @pytest.mark.slow 装饰器的用例
  • –resultlog=./log.txt 生成log
  • -r:测试结束时显示结果摘要,后面可以跟多个字符,其中 f:失败的用例、E:出错的用例、s:跳过的用例、x:标记失败的用、X:标记成功的用例、p:成功的用例、P:成功用例并输出信息、a:除开 pP 以外的用例、A 全部用例
  • -l:展示运行过程中的全局变量和局部变量
  • –maxfail=n:在第n个失败后停止
  • –reruns 失败重跑
  • –lf, --last-failed:只重新运行失败。
  • –ff, --failed-first:先运行故障,然后运行其余测试。

二、用例前置、后置处理(fixture)

fixture属于pytest中的一个方法。fixture可以用作测试用例的前置和后置操作,其中fixture命令规范没有像setup和teardown固定格式。可以随意命名。控制fixture的前置和后置操作是通过yield关键字进行来区分的,代码在yield前面的属于前置操作,代码在yield后面的属于后置操作。并且fixture也没有强烈的要求必须要前后置同时存在,可以只存在前置也可以只存在后置。fixture如果有后置内容,无论遇到什么问题,都会进行执行后置的代码。

注意:在conftest.py文件中的多个fixture函数还可以互相调用,但是要注意的是,比如fixture1调用fixture2时,那么fixture1的scope范围一定要比fixture2的范围小,否则就会报错

1、基本使用

# 定义一个夹具函数,使用装饰器pytest.fixture
@pytest.fixture()
def login():
    print("用户登录")
    yield
    print("用户登出")
 
 
# 方式1:作为参数传递
def test_demo_01(login):
    print("执行 test_demo_01 用例")
 
# 方式2:使用 pytest.mark.usefixtures 装饰器使用指定fixture,可以传入多个 fixture,执行顺序依次执行
@pytest.mark.usefixtures("login")
def test_demo_02():
    print("执行 test_demo_02 用例")

2、fixture函数参数

语法:@pytest.fixture(scope=“function”, params=None, autouse=False, ids=None, name=None)
参数解释:

  • scope:控制fixture的作用范围。类似于setup_module、setup_class等。取值如下:
取值作用
function函数级 每一个函数或方法都会调用
class类级 每一个类都会被调用
module模块级 每一个.py文件调用一次
session会话级 次会话只需要运行一次,会话内所有方法及类,模块都共享这个方法
  • autouse:默认是 False ,若为 True,则每个测试函数都会自动调用该 fixture ,无需传入 fixture 函数名。
@pytest.fixture(autouse=True)
def fix_demo():
    print("我是 fix_demo 的返回值")
 
 
# 不需要传入fixture函数
def test_demo_03():
    print("执行 test_demo_03 用例")
 
 
执行结果:
test_demo_file_01.py::test_demo_03 我是 fix_demo 的返回值
执行 test_demo_03 用例
PASSED
  • name:fixture 的重命名。重命名后原函数名将不生效
@pytest.fixture(name="new_fix_demo")
def fix_demo():
    print("我是 fix_demo 的返回值")
 
 
# 传入fixture函数名
def test_demo_03(fix_demo):
    print("执行 test_demo_03 用例")
 
 
# 传入重命名的fixture名称
def test_demo_04(new_fix_demo):
    print("执行 test_demo_04 用例")
 
 
#执行后 test_demo_03 用例将报错:fixture 'fix_demo' not found
  • params:fixture 的可选形参列表,支持列表传入,默认None,每个param的值,fixture都会去调用执行一次,类似for循环,可与参数ids一起使用,作为每个参数的标识,用法见ids。被fixture装饰的函数要调用采用:request.param(固定写法)
@pytest.fixture(params=["张三", "李四", "王五"])
def fix_demo(request):
    temp = request.param
    print("我是{0},我来签到".format(temp))
    return temp
 
 
def test_user(fix_demo):
    print("{0}已签到".format(fix_demo))
 
 
运行结果:
test_demo_file_01.py::test_user[\u5f20\u4e09] 我是张三,我来签到
张三已签到
PASSED
test_demo_file_01.py::test_user[\u674e\u56db] 我是李四,我来签到
李四已签到
PASSED
test_demo_file_01.py::test_user[\u738b\u4e94] 我是王五,我来签到
王五已签到
PASSED
 
# 或者与pytest.mark.parametrize装饰器一起使用
@pytest.fixture()
def fix_demo(request):
    temp = request.param
    print("我是{0},我来签到".format(temp))
    return temp
 
@pytest.mark.parametrize("fix_demo", ["张三", "李四", "王五"], indirect=True)   
def test_user(fix_demo):
    print("{0}已签到".format(fix_demo))
  • ids:用例标识ID,与params配合使用,一对一关系
@pytest.fixture(params=["张三", "李四", "王五"], ids=["case01", "case02", "case03"])
def fix_demo(request):
    temp = request.param
    print("我是{0},我来签到".format(temp))
    return temp
 
 
def test_user(fix_demo):
    print("{0}已签到".format(fix_demo))
 
 
运行结果:
test_demo_file_01.py::test_user[case01] 我是张三,我来签到
张三已签到
PASSED
test_demo_file_01.py::test_user[case02] 我是李四,我来签到
李四已签到
PASSED
test_demo_file_01.py::test_user[case03] 我是王五,我来签到
王五已签到
PASSED

3、fixture 对比 setup、teardown

  • conftest.py专为fixture而生,全局共享conftest.py,可以在不同目录下创建conftest.py。可以统一管理、多处调用和自动调用
  • 命名方式灵活,不局限于setup和teardown命名方式
  • 自动引入不需要导入
  • fixture出现重名,就近原则。查找路径:当前模块->当前目录->上一层目录->…->项目root目录(不会去平级的目录查找)

4、yield 和 addfinalizer 终结函数

yield在python中表示生成器,同时也是一种函数的返回值类型,是函数上下文管理器,使用yield被调fixture函数执行遇到yield会停止执行,接着执行调用的函数,调用的函数执行完后会继续执行fixture函数yield关键后面的代码。

@pytest.fixture()
def login_1():
    print("开始登录")
    result = "登录后的token"
    yield result       
    print("退出登录")
 
 
def test_demo_01(login_1):
    a = login_1
    print(a)
    print("执行 test_demo_01 用例")
 
 
运行结果:
test_demo_file_01.py::test_demo_01 开始登录
登录后的token
PASSED退出登录

三、常见的处理方法

1、用例失败重试

用例在运行过程可能因为环境原因、网络波动、莫名异常或网络延迟造成用例获取响应失败等。通过引入失败用例重跑机制来消除因为网络不稳定而引起的用例运行失败。
插件官网说明:https://pypi.org/project/pytest-rerunfailures/
安装pytest插件:pip install pytest-rerunfailures 。使用方式有以下两种:
(1)命令行参数形式
pytest --reruns 重试次数
pytest --reruns 重试次数 --reruns-delay 次数之间的延时间隔设置(单位:秒)

# 文件 test_demo_file_01.py
 
 
def test_demo_01(login):
    r = random.randint(1, 2)
    assert r == 1
 
 
def test_demo_02(login):
    b = 1 + 2
    assert b == 3
 
 
执行:pytest --reruns 3 --reruns-delay 3 test_demo_file_01.py

(2)装饰器方式
语法:@pytest.mark.flaky(reruns=重试次数, reruns_delay=次数之间的延时设置(单位:秒)) # reruns_delay 非必须

# 文件 test_demo_file_01.py
 
 
@pytest.mark.flaky(reruns=3, reruns_delay=3)
def test_demo_01():
    r = random.randint(1, 2)
    assert r == 1

2、用例跳过

在实际测试场景中,会遇到功能阻塞、功能未实现或环境等外部因素导致用例无法正常执行的情况,此时可以使用pytest提供的 skip 和 skipif 来跳过用例。

(1)无条件跳过

语法:
@pytest.mark.skip() # 跳过类、方法或用例,不备注原因
@pytest.mark.skip(reason=“”) # 跳过类、方法或用例,备注原因

# 文件 test_demo_file_01.py
 
 
@pytest.mark.skip(reason="跳过这个用例")
def test_demo_02():
    b = 1 + 2
    assert b == 3
 
 
执行结果:
test_demo_file_01.py::test_demo_02 SKIPPED (跳过这个用例)
(2)有条件跳过

语法:@pytest.mark.skipif(contdition, reason=“”) # 满足条件时跳过类、方法或用例,需备注原因

# 文件 test_demo_file_01.py
 
 
@pytest.mark.skipif(1 == 1, reason="跳过整个测试类")
class TestDemo:
 
    def test_func_01(self):
        print("test_func_01")
 
    def test_func_02(self, login):
        print("test_func_02")
 
 
运行结果:
test_demo_file_01.py::TestDemo::test_func_01 SKIPPED (跳过整个测试类)
test_demo_file_01.py::TestDemo::test_func_02 SKIPPED (跳过整个测试类)
(3)用例内跳过

语法:@pytest.skip(reason=“”) # 在用例内部执行判断,不满足条件时跳过用例

# 文件 test_demo_file_01.py
 
 
class TestDemo:
 
    def test_func_01(self):
        a = random.randint(1, 2)
        if a == 1:
            pytest.skip(reason="不满足执行条件,跳过该用例")
        print("test_func_01")
 
    def test_func_02(self):
        print("test_func_02")
 
 
运行结果:
test_demo_file_01.py::TestDemo::test_func_01 SKIPPED (不满足执行条件,跳过该用例)
test_demo_file_01.py::TestDemo::test_func_02 test_func_02 PASSED

(4)模块级跳过

语法:pytest.skip(reason=“”, allow_moudle_level=false) # 跳过整个模块,参数必填allow_module_level=True

import pytest
 
 
pytest.skip(reason="跳过整个模块", allow_module_level=True)
 
 
class TestDemo:
 
    def test_func_01(self):
        # a = random.randint(1, 2)
        # if a == 1:
        #     pytest.skip(reason="不满足执行条件,跳过该用例")
        print("test_func_01")
 
    def test_func_02(self):
        print("test_func_02")
 
 
运行结果:
Skipped: 跳过整个模块
collected 0 items / 1 skipped

(5)缺少某些导入时跳过用例

语法:@pytest.importorskip( modname: str, minversion: optional[str] = none, reason: optional[str] = none )
参数解释:

  • modname: 需要被导入的模块名称,比如 selenium;
  • minversion:表示需要导入的最小的版本号,如果该版本不达标,将会打印出报错信息;
  • reason:只有当模块没有被导入时,给定该参数将会显示出给定的消息内容
# 测试模块
import pytest
rock = pytest.importorskip("rock")
@rock
def test_1():
    print("测试是否导入了rock模块")
 
 
# 测试模块版本
import pytest
sel = pytest.importorskip("selenium", minversion="3.150")
@sel
def test_1():
    print("测试是否导入了selenium模块")

(6)skip赋值变量,多处调用

# 首先定义一个变量
myskip = pytest.mark.skip(reason="未知原因")
myskipif = pytest.mark.skipif(1==1, reason="未知原因")
 
 
 
# 然后在其它模块用例导入这个变量,使用时直接 @myskip   @myskipif
@myskip
def test_func_02(self):
    print("test_func_02")

3、用例标记或分组

在日常测试过程中,当有很多测试用例,但只想执行其中的一部分用例,可以使用@pytest.mark.自定义标签功能满足。
使用mark灵活给测试用例打标签或分组。在运行测试用例的时候,可以根据标签名来过滤运行的用例。

(1)标签规范建议
# 1.按环境
@pytest.mark.development
@pytest.mark.release
...
# 2.按作者
@pytest.mark.zhangsan
@pytest.mark.lisi
...
# 3.按版本
@pytest.mark.v1
@pytest.mark.v2
...
# 4.按用途(回归、冒烟、全量等)
@pytest.mark.smoke
@pytest.mark.full
...
(2)标签使用

测试用例和测试类都支持单标签和多标签。给测试类打标签时,生效的对象是这个测试类下所有的用例。

# 对测试类打标签时可以使用以下两种方式
# 方式一:
@pytest.mark.zhangsan
@pytest.mark.smoke
class TestDemo:
 
    def test_func_01(self):
        print(" excute test_func_01")
 
    def test_func_02(self):
        print("test_func_02")
 
 
# 方式二:
class TestDemo:
    # 单标签
    # pytestmark = pytest.mark.full
     
    # 多标签
    pytestmark = [pytest.mark.zhangsan, pytest.mark.smoke]
    def test_func_01(self):
        print(" excute test_func_01")
 
    def test_func_02(self):
        print("test_func_02")
(3)执行/不执行指定标签的用例
  • 执行指定标签的用例
    pytest test_demo_file_01.py -m smoke
  • 不执行指定标签的用例
    pytest test_demo_file_01.py -m “not smoke”
  • 多标签执行
    pytest test_demo_file_01.py -m “zhangsan or smoke”
(4)标签管理

自定义标签在执行的时候会提示告警信息,如下:
PytestUnknownMarkWarning: Unknown pytest.mark.smoke - is this a typo? You can register custom marks to avoid this warning - for details, see https://docs.pytest.org/en/stable/how-to/mark.html
解决方法一:
在项目的 pytest.ini 文件中添加标签集合,如下:

[pytest]
markers =
    smoke: explain for this
    success
    .....

解决方法二:
在 conftest.py 文件中注册,多个标签添加多条记录,如下:注册 regression、smoke、zhangsan 三个自定义标签

# 固定插件用法
def pytest_configure(config):
    config.addinivalue_line("markers", "regression: only regression test")
    config.addinivalue_line("markers", "smoke: only smoke test")
    config.addinivalue_line("markers", "zhangsan: only author test")

4、用例执行顺序和依赖

(1)用例执行顺序

pytest默认执行用例顺序是根据项目下文件名称按ascii码去收集运行的,文件里的用例是从上往下按顺序执行的(模块级会先以模块名按ascii编码进行排序)。
当需要调整测试用例执行顺序时,可以引入插件 pytest-ordering 来控制用例执行顺序。
安装:pip install pytest-ordering
语法:@pytest.mark.run(order=n) # 按照n值顺序执行,order为非负整数(值越小优先级越高) > 无排序装饰器 > order为负整数(负的值越大优先级越高)

@pytest.mark.run(order=3)
def test_01():
    print("test_01")
    time.sleep(1.0)
 
 
@pytest.mark.run(order=2)
def test_two():
    print("test_two")
    time.sleep(10)
 
 
@pytest.mark.run(order=1)
def test_regin():
    print("用例test_regin")
    time.sleep(1.5)
 
 
def test_login():
    print("用例login")
    time.sleep(0.1)
 
 
def test_05():
    print("用例5")
    time.sleep(2.3)
 
 
运行结果:
test_demo_file_02.py::test_regin 用例test_regin
PASSED
test_demo_file_02.py::test_two test_two
PASSED
test_demo_file_02.py::test_01 test_01
PASSED
test_demo_file_02.py::test_login 用例login
PASSED
test_demo_file_02.py::test_05 用例5
PASSED
(2)用例依赖

安装:pip install pytest-dependency
语法:@pytest.mark.dependency(name=None, depends=[], scope=‘module’)
参数解释:
name ( str) – 用于依赖测试引用的测试名称。如果未设置,则默认为 pytest 定义的节点 ID。名称必须是唯一的。
depends (iterable of str) – 依赖项,该测试所依赖的测试名称列表。除非所有依赖项都已成功运行,否则将跳过测试。依赖项也必须已被标记修饰。依赖项的名称必须适应范围。
scope ( str) – 搜索依赖项的范围。必须是’session’、‘package’、‘module’或’class’。默认是module
创建2个文件 test_depend_01.py、test_depend_02.py,如下:

import pytest
 
@pytest.mark.dependency()
def test_a():
    pass
 
 
@pytest.mark.dependency()
@pytest.mark.xfail(reason="deliberate fail")
def test_b():
    assert False
 
 
@pytest.mark.dependency(depends=["test_a"])
def test_c():
    pass
 
 
@pytest.mark.dependency(depends=['test_b'])
def test_d():
    pass
 
 
class TestClass(object):
 
 
    @pytest.mark.dependency()
    def test_b(self):
        pass
 
 
运行结果:
test_depend_01.py::test_a PASSED
test_depend_01.py::test_b XFAIL (deliberate fail)
test_depend_01.py::test_c PASSED
test_depend_01.py::test_d SKIPPED (test_d depends on test_b)   # test_d依赖test_b,test_b执行失败,所以test_d跳过执行
test_depend_01.py::TestClass::test_b PASSED

5、参数化数据驱动

参数化,就是把测试过程中的数据提取出来,通过参数传递不同的数据来驱动用例运行。pytest框架使用装饰器 @pytest.mark.parametrize 来对测试用例进行传参。
语法:@pytest.mark.parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)
参数解释:
argnames:参数名称,字符串格式,多个参数用逗号隔开,如:“arg1,arg2,arg3”
argvalues:参数值,需要与argnames对应,元组或列表,如:[ val1,val2,val3 ],如果有多个参数例,元组列表一个元组对应一组参数的值,如:@pytest.mark.parametrize(“name,pwd”, [(“yy1”, “123”), (“yy2”, “123”), (“yy3”, “123”)])
indirect:默认为False,代表传入的是参数。如果设置成True,则把传进来的参数当函数执行,而不是一个参数
ids:自定义测试id,字符串列表,ids的长度需要与测试数据列表的长度一致,标识每一个测试用例,自定义测试数据结果的显示,为了增加可读性

import pytest
 
 
# fixture函数
@pytest.fixture()
def fix_demo(request):
    temp = request.param
    print("我是{0},我来签到".format(temp))
    return temp
 
 
# 被测函数
def add(a, b):
    return a + b
 
 
# 单个参数参数化
@pytest.mark.parametrize("a", [1, 2, 3, 4, 5])
def test_add_01(a):     # 参数名称和个数需和parametrize传入的一致
    print("a的值:", a)
    assert add(a, 1) == a + 1
 
 
# 多个参数
@pytest.mark.parametrize("a, b, c", [(1, 2, 3), (4, 5, 9), ('1', '2', '12')])
def test_add_02(a, b, c):   # 参数名称和个数需和parametrize传入的一致
    print(f"a, b, c的值是:{a}, {b}, {c}")
    assert add(a, b) == c
 
 
# 参数组合,场景总数为各参数个数相乘后结果。适用于期望结果是固定的
@pytest.mark.parametrize('x', [0, 1])
@pytest.mark.parametrize('y', [2, 3])
def test_combination(x, y):
    print(f"测试组合:x={x}, y={y}")
 
 
# indirect=True, parametrize与request结合使用给fixture传参
@pytest.mark.parametrize("fix_demo", ["张三", "李四", "王五"], indirect=True)
def test_user(fix_demo):
    print("{0}已签到".format(fix_demo))
 
 
# 和 pytest.param 联合使用,处理部分用例
@pytest.mark.parametrize("a, b, c",
                         [
                             (1, 2, 3),
                             pytest.param(2, 3, 6, marks=pytest.mark.xfail),
                             pytest.param('a', 'b', 'ab', marks=pytest.mark.skip),
                             pytest.param(9, 1, 10, id="9+1=10: pass")
                         ])
def test_param(a, b, c):
    print(f"a, b, c的值是:{a}, {b}, {c}")
    assert add(a, b) == c

四、allure-pytest的一些介绍

pytest框架使用allure生成测试报告,报告内容丰富美观,功能强大,使用的插件 allure-pytest
安装:pip install allure-pytest
功能特性:

在这里插入图片描述
allure使用实例:

import allure
from common.logger import logger
import requests
 
 
@allure.step('这是测试步骤')
def step_1():
    print("初始化数据")
 
@allure.epic('测试天气API接口'.center(30, '*'))
@allure.feature('测试模块')
@allure.suite('这是套件')
class TestHttpbin:
    """测试模块httpbin"""
 
    @allure.severity('normal')
    @allure.story('故事1:获取天气数据')
    @allure.title('获取单个城市的天气')
    @allure.description('获取深圳的天气')
    @allure.testcase('测试用例地址:www.***.com')
    @allure.issue('缺陷管理地址:https://www.zentao.net/')
    @allure.tag('这是tag')
    def test_001(self, login):
        """
        测试httpbin接口:get方法
        """
        step_1()
        # api:host
        url = 'https://tianqiapi.com/api'
        params = {'version': 'v6', 'appid': 12253812, 'appsecret': 'KzT8yOpX'}
 
        response = requests.get(url=url, params=params).json()
        print('接口返回数据: %s' % response)
        logger.info('接口返回数据: %s' % response)

在这里插入图片描述

五、项目流程简单介绍

在这里插入图片描述
https://gitlab.dev.21vianet.com/fan.jun3/api-request.git

基本数据流程:读取配置信息–>读取yml测试数据–>生成测试用例–>执行测试用例–>断言–>生成allure报告(–>发送邮件,钉钉推送?)

更多pytest用法参考官方文档文档:https://docs.pytest.org/en/stable/index.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1612487.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第 7 章 导航实现(自学二刷笔记)

重要参考: 课程链接:https://www.bilibili.com/video/BV1Ci4y1L7ZZ 讲义链接:Introduction Autolabor-ROS机器人入门课程《ROS理论与实践》零基础教程 准备工作 请先安装相关的ROS功能包: 安装 gmapping 包(用于构建地图): sudo apt inst…

详细UI色彩搭配方案分享

UI 配色是设计一个成功的用户界面的关键之一。UI 配色需要考虑品牌标志、用户感受、应用程序的使用场景,这样可以帮助你创建一个有吸引力、易于使用的应用程序。本文将分享 UI 配色的相关知识,帮助设计师快速构建 UI 配色方案,以满足企业的需…

webgl canvas系列——animation中基本旋转、平移、缩放(模拟冒泡排序过程)

文章目录 ⭐前言⭐canvas绘制图片💖状态保存和恢复💖移动、旋转、缩放、变形💖移动绘制一个渐变的box💖旋转💖缩放 ⭐模拟冒泡排序过程⭐结束 ⭐前言 大家好,我是yma16,本文分享webgl canvas系…

EMD分解

ref:【EMD经验模态分解-哔哩哔哩】 https://b23.tv/LfepZjU 流程: IMF 固有模态函数 imf1 迭代直到是一个imf 8次迭代后,满足是一个imf residual的得到:原始信号-均值(上下包络线的均值) imf2 为什么时序…

【公司UI自动化学习】

公司课程链接:https://l.jd.com/student/project/project.du?project_id697509403 公司的课程,是给一个学习方向。 一、 PC自动化 1)什么项目适合 2)PC自动化介入时间点 3)自动化率: 频繁改动的&…

【Harmony3.1/4.0】笔记二

概述 列表是一种复杂的容器,当列表项达到一定数量,内容超过屏幕大小时,可以自动提供滚动功能。它适合用于呈现同类数据类型或数据类型集,例如图片和文本。在列表中显示数据集合是许多应用程序中的常见要求(如通讯录、…

深度学习500问——Chapter08:目标检测(2)

文章目录 8.2.4 R-FCN 8.2.5 FPN 8.2.6 Mask R-CNN 8.2.4 R-FCN R-FCN 有哪些创新点 R-FCN仍然属于two-stage目标检测算法:RPN R-FCN Fully convolutional位置敏感得分图(position-sentive score maps) our region-based detector is ful…

java-Spring-入门学习-第二天(单例模式和多例模式)

目录 Bean作用域 单例模式(默认可以不写) Spring下的 AutoWired 依赖注入 JaveEE下的 Resource 依赖注入 多例模式 Bean作用域 ​在Spring框架中,Bean是按照作用域来创建的,常见的作用域有两种:Singleton 和 Prototype。Singleton (单例…

6.SpringBoot 日志文件

文章目录 1.日志概述2.日志作用3.使用和观察日志3.1如何观察日志3.2使用日志3.3日志级别3.4日志持久化3.5日志分割 4.日志框架4.1门面模式(外观模式)4.2 SLF4J框架介绍4.3 日志格式的说明4.3.1日志名称 5.日志颜色设置6.总结 大家好,我是晓星航。今天为大家带来的是…

【Java】HashMap、HashTable和ConcurrentHashMap的区别

文章目录 区别一、HashMap1.1基本定义与特性1.2工作原理与实现1.3常用方法1.4性能与优化 二、HashTable三、ConcurrentHashMap3.1基本特点3.2实现原理3.3常用方法3.4适用场景3.5性能优化 HashTable、HashMap和ConcurrentHashMap之间的区别主要体现在线程安全、继承关系与实现接…

(2024|ICLR,变分扩散模型(VDM),可学习编码器,时间相关的均值函数)DiffEnc:使用学到的编码器进行变分扩散

DiffEnc: Variational Diffusion with a Learned Encoder 公和众和号:EDPJ(进 Q 交流群:922230617 或加 VX:CV_EDPJ 进 V 交流群) 目录 0. 摘要 2. 变分扩散模型的基础 3. DiffEnc 4. 编码器和生成模型的参数化 …

Linux--地址空间

目录 看一个现象 基本概念 细节问题--理解它 1.如何理解地址空间? 2.为什么要有地址空间? 3. 进一步了解页表和写时拷贝 4.如何理解虚拟地址? 看一个现象 先通过一段代码,看一看现象 int g_val 100;int main() {printf(&quo…

Linux 认识与学习Bash——2

1 read 从键盘读取变量的值 read 后面不带变量,那么默认会给REPLY变量赋值 #!/bin/bash echo -n "请输入你的名字:" read name echo "欢迎您 $name" echo "----------------"echo -n "请输入你的名字2:&q…

我与深拷贝

前言 最近在掘金读到了一篇文章《Radash 能取代 Lodash???真幽默 - 掘金》,文章的评论区讨论起了深拷贝。"深拷贝" 我的"老朋友",还记得在学习我人生中的第二道面试题的时候认识了它,…

CSS 画一个三角形

一、前言 在前端开发的时候,我们有时候会需要用到一个三角形的形状,比如地址选择或者播放器里面播放按钮 通常情况下,我们会使用图片或者svg去完成三角形效果图,但如果单纯使用css如何完成一个三角形呢? 实现过程似…

物理学视角讲解diffusion生成模型——隐扩散模型

https://zhuanlan.zhihu.com/p/692996885 https://zhuanlan.zhihu.com/p/693255617 前面两篇文章介绍了扩散过程,同时实现了1维、2维混合高斯扩散、逆扩散,通过模型预测得分函数来实现逆扩散推理。这个章节介绍工业界使用的文本生成图扩撒模型&#xff1…

基于SSM+Jsp+Mysql的多人命题系统

开发语言:Java框架:ssm技术:JSPJDK版本:JDK1.8服务器:tomcat7数据库:mysql 5.7(一定要5.7版本)数据库工具:Navicat11开发软件:eclipse/myeclipse/ideaMaven包…

frp改造Windows笔记本实现家庭版免费内网穿透

文章目录 前言frp原理Windows服务端IP检验IP固定软件下载端口放行端口映射开机启动 NAS客户端端口查询软件下载端口检验穿透测试自启设置 Ubuntu客户端软件下载后台启动 后记 前言 之前一直用花生壳远程控制一个服务器,但最近内网的网络策略似乎发生了变化&#xf…

InfiniGate自研网关实现思路二

5.HTTP请求参数解析 解析 HTTP 网络请求的参数信息,包括;GET/POST,以及应对不同 Content-Type 类型的处理。 HTTP 接口请求的参数需要解析成可以匹配到 RPC 接口的入参信息,所以通常为了方便控制一般只支持 RPC 接口单个对象入参…

「sentinel」流量控制组件的应用

「sentinel」流量控制组件的应用 Sentinel版本QPS 一、初识Sentinel1、Sentinel2、Sentinel 和 Hystrix对比3、雪崩问题 二、环境搭建1、下载安装Sentinel2、微服务整合Sentinel 三、流量控制1、簇点链路2、流控设置3、流控模式直接关联链路 4、流控效果流控效果解释 四、热点限…