Python —— UI自动化用例前置处理日志封装

1、UI自动化用例增加前置

1、fixture(夹具)的使用

前置顾名思义是在执行测试用例之前做的一些事情,在自动化测试时会碰到用例执行前需要做一些前置操作,以及用例执行后需要做一些后置操作,比如登录、退出等,通过pytest fixture可以很方便实现。那么根据上篇文章写的用例,写一个获取浏览器驱动的前置,如下:

@pytest.fixture()
def driver_fixture():
    driver = webdriver.Chrome()
    driver.maximize_window()
    yield driver
    time.sleep(5)
    driver.quit()

将这个前置放在项目目录下的conftest.py文件中,可以实现数据共享,不需要import 导入 conftest.py,pytest用例就会自动查找。对 于一些公共的fixture我们可以将其存放到conftest.py进行管理。

针对上一篇文章,点击登录的操作也是很多用例都要遇到的,那么对这个操作也写一个夹具,如下:

import pytest
from selenium import webdriver
from d9_fixture前置后置处理及日志封装.pageobjects.home_page import HomePage
from d9_fixture前置后置处理及日志封装.pageobjects.login_page import LoginPage


# 自定义的fixture函数 -- 可以共享使用了,会在每个测试函数运行时都会执行?scope='function'
# session代表的是会话,整个测试用例运行就是一次会话
@pytest.fixture()
def get_driver():
    print("这是前置")
    driver = webdriver.Chrome()
    driver.get("http://mall.banabann.com:3344/")
    driver.maximize_window()
    yield driver
    print("这是后置")
    driver.quit()


'''
此时,函数的返回值就是driver,因此前置返回就是driver,可以使用夹具替换掉其他文件中的实例化驱动语句
'''

# 登录也是前置,因此,登录也可以作为夹具
@pytest.fixture()
def login(get_driver):
    # 点击首页的登录操作
    print("这是login的前置")
    homepage = HomePage(get_driver)
    homepage.click_login_link()
    # 在登陆页面进行登录操作
    loginpage = LoginPage(get_driver)
    loginpage.login("auto", "123456")
    yield get_driver
    print("这是login的后置")

 注意点:login夹具中,调用了get_driver夹具,那么输出语句执行顺序是:

        1、get_driver的前置

        2、login的前置

        3、login的后置

        4、get_driver的后置

可以参考下图:

2、fixture的作用域

fixture默认的作用域是function(函数)级别的,每次执行测试函数时都会运行fixture前置/后置,如果 想要fixture在全部测试用例执行期间只运行一次,可以设置为session(会话)级别。举例如下:

@pytest.fixture(scope='session')
def driver_fixture():
driver = webdriver.Chrome()
driver.maximize_window()
yield driver
time.sleep(5)
driver.quit()

2、关于UI自动化用例执行期间,浏览器关闭打开的最优选择

 浏览器在执行期间的打开关闭有2种类型:

        1、执行所有用例,浏览器只打开/关闭一次(可以通过给夹具设定作用域为session实现)

        2、每次执行一条用例,都会有浏览器打开/关闭的操作

那么我们该选择哪一种呢?选择第2种,原因如下:

        1、UI自动化不稳定

        2、前面一个用例失败,导致后面用例接连失败

        3、最好每条用例都可以单独执行-打开/关闭浏览器-可以避免很多问题

2、loguru日志封装

1、日志的级别

        DEBUG 调试

        INFO 一般的提示信息

        WARN 警告

        ERROR 程序已经发生了错误

        CRITICAL ERROR 严重的错误

2、添加日志的写法

from loguru import logger

logger.add(sink="my.log",
            encoding="utf8",
            level="INFO",
            rotation="1kB",
            retention=20)

3、实战

主要改动点:

1、在base_page.py中增加异常捕获代码

2、在base_page.py中二次封装点击、获取文本、输入文本的函数

3、给全部用例执行的轨迹增加日志信息

