pytest +uiautomator2+weditor app自动化从零开始

news2024/11/17 7:20:46

目录结构1.0
在这里插入图片描述
把设备连接单独移出去了
在这里插入图片描述
模块操作代码,有一些流程操作和断言方法

from devices import dv
from time import sleep
import random
from tool.jt import capture_screenshot


def initialization(func):
    def wrapper():
        sleep(1)
        dv.app_stop('com.visteon.txzing.accountcenter')
        dv.app_start('com.visteon.txzing.accountcenter')
        sleep(2)
        func()
    return wrapper


@initialization
def f1():
    '''1、打开账号切换,点击其他的账号,点击确认登录,点击取消'''
    dv(text='账号切换').click()
    dv.xpath(
        '//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/change_account_recycler"]/android.view.ViewGroup[2]').click()
    dv(text='确定').click()
    dv(text='取消').click()


@initialization
def f2():
    '''2、点击设置、点击退出登录、点击取消'''
    dv(text='设置').click()
    dv(text='退出登录').click()
    dv(text='取消').click()


@initialization
def f3():
    '''3、点击设置、点击用户协议,点击返回,点击隐私政策,点击返回,再次点击返回到个人中心主页面'''
    dv(text='设置').click()
    dv(text='用户协议').click()
    sleep(1.5)
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/top_bar_back"]').click()
    dv(text='隐私政策').click()
    sleep(1.5)
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/top_bar_back"]').click()
    sleep(1.5)
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/top_bar_back"]').click()


@initialization
def f4():
    '''4、点击账号关联,点击高德地图绑定,点击确定'''
    dv(text='账号关联').click()
    try:
        dv.xpath('//*[@content-desc="绑定高德地图"]').click()
    except:
        dv.xpath('//*[@content-desc="绑定高德地图"]').click()
    dv(text='确定').click()


def f5():
    '''5、进入问题反馈,点击开始录音,5s内结束录音,重新开始录音,切换问题类别从第一个切到最后一个,然后提交,最后播放语音'''
    dv(text='问题反馈').click()
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()
    sleep(4)
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()
    sleep(1)
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()
    for i in ['多媒体', '导航', '蓝牙电话', '维保类', '设置', '其他']:
        dv(text=i).click()
        sleep(1)
    # 录音秒数随机
    sleep(random.randint(1, 80))
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()
    dv(text='提交').click()
    sleep(2)
    dv.xpath(
        '//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/mine_feedback_recyclerview"]/android.view.ViewGroup[1]/android.view.ViewGroup[1]').click()


def run():
    while True:
        try:
            f1()
            f2()
            f3()
            f5()
            f4()
        except Exception as e:
            capture_screenshot(e)
            print(f'报错了重新运行{e}')


# 通过获取文本来断言
b = '//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/mine_feedback_recyclerview"]/android.view.ViewGroup[1]/android.widget.TextView[1]'
a = dv.xpath(b).get_text()
print(a)

# 通过判断元素是否存在来断言
c = dv.xpath('//*[@text="2023/11/30 15:49"]').exists
print(c)

# 通过元素属性是否发生变化来进行断言
d = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_record_bar_time"]')
# 获取语音条初始状态的info信息
initial_info = d.info
d.click()
clicked_info = d.info
# 比较前后的info信息,找出差异数据
diff = {k: clicked_info[k] for k in clicked_info if clicked_info[k] != initial_info[k]}
print("前后的差异数据:", diff)
if len(diff) == 0:
    print('状态未发生变化')
else:
    print('断言成功')


if __name__ == '__main__':
    while True:
        run()

目录结构1.1
新增test_accountcenter.py编写测试用例
新增run.py执行pytest
新增pytest.ini配置文件
在这里插入图片描述
test_accountcenter.py
删除了3个场景,留下2个场景,每个场景加了2种断言方式f1(ex):f5(ex):,测试用例是test_zhanghao():test_luyin():,f1(ex):f5(ex):内部实现了断言并且返回结果

from devices import dv
from time import sleep
import random
from tool.jt import capture_screenshot
def f1(ex):
    '''1、打开账号切换,点击其他的账号,点击确认登录,点击取消'''
    dv.app_stop('com.visteon.txzing.accountcenter')
    dv.app_start('com.visteon.txzing.accountcenter')
    dv(text='账号切换').click()
    dv.xpath(
        '//*[@resource-id="com.visteon.txzing.accountcenter:id/change_account_recycler"]/android.view.ViewGroup[2]').click()
    dv(text='确定').click()
    text= dv(text='请在互联小程序确认登录').get_text()
    if not dv.xpath('//*[@resource-id="com.visteon.txzing.accountcenter:id/loading_cancel"]').exists:
        return False
    ass =ex==text
    return ass