4、增加了login夹具

目录:

 run.py的文件内容:

import pytest
# -s,-v选项可以让pytest执行的日志更加的丰富
pytest.main(['-s','-v'])

conftest.py的内容:

import pytest
from selenium import webdriver

from d9_fixture前置后置处理及日志封装.pageobjects.home_page import HomePage
from d9_fixture前置后置处理及日志封装.pageobjects.login_page import LoginPage


# 自定义的fixture函数 -- 可以共享使用了,会在每个测试函数运行时都会执行?scope='function'
# session代表的是会话,整个测试用例运行就是一次会话
@pytest.fixture()
def get_driver():
    print("这是前置")
    driver = webdriver.Chrome()
    driver.get("http://mall.banbanban.com:3344/")
    driver.maximize_window()
    yield driver
    print("这是后置")
    driver.quit()

'''
此时,函数的返回值就是driver,因此前置返回就是driver,可以使用夹具替换掉其他文件中的实例化驱动语句
'''

# 登录也是前置,因此,登录也可以作为夹具
@pytest.fixture()
def login(get_driver):
    # 点击首页的登录操作
    print("这是login的前置")
    homepage = HomePage(get_driver)
    homepage.click_login_link()
    # 在登陆页面进行登录操作
    loginpage = LoginPage(get_driver)
    loginpage.login("auto", "123456")
    yield get_driver
    print("这是login的后置")

 base_page.py 文件的内容:

from d9_fixtur.pageobjects.home_page import HomePage
from d9_fixture.pageobjects.my_order_page import MyOrderPage
from d9_fixture.pageobjects.product_detail_page import ProductDetailPage
from d9_fixture.pageobjects.submit_order_page import SubmitOrderPage


def test_submit_order(login):

    # 登录,点击首页的登录链接
    home_page = HomePage(login)

    # 点击商品列表
    home_page.click_goods_list()

    # 搜索选择商品
    home_page.search_select_product("Mac")

    # 商品详情页
    product_detail_page = ProductDetailPage(login)
    product_name = product_detail_page.get_product_name()
    product_price = product_detail_page.get_product_price()
    product_detail_page.buy_now()

    # 提交订单
    submit_order_page = SubmitOrderPage(login)
    submit_order_page.submit_order()

    # 进入我的订单页面
    home_page.my_order()

    my_order_page = MyOrderPage(login)

    # 断言
    # 1、检查订单商品名称
    assert my_order_page.get_product_name() == product_name
    # 2、检查订单商品数量
    assert my_order_page.get_product_num() == '1'
    # 3、检查订单商品价格
    assert my_order_page.get_product_price() == product_price
    # 4、检查订单的状态
    assert my_order_page.get_order_status() == '待支付'

home_page.py文件的内容:

import time
from selenium.webdriver.common.by import By
from d9_fixtur.common.base_page import BasePage


class HomePage(BasePage):
    # 属性-登录链接
    login_link_locator = (By.LINK_TEXT,'登录')
    # 欢迎提示信息
    welcome_tips_locator = (By.XPATH,'//span[text()="欢迎来到我的世界"]')
    welcome_tips_text_locator = (By.XPATH,'//span[@class="text"]')
    # 用户名
    username_text_locator = (By.XPATH,'//a[@class="link-name"]')
    # 点击个人中心
    person_center_locator = (By.XPATH,"//span[text()='个人中心']")
    # 点击商品列表
    goods_list_locator = (By.LINK_TEXT,"商品列表")
    # 搜索框
    serach_input_locator = (By.XPATH,"//input[@class='search-input']")
    # 搜索按钮
    search_button_locator = (By.XPATH,"//input[@value = '搜索']")
    # 搜索第一个商品
    first_goods_locator = (By.XPATH,"//div[@class='goods-img']")
    # 我的订单定位
    my_order_button_locator = (By.XPATH,"//span[@data-route='order']")

    def click_login_link(self):
        time.sleep(5)
        self.click(self.login_link_locator)

    def is_display_welcome_tips(self):
        time.sleep(1)
        return self.wait_element_visible(self.welcome_tips_locator).is_displayed()

    def get_username_text(self):
        return self.get_text(self.username_text_locator)

    # 点击个人中心按钮
    def click_person_center(self):
        self.click(self.person_center_locator)

    # 点击商品列表
    def click_goods_list(self):
        self.click(self.goods_list_locator)

    # 进入我的订单页面
    def my_order(self):
        time.sleep(2)
        self.click(self.my_order_button_locator)


    # 搜索并选择对应的商品
    def search_select_product(self,goodname):
        time.sleep(1)
        self.input_text(self.serach_input_locator, goodname)
        self.click(self.search_button_locator)
        # 选择第一个商品
        time.sleep(1)
        self.click(self.first_goods_locator)



login.py文件的内容:

import time
from selenium.webdriver.common.by import By
from d9_fixture前置后置处理及日志封装.common.base_page import BasePage

class LoginPage(BasePage):
    # 属性->元素定位信息(元素定位方法+元素定位值)-元组类型
    phone_input_locator = (By.XPATH, '//input[@placeholder="请输入手机号/用户名"]')
    pwd_input_locator = (By.XPATH, '//input[@placeholder="请输入密码"]')
    login_button_locator = (By.CLASS_NAME, 'login-button')
    login_tips_locator = (By.XPATH,'//p[@class="el-message__content"]')

    # 用户名输入框错误提示文本
    user_input_error_tips_locator = (By.XPATH, '//div[contains(@class,"msg-error")]/following-sibling::div[1]')
    def login(self,phone,pwd):
        # 因为继承了 basepage类,所以克不用再写driver参数
        # self.wait_element_visible(self.driver,self.phone_input_locator).send_keys("17728373518")
        self.input_text(self.phone_input_locator, phone)
        self.input_text(self.pwd_input_locator, pwd)
        # 点击登录按钮
        time.sleep(3)
        self.click(self.login_button_locator)

    def get_login_tips(self):
        # 这里比较文本内容
        time.sleep(2)
        return self.get_text(self.login_tips_locator)

    def get_user_input_error_tips(self):
        return self.get_text(self.user_input_error_tips_locator)

my_order_page.py文件的内容:

from time import sleep
from selenium.webdriver.common.by import By
# 我的订单页面
from d9_fixture.common.base_page import BasePage


class MyOrderPage(BasePage):
    # 最新的一笔订单的商品名
    goods_name_locator = (By.XPATH,"//a[@class='name']")
    # 商品数量
    goods_num_locator = (By.XPATH,"//div[@class='goods-number']")
    # 商品付款总额
    pay_price_locator = (By.XPATH,"//td[@rowspan='1']/div/div/span")
    # 订单状态
    order_status_locator = (By.XPATH,"//div[@class='status']/div")

    def get_product_name(self):
        return self.get_text(self.goods_name_locator)

    def get_product_num(self):
        sleep(2)
        goods_num = self.get_text(self.goods_num_locator)
        return goods_num[1:]

    def get_product_price(self):
        product_amount = self.get_text(self.pay_price_locator)
        return product_amount[1:]

    def get_order_status(self):
        order_status = self.get_text(self.order_status_locator)
        return order_status.strip()

 product_detail_page.py文件的内容:

from selenium.webdriver.common.by import By

# 商品详情页面
from d9_fixture.common.base_page import BasePage