def f5(ex):
    '''5、进入问题反馈,点击开始录音,5s内结束录音,重新开始录音,切换问题类别从第一个切到最后一个,然后提交,最后播放语音'''
    dv.app_stop('com.visteon.txzing.accountcenter')
    dv.app_start('com.xxxxxxx.xxxxxxx.accountcenter')
    dv(text='问题反馈').click()
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()
    sleep(4)
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()
    sleep(1)
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()
    lb=['多媒体', '导航', '蓝牙电话', '维保类', '其他', '设置']
    for i in lb:
        dv(text=i).click()
        sleep(1)
    # 录音秒数随机
    sleep(random.randint(5, 10))
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()
    dv(text='提交').click()
    ass= '设置'==ex
    '''元素信息变化'''
    d = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_record_bar_time"]')
    # 获取语音条初始状态的info信息
    initial_info = d.info
    d.click()
    clicked_info = d.info
    # 比较前后的info信息,找出差异数据
    diff = {k: clicked_info[k] for k in clicked_info if clicked_info[k] != initial_info[k]}
    print("前后的差异数据:", diff)
    if len(diff) == 0:
        return False

    sleep(2)
    dv.xpath(
        '//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/mine_feedback_recyclerview"]/android.view.ViewGroup[1]/android.view.ViewGroup[1]').click()
    return ass

def test_zhanghao():
    f1('请在互联小程序确认登录')
    assert True

def test_luyin():
    assert f5('设置')