class ProductDetailPage(BasePage):
    # 商品名
    product_name_locator = (By.XPATH, "//div[@class='name-box']/div[@class='name']")
    # 商品价格
    product_price_locator = (By.XPATH, '//div[@class="price"]')
    # 添加购物车
    button_addcart_locator = (By.CLASS_NAME, "add-cart")
    # 立即购买
    button_buynow_locator = (By.CLASS_NAME, "buy-now")
    # 收藏商品
    button_collect_locator = (By.CLASS_NAME, "collect")

    def add_cart(self):
        self.click(self.button_addcart_locator)

    def buy_now(self):
        self.click(self.button_buynow_locator)

    def get_product_name(self):
        return self.get_text(self.product_name_locator)

    def get_product_price(self):
        product_price = self.get_text(self.product_price_locator)
        # 将换行符号去掉
        product_price = product_price.replace('\n', '')
        # 去掉开头的'¥'  ‘¥0.01’
        return product_price[1:]

 submit_order_page.py文件的内容:

from selenium.webdriver.common.by import By
# 提交订单页面
from d9_fixture.common.base_page import BasePage

class SubmitOrderPage(BasePage):
    # 提交订单按钮
    button_submit_locator = (By.LINK_TEXT, "提交订单")

    def submit_order(self):
        self.click(self.button_submit_locator)

user_center_page.py文件的内容:

from time import sleep
from selenium.webdriver.common.by import By
from d9_fixture.common.base_page import BasePage

class PersonCenterPage(BasePage):
    take_delivery_goods_link_locaotr = (By.LINK_TEXT,"收货地址")
    add_new_address_locator = (By.LINK_TEXT,"新增收货地址")
    recipient_name_locator = (By.XPATH,"//div[text()='收件人:']/following-sibling::div/input")
    recipient_phone_locator = (By.XPATH,"//div[@class='item'][1]//input[@class='input']")
    recipient_province_locator = (By.XPATH,"//div[@prop='province']//i")
    click_prodropdown_icon_locator = (By.XPATH,"//div[@x-placement='bottom-start']//li[text()='陕西省']")
    recipient_city_locator = (By.XPATH,"//div[@prop='city']//i")
    click_citydropdown_icon_locator = (By.XPATH,"//div[@x-placement='bottom-start']//li[text()='延安市']")
    recipient_area_locator = (By.XPATH,"//div[@prop='area']//i")
    click_areadropdown_icon_locator = (By.XPATH,"//div[@x-placement='bottom-start']//li[text()='黄龙县']")
    detail_address_locator = (By.XPATH,"//div[text()='详细地址:']/parent::div/div[2]/input")
    submit_button_locator = (By.LINK_TEXT,"保存收件人信息")
    add_address_success_tips_locator = (By.CLASS_NAME,"el-message__content")


    # 将新增地址的所有操作都放在一个函数中
    def write_detail_address(self,name,phone,province,city,area,detail_address):
        # 点击收货地址
        self.click(self.take_delivery_goods_link_locaotr)
        # 点击新增地址按钮
        self.click(self.add_new_address_locator)
        # 填写姓名
        sleep(2)
        self.input_text(self.recipient_name_locator, name)
        # 填写电话号码
        self.input_text(self.recipient_phone_locator, phone)
        # 填写省份信息
        self.click(self.recipient_province_locator)
        sleep(1)
        self.click((By.XPATH,f"//div[@x-placement='bottom-start']//li[text()='{province}']"))
        # 填写城市信息
        self.click(self.recipient_city_locator)
        self.click((By.XPATH,f"//div[@x-placement='bottom-start']//li[text()='{city}']"))
        # 填写区域信息
        self.click(self.recipient_area_locator)
        self.click((By.XPATH,f"//div[@x-placement='bottom-start']//li[text()='{area}']"))
        # 填写详细地址
        self.input_text(self.detail_address_locator, detail_address)
        # 点击提交按钮
        self.click(self.submit_button_locator)

    # 是否添加地址成功,通过提示来进行断言
    def add_new_address_tips(self):
        return self.get_text(self.add_address_success_tips_locator)

    # 添加手机号码作为断言的函数
    def is_phone_displayed(self,phone_number):
        return self.wait_element_visible((By.XPATH,f"//div[text()='{phone_number}']")).is_displayed()

test_add_address.py文件的内容:

from selenium import webdriver
from d9_fixture.pageobjects.home_page import HomePage
from d9_fixture.pageobjects.login_page import LoginPage
from d9_fixture.pageobjects.user_center_page import PersonCenterPage

def test_is_add_address_success(login):
    home_page = HomePage(login)
    # 点击个人中心
    home_page.click_person_center()
    # 在个人中心页面添加地址
    user_page = PersonCenterPage(login)
    # 添加地址
    user_page.write_detail_address("富贵花","18867894326","","东北市","富贵区","城市花园1号楼1单元101室")
    assert  user_page.add_new_address_tips() == '添加地址成功'
    # 添加手机号码断言
    assert user_page.is_phone_displayed("18867894326")

test_login.py文件的内容:

from time import sleep
import pytest
from selenium import webdriver
from d9_fixture.pageobjects.home_page import HomePage
from d9_fixture.pageobjects.login_page import LoginPage

def test_login_success(get_driver):
    # 点击首页的登录操作
    homepage = HomePage(get_driver)
    homepage.click_login_link()
    # 在登陆页面进行登录操作
    loginpage = LoginPage(get_driver)
    loginpage.login("uto","123456")
    # 断言检测测试是否成功(通过预期结果和实际结果的比较)
    #  检查点:1、欢迎页,如果函数的返回值为True,那么断言之后返回是通过的
    assert homepage.is_display_welcome_tips()
    # assert loginpage.get_login_tips() == '账号或者密码不正确'
    assert homepage.get_username_text() == 'uto'

# 对登录结果的断言
def test_login_uncorrect_username(get_driver):
    homepage = HomePage(get_driver)
    homepage.click_login_link()
    # 在登陆页面进行登录操作
    login_page = LoginPage(get_driver)
    login_page.login("lemon_auto1", "lemon123456")
    # 页面登录过程中的提示信息断言
    sleep(1)
    assert login_page.get_login_tips() == '账号或密码不正确'

login_datas = [{'username':'','password':'123456','tips':'账号为4~16位字母、数字或下划线'},
               {'username':'11','password':'123456','tips':'账号为4~16位字母、数字或下划线'},
               {'username':'lem','password':'123456','tips':'账号为4~16位字母、数字或下划线'}]

@pytest.mark.parametrize('datas',login_datas)
def test_login_fail(datas,get_driver):
    # 点击首页的登录链接
    home_page = HomePage(get_driver)
    home_page.click_login_link()
    # 在登录页面进行登录操作
    login_page = LoginPage(get_driver)
    login_page.login(datas['username'], datas['password'])
    # 用户名输入框的提示 - 断言
    assert login_page.get_user_input_error_tips()== datas['tips']

test_submit_order.py文件的内容:

from d9_fixture.pageobjects.home_page import HomePage
from d9_fixture.pageobjects.my_order_page import MyOrderPage
from d9_fixture.pageobjects.product_detail_page import ProductDetailPage
from d9_fixture.pageobjects.submit_order_page import SubmitOrderPage


def test_submit_order(login):
    # 登录,点击首页的登录链接
    home_page = HomePage(login)
    # 点击商品列表
    home_page.click_goods_list()
    # 搜索选择商品
    home_page.search_select_product("Mac")
    # 商品详情页
    product_detail_page = ProductDetailPage(login)
    product_name = product_detail_page.get_product_name()
    product_price = product_detail_page.get_product_price()
    product_detail_page.buy_now()

    # 提交订单
    submit_order_page = SubmitOrderPage(login)
    submit_order_page.submit_order()
    # 进入我的订单页面
    home_page.my_order()
    my_order_page = MyOrderPage(login)
    # 断言
    # 1、检查订单商品名称
    assert my_order_page.get_product_name() == product_name
    # 2、检查订单商品数量
    assert my_order_page.get_product_num() == '1'
    # 3、检查订单商品价格
    assert my_order_page.get_product_price() == product_price
    # 4、检查订单的状态
    assert my_order_page.get_order_status() == '待支付'

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Leetcode—80.删除有序数组中的重复项II【中等】