run.py文件
运行文件,暂未配置参数
```python
import pytest
pytest.main([])

pytest.ini文件
配置了下报告的一些参数

[pytest]
addopts = -s --alluredir ./report/data

目录结构1.2
新增断言方法文件
在这里插入图片描述
assertion.py文件
首先dw()判断元素是否存在,不存在不需要进行后续操作,element_existence方法适用于断言元素是否存在,element_info_existence方式适用于判断元素在点击后是否发生了属性变化来断言,element_text_existence适用于判断元素文本和预期结果是否一致

from time import sleep
def dw(dv, element, positioning_method):
    '''
    :param dv: 设备
    :param element: 定位元素
    :param positioning_method: 定位方式
    :return: 判定元素是否存在,存在则返回元素对象用于后续操作
    '''
    if positioning_method == 'xpath':
        if not dv.xpath(element).exists:
            print('断言元素不存在,直接判定断言失败')
            return False
        return dv.xpath(element)
    if positioning_method == 'text':
        if not dv(text=element).exists:
            print('断言元素不存在,直接判定断言失败')
            return False
        return dv(text=element)


def element_existence(dv, element, positioning_method):
    '''
      :param dv: 设备
      :param element: 定位元素
      :param positioning_method: 定位方式
      :return:通过元素是否存在来断言
      '''
    element_ = dw(dv, element, positioning_method)
    if not element_:
        return False
    return True


def element_info_existence(dv, element, positioning_method):
    '''
      :param dv: 设备
      :param element: 定位元素
      :param positioning_method: 定位方式
      :return:通过元素属性是否发生变化来断言
      '''
    if not dw(dv, element, positioning_method):
        return False
    else:
        el = dw(dv, element, positioning_method)
        initial_info = el.info
        el.click()
        sleep(1)
        clicked_info = el.info
        diff = {k: clicked_info[k] for k in clicked_info if clicked_info[k] != initial_info[k]}
        print(f'元素差异字段{diff}')
        if len(diff) == 0:
            print('元素属性未发生变化,断言失败')
            return False
        return True


def element_text_existence(dv, element, positioning_method, text):
    '''

    :param dv: 设备
    :param element: 定位元素
    :param positioning_method: 定位方式
    :param text: 预期结果文本
    :return: 通过文本是否相等来断言
    '''
    if not dw(dv, element, positioning_method):
        return False
    else:
        el = dw(dv, element, positioning_method)
        el_text=el.get_text()
        if not text ==el_text :
            print(f'文本不匹配预期结果{text},实际结果{el_text}')
            return False
        else:
            return True


目录结构1.3
新增case文件夹
case-fun 以每个模块一个文件,里面包含多个场景操作,和场景断言
case-test_case 以每个模块一个文件,和fun文件夹文件一一对应,负责执行模块的每个场景
在这里插入图片描述
accountcenter.py文件

import random
from time import sleep
from tool.assertion import element_existence, element_info_existence, element_text_existence


def f1(dv):
    '''1、打开账号切换,点击其他的账号,点击确认登录'''
    dv.app_stop('com.visteon.txzing.accountcenter')
    dv.app_start('com.visteon.txzing.accountcenter')
    dv(text='账号切换').click()
    dv.xpath(
        '//*[@resource-id="com.visteon.txzing.accountcenter:id/change_account_recycler"]/android.view.ViewGroup[2]').click()
    dv(text='确定').click()

    '''断言'''
    return element_existence(dv, '取消', 'text')


def f2(dv):
    dv.app_stop('com.xxxxxxx.xxxxxxx.accountcenter')
    dv.app_start('com.xxxxxxx.xxxxxxx.accountcenter')
    '''2、点击设置、点击退出登录、点击取消'''
    dv(text='设置').click()
    dv(text='退出登录').click()
    dv(text='取消').click()

    return element_text_existence(dv, '退出登录', 'text', '退出登录')


def f5(dv):
    '''5、进入问题反馈,点击开始录音,5s内结束录音,重新开始录音,切换问题类别从第一个切到最后一个,然后提交,最后播放语音'''
    dv.app_stop('com.xxxxxxx.xxxxxxx.accountcenter')
    dv.app_start('com.xxxxxxx.xxxxxxx.accountcenter')
    dv(text='问题反馈').click()
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()
    sleep(2)
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()
    sleep(1)
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()
    lb = ['多媒体', '导航', '蓝牙电话', '维保类', '其他', '设置']
    for i in lb:
        dv(text=i).click()
        sleep(1)
    # 录音秒数随机
    sleep(random.randint(5, 10))
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_start_record"]').click()
    dv(text='提交').click()
    sleep(2)
    dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_record_bar_time"]').click()  # 点击语音条
    '''断言'''
    return element_info_existence(dv,
                                  '//*[@resource-id="com.xxxxxxx.xxxxxxx.accountcenter:id/feedback_record_bar_time"]',
                                  'xpath')

test_accountcenter.py文件

from case.fun.accountcenter import f1, f2, f5
from devices import dv
def test_f1():
    assert f1(dv)
def test_f2():
    assert f2(dv)
def test_f5():
    assert f5(dv)

familytime.py

import random
from time import sleep
from devices import dv
from tool.assertion import element_existence, element_info_existence, element_text_existence

'''这些是通过观察元素属性观察得出的结论,这些是通用值'''


def tu(number):
    '''家人时光每个图片定位'''
    tu = dv.xpath(
        f'//*[@resource-id="com.visteon.txzing.familytime:id/recycler_view"]/android.view.ViewGroup[{number}]/android.widget.ImageView[1]')
    return tu


# 设为按钮
set_as = dv(text='设为')
# 设置壁纸
set_wallpaper = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_wallpaper"]')
# 设置屏保
set_screensaver = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_screensaver"]')
# 设为按钮
confirm = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/btn_normal_allow"]')
# 取消按钮
cancel = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/btn_normal_cancel"]')


def set_s_w():
    dv.app_stop('com.xxxxxxx.xxxxxxx.familytime')
    dv.app_start('com.xxxxxxx.xxxxxxx.familytime')

    tu(1).click()
    set_as.click()
    set_wallpaper.click()
    set_screensaver.click()
    confirm.click()
    # 多个断言处理
    ass_1 = element_text_existence(dv, '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/tv_message"]', 'xpath',
                                   '壁纸、屏保设置成功')
    ass_2 = element_text_existence(dv, '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/tv_label"]', 'xpath',
                                   '壁纸 屏保')
    ass_list = [ass_1, ass_2]
    for i in ass_list:
        if not i:
            print(f'断言{i}失败')
            return False
    return True


def cancel_s_w():
    dv.app_stop('com.xxxxxxx.xxxxxxx.familytime')
    dv.app_start('com.xxxxxxx.xxxxxxx.familytime')
    tu(1).click()
    set_as.click()
    set_wallpaper.click()
    set_screensaver.click()
    confirm.click()
    return element_text_existence(dv, '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/tv_message"]', 'xpath',
                                  '壁纸、屏保取消成功')

test_familytime.py

from case.fun.familytime import set_s_w, cancel_s_w
from devices import dv
from time import sleep
def test_set_s_w():
    set_s_w()
def test_cancel_s_w():
    cancel_s_w()

目录结构1.4
新增dw.py文件,增加元素定位封装,定位失败截图
新增conftest.py,配合pytest.fixture实现前后置
在这里插入图片描述
dw.py

from time import sleep
from lxml import etree
from tool.screenshot import capture_screenshot
class DwFail(Exception):
    pass
def jt(case_name, positioning_instructions):
    print('定位元素不存在,进行截图')
    info = f'用例标题{case_name},定位元素说明:{positioning_instructions}'
    capture_screenshot(info)
def find_elements(dv, element, positioning_method, case_name, positioning_instructions):
    '''
    :param dv: 设备对象
    :param element:元素定位数据
    :param positioning_method:元素定位方式
    :param case_name:测试用例名称
    :param positioning_instructions: 这个元素测试的对象说明
    :return:
    '''
    sleep(1.5)
    if positioning_method == 'xpath':
        try:
            if dv.xpath(element).exists:
                print('定位成功')
                return dv.xpath(element)
            else:
                jt(case_name, positioning_instructions)
                raise DwFail(f'定位失败,用例标题{case_name},定位元素说明:{positioning_instructions}')
        except etree.XPathEvalError:
            jt(case_name, positioning_instructions)
            raise DwFail(f'xpath路径错误定位,用例标题{case_name},定位元素说明:{positioning_instructions}')

    elif positioning_method == 'text':
        if dv(text=element).exists:
            return dv(text=element)
        else:
            jt(case_name, positioning_instructions)
            raise DwFail(f'定位失败,用例标题{case_name},定位元素说明:{positioning_instructions}')
    else:
        print('暂时只支持xpath,text定位')

if __name__ == '__main__':
    from devices import dv
    # find_elements(dv, '.ViewGroup[2]', 'xpath', 'xpath', '点击设12222211111111置')
    find_elements(dv, '//*[@resource-id="com.visteon.txzing.accountcenter:id/feedback_record_bar_time', 'xpath',
                  '进行录音问题反馈', '点击语音条').click()
    # find_elements(dv, '//*[@resource-id="com.visteon.txzing.accountcenter:id/mine_feedback_recyclerview"]/android.view.ViewGroup[1]/android.view.ViewGroup[1]', 'xpath',
    #               '进行录音问题反馈', '点击语音条').click()

dw.py文件find_elements方法应用

import random
from time import sleep
from devices import dv
from tool.assertion import element_existence, element_info_existence, element_text_existence
from tool.dw import find_elements

'''这些是通过观察元素属性观察得出的结论,这些是通用值'''
def tu(number):
    '''家人时光每个图片定位'''
    tu = dv.xpath(
        f'//*[@resource-id="com.visteon.txzing.familytime:id/recycler_view"]/android.view.ViewGroup[{number}]/android.widget.ImageView[1]')
    return tu

# 设为按钮
set_as = dv(text='设为')
# 设置壁纸
set_wallpaper = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_wallpaper"]')
# 设置屏保
set_screensaver = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_screensaver"]')
# 设为按钮
confirm = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/btn_normal_allow"]')
# 取消按钮
cancel = dv.xpath('//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/btn_normal_cancel"]')
def set_s_w():
    dv.app_stop('com.xxxxxxx.xxxxxxx.familytime')
    dv.app_start('com.xxxxxxx.xxxxxxx.familytime')
    find_elements(dv,
                  '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/recycler_view"]/android.view.ViewGroup[1]/android.widget.ImageView[1]',
                  'xpath', '照片设置为屏保壁纸', '点击照片进入详情').click()

    find_elements(dv, '设为','text', '照片设置为屏保壁纸', '点击设为按钮').click()
    find_elements(dv,
                  '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_wallpaper"]',
                  'xpath', '照片设置为屏保壁纸', '勾选壁纸').click()
    find_elements(dv,
                  '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_screensaver"]',
                  'xpath', '照片设置为屏保壁纸', '勾选屏保').click()
    find_elements(dv,
                  '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/btn_normal_allow"]',
                  'xpath', '照片设置为屏保壁纸', '进行设置').click()
    # 多个断言处理
    ass_1 = element_text_existence(dv, '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/tv_message"]', 'xpath',
                                   '壁纸、屏保设置成功','照片设置为屏保壁纸断言1')
    ass_2 = element_text_existence(dv, '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/tv_label"]', 'xpath',
                                   '壁纸 屏保','照片设置为屏保壁纸断言2')
    ass_list = [ass_1, ass_2]
    for i in ass_list:
        if not i:
            print(f'断言{i}失败')
            return False
    return True

def cancel_s_w():
    dv.app_stop('com.xxxxxxx.xxxxxxx.familytime')
    dv.app_start('com.xxxxxxx.xxxxxxx.familytime')
    find_elements(dv,
                  '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/recycler_view"]/android.view.ViewGroup[1]/android.widget.ImageView[1]',
                  'xpath', '照片取消为屏保壁纸', '点击照片进入详情').click()

    find_elements(dv, '设为', 'text', '照片取消为屏保壁纸', '点击设为按钮').click()
    find_elements(dv,
                  '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_wallpaper"]',
                  'xpath', '照片取消为屏保壁纸', '取消勾选壁纸').click()
    find_elements(dv,
                  '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/check_screensaver"]',
                  'xpath', '照片取消为屏保壁纸', '取消勾选屏保').click()
    find_elements(dv,
                  '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/btn_normal_allow"]',
                  'xpath', '照片取消为屏保壁纸', '进行设置').click()
    return element_text_existence(dv, '//*[@resource-id="com.xxxxxxx.xxxxxxx.familytime:id/tv_message"]', 'xpath',
                                  '壁纸、屏保取消成功','照片取消为屏保壁纸')

conftest.py文件

import pytest
from uiautomator2 import UiObjectNotFoundError
from tool.screenshot import capture_screenshot
@pytest.fixture(scope='function',autouse=True)
#autouse=True这将使该 fixture 在每个测试用例中自动执行,而无需显式地添加装饰器或参数
def zx(request):
    print('开始')
    print(f'用例信息{request}')
    yield

    print('结束')


# def pytest_runtest_protocol(item, nextitem):
#     reports = yield
#     for report in reports:
#         if report.when == "call" and report.failed:
#             # 检查是否是 UiObjectNotFoundError 异常
#             if isinstance(report.longrepr, UiObjectNotFoundError):
#                 # 获取异常信息
#                 err_info = str(report.longrepr)
#
#                 # 调用截图方法
#                 capture_screenshot(err_info)

截图效果
在这里插入图片描述

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

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

相关文章

Linux学习笔记3 xshell(lnmp)

xshell能连接虚拟机的前提是真机能够ping通虚拟机网址 装OpenSSL依赖文件 [rootlocalhost nginx-1.12.2]# yum -y install openssl pcre-devel 依赖检测[rootlocalhost nginx-1.12.2]# ./configure [rootlocalhost nginx-1.12.2]# yum -y install zlib [rootlocalhost n…

Windows下使用CMD修改本地IP

在网络适配器界面查看当前网线连接的哪个网口,我当前连的是 以太网 这个名字的: 在windows下使用管理员权限打开CMD命令工具,输入如下命令(如我想本地ip改成192.168.2.4): netsh interface ip set address "以太网" st…

Vue:用IDEA开发Vue,标签语法爆红问题处理

一、场景描述 我在IDEA中,学习Vue课程。 入门学习时,是在html文件中,script引入vue.js文件方式。 此时,在html文件中用v-标签,爆红。 二、解决办法 打开 菜单栏 File - Settings 选择 Editor - Files Type&#xf…

虾皮关键词广告怎么选

在虾皮(Shopee)平台上,关键词广告是提高商品曝光度和销量的有效手段。然而,选择合适的关键词对于广告效果至关重要。本文将为您提供一些建议,帮助您选择适合虾皮关键词广告的关键词。 先给大家推荐一款shopee知虾数据…

云上巴蜀丨云轴科技ZStack成功实践精选(川渝)

巴蜀——古政权必争之地 不仅拥有优越的战略位置 而且拥有丰富的自然资源,悠久的历史文化 如今的川渝经济、人口发展迅速 2023年前三季度,四川与重庆GDP增速均超过国家平均线,为6.5%为5.6% 川渝经济发展带动数字化发展浪潮 云轴科技ZSt…

LeetCode题:174. 地下城游戏

目录 一、题目要求 二、解题思路 (1)状态表示 (2)状态转移方程 (3)初始化dp表 (4)填表顺序 (5)返回值 三、代码 一、题目要求 174. 地下城游戏 恶魔们…

【学一点儿前端】真机调试本地公众号网页项目

前言 微信公众号网页开发的真机调试一直是很头疼的事情。 原因一 微信公众号配置的JS安全域名只有三个,一个大中型的公众号这三个JS安全域名都是生产的域名,不可能预留域名用于开发和调试。 原因二 在微信里面只有访问正确的安全域名才能调用wx.config用…

电商早报 | 12月8日|母婴电商宝贝格子北京总部已人去楼空

国家邮政局:预计11月快递量同比增长30%,业务收入增长27% 12月7日消息,国家邮政局发布2023年11月中国快递发展指数报告。经测算,2023年11月中国快递发展指数为406.4,同比提升20%。其中发展规模指数、服务质量指数、发展…

初识Linux:权限(2)

目录 权限 用户(角色) 文件权限属性 文件的权限属性: 有无权限的区别: 身份匹配: 拥有者、所属组的修改: 八进制的转化: 文件的类型: x可执行权限为什么不能执行&#xf…

深入理解 Python 中的 eval 函数

更多资料获取 📚 个人网站:ipengtao.com eval 是 Python 中一个强大而灵活的函数,它允许将字符串作为代码执行。然而,由于其潜在的安全风险,使用时需要谨慎。本文将深入探讨 eval 函数的各个方面,包括基本…

系统设计-微服务架构

典型的微服务架构图 下图展示了一个典型的微服务架构。 负载均衡器:它将传入流量分配到多个后端服务。CDN(内容交付网络):CDN 是一组地理上分布的服务器,用于保存静态内容以实现更快的交付。客户端首先在 CDN 中查找内…

[⑦ADRV902x]: JESD204学习笔记

前言 JESD204B/C基于SERDES(SERialization/DESerialization)技术,也就是串化和解串,在发送端将多位并行的数据转换为1 bit的串行数据,在接收端将串行数据恢复成原始的并行数据。 在JESD204接口出现以前,数…

作业12.8

1. 使用手动连接,将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中,在自定义的槽函数中调用关闭函数。将登录按钮使用qt5版本的连接到自定义的槽函数中,在槽函数中判断ui界面上输入的账号是否为"admin",密码是…

PVE系列-LVM安装MacOS的各个版本及VNC加密隧道访问

PVE系列-LVM安装MacOS的各个版本 环境配置大概过程:详细步骤:1.建立安装环境和下载安装工具2. 重启后,执行osx-setup配置虚拟机3. 安装到硬盘,4.设定引导盘,以方便自动开机启动5.打开屏幕共享和系统VNC6.VNC加密的ssh隧…

Python 数据分析:日期型数据的玩转之道

更多资料获取 📚 个人网站:ipengtao.com 在数据分析的领域中,处理日期型数据是至关重要的一环。Python 提供了丰富的工具和库,使得对日期进行分析、处理、可视化变得更加轻松。本文将深入探讨 Python 中如何玩转日期型数据&#…

python之日志记录

1.导包 import logging2.设置日志基本信息 2.1设置日志级别 logger logging.getLogger("你的类名"|None) # 可以空参logger.setLevel(logging.DEBUG) # 也可以为loggin.INFO 2.2 设置日志输出格式 formatter logging.Formatter(%(asctime)s - %(name)s - %(level…

基于OpenCV的人脸识别系统案例

基于OpenCV的人脸识别系统案例 人脸识别简介代码实现案例应用情况 下面将介绍如何使用Python和OpenCV库构建一个简单但强大的人脸识别系统。人脸识别是计算机视觉领域的一个重要应用,具有广泛的实际用途,从安全门禁到娱乐应用。 人脸识别简介 人脸识别是…

vue中组件传值方法

父组件给子组件传值 一、 1.在子组件标签中写入父组件传递数据 向下传递prop 2.在子组件内声明props选项接收父组件传递的数据 props:[,,] 父组件&#xff1a; <Header :msgmsg ></Header> 子组件&#xff1a; props:[msg], 二、 provide i…

大三上实训内容

项目一&#xff1a;爬取天气预报数据 【内容】 在中国天气网(http://www.weather.com.cn)中输入城市的名称&#xff0c;例如输入信阳&#xff0c;进入http://www.weather.com.cn/weather1d/101180601.shtml#input 的网页显示信阳的天气预报&#xff0c;其中101180601是信阳的…

高级IO函数

1. 高级 I/O 函数 1.1 pipe #include <unistd.h> /* 成功返回0&#xff0c;失败返回-1设置error */ int pipe( int fd[2] );&#xff08;1&#xff09;fd[0] 只能从管道读&#xff0c;fd[1] 只能写&#xff0c;默认情况下这一对文件描述符都是阻塞的&#xff08;读空管…