2023每日刷题&#xff08;十&#xff09; Leetcode—80.删除有序数组中的重复项II 双指针实现代码 int removeDuplicates(int* nums, int numsSize){int i 0;int j 1;int k 1;int tmp nums[i];while(j < numsSize) {if(nums[j] tmp && k < 2) {nums[i] n…

YOLOv5— Fruit Detection

&#x1f368; 本文为[&#x1f517;365天深度学习训练营学习记录博客 &#x1f366; 参考文章&#xff1a;365天深度学习训练营-第7周&#xff1a;咖啡豆识别&#xff08;训练营内部成员可读&#xff09; &#x1f356; 原作者&#xff1a;[K同学啊 | 接辅导、项目定制](https…

P1868 饥饿的奶牛

根据题意可以知道是一个动态规划&#xff0c;看完数据范围之后可以知道是一个线性DP。 解决方法有点类似于背包问题&#xff0c;枚举背包的每一个空间。 如果把坐标轴上每个点都看成一个块儿&#xff0c;只需要按顺序求出前 i 个块儿的最大牧草堆数&#xff0c;f[i] 就是前i的…

【软考系统架构设计师】2023年系统架构师冲刺模拟习题之《软件工程》

在软考中软件工程模块主要包含以下考点&#xff1a; 文章目录 软件过程模型&#x1f31f;&#x1f31f;&#x1f31f;&#x1f31f;逆向工程&#x1f31f;基于构件的软件工程&#x1f31f;&#x1f31f;软件开发与软件设计与维护净室软件工程软件模型软件需求 软件过程模型&am…

支持向量机(SVM)

一. 什么是SVM 1. 简介 SVM&#xff0c;曾经是一个特别火爆的概念。它的中文名&#xff1a;支持向量机&#xff08;Support Vector Machine, 简称SVM&#xff09;。因为它红极一时&#xff0c;所以关于它的资料特别多&#xff0c;而且杂乱。虽然如此&#xff0c;只要把握住SV…

Kotlin中使用ViewBinding绑定控件并添加点击事件

文章目录 效果1、加入依赖2、与控件进行绑定在 Activity 中使用视图绑定 3、监听控件 效果 实现源码 class MainActivity : AppCompatActivity() {lateinit var binding:ActivityMainBindingoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstan…

C# 串口通信简单示例

C# 简单串口通信示例 串口通信示例代码 串口通信 C# 串口通信主要操作&#xff1a; 命名空间&#xff1a;using System.IO.Ports;获取端口&#xff1a;string[] ports System.IO.Ports.SerialPort.GetPortNames();设置端口名&#xff1a;serialPort1.PortName “COM1”; //…

性能测试工具:如何学习JMeter?

JMeter是一个广泛应用于Web应用程序性能测试与负载测试的开源负载测试工具&#xff0c;学习JMeter则可以协助软件测试工程师更好地进行自动化性能测试与负载测试&#xff0c;本文就来介绍下如何学习JMeter。 1. 应用场景 (1) Web应用程序、数据库服务器、FTP服务器、SOAP和RE…

Makefile 基础教程:从零开始学习

在软件开发过程中&#xff0c;Makefile是一个非常重要的工具&#xff0c;它可以帮助我们自动构建程序&#xff0c;管理程序依赖关系&#xff0c;提高开发效率。本篇博客将从基础开始&#xff0c;介绍Makefile的相关知识&#xff0c;帮助大家快速掌握Makefile的使用方法 Makefil…

springboot异步线程池

项目中经常会遇到线程池异步处理一些任务 1.配置信息 # 异步线程配置 # 核心线程数 async:executor:thread:core_pool_size: 10# 最大线程数max_pool_size: 100# 任务队列大小queue_capacity: 20# 线程池中线程的名称前缀name:prefix: kc-async-service-# 缓冲队列中线程的空闲…

0基础学习PyFlink——用户自定义函数之UDTF

大纲 表值函数完整代码 在《0基础学习PyFlink——用户自定义函数之UDF》中&#xff0c;我们讲解了UDF。本节我们将讲解表值函数——UDTF 表值函数 我们对比下UDF和UDTF def udf(f: Union[Callable, ScalarFunction, Type] None,input_types: Union[List[DataType], DataTy…

【JavaEE初阶】 线程安全的集合类

文章目录 &#x1f340;前言&#x1f332;多线程环境使用 ArrayList&#x1f6a9;自己使用同步机制 (synchronized 或者 ReentrantLock)&#x1f6a9;Collections.synchronizedList(new ArrayList);&#x1f6a9;使用 CopyOnWriteArrayList &#x1f38d;多线程环境使用队列&am…

【AI视野·今日Robot 机器人论文速览 第五十九期】Fri, 20 Oct 2023

AI视野今日CS.Robotics 机器人学论文速览 Fri, 20 Oct 2023 Totally 29 papers &#x1f449;上期速览✈更多精彩请移步主页 Daily Robotics Papers CCIL: Continuity-based Data Augmentation for Corrective Imitation Learning Authors Liyiming Ke, Yunchu Zhang, Abhay D…

html/css/javascript/js实现的简易打飞机游戏

源码下载地址 支持&#xff1a;远程部署/安装/调试、讲解、二次开发/修改/定制 视频浏览地址

Java提升技术,进阶为高级开发和架构师的路线

原文网址&#xff1a;Java提升技术&#xff0c;进阶为高级开发和架构师的路线-CSDN博客 简介 Java怎样提升技术&#xff1f;怎样进阶为高级开发和架构师&#xff1f;本文介绍靠谱的成长路线。 首先点明&#xff0c;只写业务代码是无法成长技术的。提升技术的两个方法是&…

Qt之普通项目如何生成DLL(含源码+注释)

文章目录 一、示例图二、普通项目需要改造的内容三、源码&#xff08;创建了一个TestDLL的项目&#xff0c;更改内容主要在pro文件和maindow.h文件&#xff09;TestDLL.promainwindow.hmainwindow.cppmainwindow.ui 总结 一、示例图 使用不同的编译模式编译&#xff0c;会在对…

LLM系列 | 22 : Code Llama实战(下篇):本地部署、量化及GPT-4对比

引言 模型简介 依赖安装 模型inference 代码补全 4-bit版模型 代码填充 指令编码 Code Llama vs ChatGPT vs GPT4 小结 引言 青山隐隐水迢迢&#xff0c;秋尽江南草未凋。 小伙伴们好&#xff0c;我是《小窗幽记机器学习》的小编&#xff1a;卖热干面的小女孩。紧接…

Sql Server中的表组织和索引组织(聚集索引结构,非聚集索引结构,堆结构)

正文 SqlServer用三种方法来组织其分区中的数据或索引页&#xff1a; 1、聚集索引结构 聚集索引是按B树结构进行组织的&#xff0c;B树中的每一页称为一个索引节点。每个索引行包含一个键值和一个指针。指针指向B树上的某一中间级页&#xff08;比如根节点指向中间级节点中的…

私有云:【1】ESXI的安装

私有云&#xff1a;【1】ESXI的安装 1、使用VMware Workstation创建虚拟机2、启动配置虚拟机3、登录ESXI管理台 1、使用VMware Workstation创建虚拟机 新建虚拟机 选择典型安装 稍后安装操作系统 选择VMware ESXI 选择虚拟机安装路径 硬盘设置300G或者更多 自定义硬件 内存和处…