做测试,不会接口测试怎么能行?

接口测试的测试点

功能测试:单接口功能、业务场景功能

性能测试:响应时长、错误率、吞吐量、服务器资源使用率

安全测试:敏感数据是否加密、SQL注入、其他

本篇文章以接口功能测试为主。

接口用例设计方法:

单接口测试用例设计:

正向用例设计:

(1)必选参数。所有必选参数给正确数据

(2)组合参数:所有必选+任意可选,给正确数据

(3)全部参数:所有必选+所有可选,给正确参数

反向用例设计:

(1)功能异常:数据格式正确,不能履行接口功能

(2)数据异常:数据格式不正确(空格、特殊字符、字母、长度----等价类,边界值)

(3)参数异常:(多参、少参、无参、错误参数)

业务场景接口测试

(1)尽量模拟用户实际使用场景

(2)尽量用最少的用例,覆盖最多的接口请求

(3)一般情况下,覆盖正向的测试即可

案例1:登录接口用例设计(以下用例只是部分)

image.png

案例2:添加用户用例设计(以下用例只是部分)

image.png

接口测试工具-postman

关于postman的详细操作见:

接口测试工具之postman juejin.cn/post/695424…

使用requests库实现接口测试

Requests库 是 Python编写的,基于urllib 的 HTTP库,使用方便。

安装:pip install requests

或者指定国内镜像源安装:pip install requests -i https://pypi.douban.com/simple/

设置http请求语法

resp = requests.请求方法(url='URL地址', params={k:v}, headers={k:v},data={k:v}, json={k:v}, cookies='cookie数据'(如:令牌))

入门案例:访问百度接口

image.png

我们在练习过程中,可以使用开源商城tpshop来进行练习,具体安装在百度上搜索即可

案例:开源商城tpshop的登录接口

import requests

# 发送 post 请求,指定url、请求头、请求体,并获取响应结果
resp = requests.post(url="http://127.0.0.1/index.php?m=Home&c=User&a=do_login&t=0.04841131938292054",
                     headers={"Content-Type": "application/x-www-form-urlencoded"},
                     data={"username": "13012345678", "password": "1234567", "verify_code": "8888"})

# 打印响应结果 - 文本
print(resp.text)
# 打印响应结果 - json
print(resp.json())

案例:商城调用登录接口,增加cookie参数(tpshop项目:cookie+Session认证。

image.png

import requests

resp_v = requests.get(url="http://127.0.0.1/index.php?m=Home&c=User&a=verify&r=0.47350402574416184")

my_cookie = resp_v.cookies

resp = requests.post(url="http://127.0.0.1/index.php?m=Home&c=User&a=do_login&t=0.04841131938292054",
                     headers={"Content-Type": "application/x-www-form-urlencoded"},
                     data={"username": "18800000000", "password": "1234567", "verify_code": "8888"},
                     cookies=my_cookie)

print(resp.json())

image.png

以下方式是使用session认证,不需要获取cookie--掌握

import requests

# 1. 创建一个 Session 实例。
session = requests.session()
# 2. 使用 Session 实例,调 get方法,发送获取验证码请求。
session.get(url="http://127.0.0.1/index.php?m=Home&c=User&a=verify&r=0.47350402574416184")
# 3. 使用 同一个 Session 实例,调用 post方法,发送登录请求。
resp = session.post(url="http://127.0.0.1/index.php?m=Home&c=User&a=do_login&t=0.04841131938292054",
                    headers={"Content-Type": "application/x-www-form-urlencoded"},
                    data={"username": "18892089999", "password": "123456", "verify_code": "8888"})

print(resp.json())

面试题 Cookie 和 Session 区别

  1. 数据存储位置:

cookie存储在浏览器;session存储在服务器。

  1. 安全性:

cookie中的数据可以随意获取,没有安全性可言。Session的数据多为加密存储,安全较高!

  1. 数据类型:

cookie支持的数据类型受浏览器限制,较少;Session直接使用服务器存储,支持所有数据类型

  1. 大小:

cookie大小默认 4k; Session 大小约为服务器存储空间大小

Unittest框架集成Requests库

Unittest的相关详细知识见下面文档:

Python框架之UnitTest: juejin.cn/post/712533…

案例:登录接口,单个测试方法

import unittest
import requests


class TestLogin(unittest.TestCase):
    def test01_login(self):
        resp = requests.post(url="http://127.0.0.1/index.php?m=Home&c=User&a=do_login&t=0.04841131938292054",
                             headers={"Content-Type": "application/x-www-form-urlencoded"},
                             data={"username": "18892081111", "password": "123456", "verify_code": "8888"})
        print(resp.json())

        # 断言状态码
        self.assertEqual(200, resp.status_code)

        # 断言 success的值为True
        self.assertEqual(True, resp.json().get("success"))

PyMySQL操作数据库

应用场景:

校验测试数据:接口发送请求之后,明确会对数据库中的某个字段进行修改,但是响应结果中不体现

构造测试数据:比如测试数据使用一次就失败(用手机号添加员工);测试前,无法保证测试数据一定存在(比如:列表查询)

安装PyMySQLpip install PyMySQL

或者pip install PyMySQL -i https://pypi.douban.com/simple/

操作数据库的基本流程:

1、导包;import pymysql

2、创建数据库连接(connection);conn = pymysql.connect()

3、获取游标对象(cursor);cursor = conn.cursor()

4、执行操作;cursor.execute('sql语句')

(4.1)查询语句:不会对数据库产生影响,有结果集返回,使用fetch提取返回数据;

(4.2)增删改语句:会对数据库产生影响。成功:提交事务:conn.commit();失败:回滚事务:conn.rollback()

5、关闭游标对象(cursor);cursor.close()

6、关闭数据库连接(connection);conn.close()

案例:

# 1、导包;`
import pymysql
# 2、创建数据库连接(connection);`conn = pymysql.connect()
conn = pymysql.connect(host="localhost",port=3306,user="root",password="root",database="mysql",charset="utf8")
# 3、获取游标对象(cursor);`cursor = conn.cursor()
cursor = conn.cursor()
# 4、执行操作;`cursor.execute('sql语句')`
cursor.execute('select version()')
# 提取一行结果
res = cursor.fetchone()
print(res) # 返回元组
print(res[0]) #取返回的第一个值
# 5、关闭游标对象(cursor);`cursor.close()`
cursor.close()
# 6、关闭数据库连接(connection);`conn.close()`
conn.close()

常用方法说明:

fetchone():从结果集中提取一行

fetchmany(size):从结果集中提取size行

fetchall():提取所有结果集

属性rownumber:可以设置游标位置(cursor.rownumber = 0(设置游标归零))

数据库工具类封装:

(1)获取、关闭连接

import pymysql
# 封装数据库工具类
class DBUtil(object):
    # 添加类属性
    conn = None

    @classmethod
    def __get_conn(cls):
        # 判断 conn 是否为空, 如果是,再创建
        if cls.conn is None:
            cls.conn = pymysql.connect(host="localhost",port=3306,user="root",password="root",database="mysql",charset="utf8")
        # 返回非空连接
        return cls.conn

    @classmethod
    def __close_conn(cls):
        # 判断conn 不为空,需要关闭。
        if cls.conn is not None:
            cls.conn.close()
            cls.conn = None

(2)查询一条记录

# 常用方法:查询一条结果
    @classmethod
    def select_one(cls, sql):
        cursor = None
        res = None
        try:
            # 获取连接
            cls.conn = cls.__get_conn()
            # 获取游标
            cursor = cls.conn.cursor()
            # 执行 查询语句
            cursor.execute(sql)
            # 提取一条结果
            res = cursor.fetchone()
        except Exception as err:
            print("查询sql错误:", str(err))
        finally:
            # 关闭游标
            cursor.close()
            # 关闭连接
            cls.__close_conn()
            # 将查询sql执行的 结果,返回
            return res

if __name__ == '__main__':
    res = DBUtil.select_one("select * from person;")
    print("查询结果为:", res)

(3)增删改数据时方法封装

# 常用方法:增删改数据
    @classmethod
    def uid_db(cls, sql):
        cursor = None
        try:
            # 获取连接
            cls.conn = cls.__get_conn()
            # 获取游标
            cursor = cls.conn.cursor()
            # 执行 uid 语句
            cursor.execute(sql)
            print("影响的行数:", cls.conn.affected_rows())
            # 提交事务
            cls.conn.commit()
        except Exception as err:
            # 回滚事务
            cls.conn.rollback()
            print("增删改 SQL 执行失败:", str(err))
        finally:
            # 关闭游标
            cursor.close()
            # 关闭连接
            cls.__close_conn()

if __name__ == '__main__':
    DBUtil.uid_db("update person set age = 30 where id = 2;")

接口对象封装

核心思想:代码分层思想,分为接口对象层和测试脚本层

(1)接口对象层:对接口进行封装,封装好之后,给测试用例层调用,面向对象类封装实现。

(2)测试用例层:调用接口对象层封装的方法,获取响应结果,断言进行接口测试,借助unittest框架实现。

封装思想:

(1)将动态变化的数据设计到方法的参数;

(2)将固定不变的,直接写成方法的实现;

(3)将响应结果通过返回值传出;

我们以TPshop开源商城为例,在没有封装之前的代码为:

import unittest
import requests


class TestTpshopLogin(unittest.TestCase):
    # 测试登录成功
    def test01_login_ok(self):
        # 创建 session 实例
        session = requests.Session()
        # 使⽤实例,调⽤get 发送获取验证码请求
        session.get(url="http://127.0.0.1/index.php?m=Home&c=User&a=verify&r=0.47350402574416184")
        # 使⽤实例,调⽤post 发送登录请求
        resp = session.post(url="http://127.0.0.1/index.php?m=Home&c=User&a=do_login&t=0.04841131938292054",
                            headers={"Content-Type": "application/x-www-form-urlencoded"},
                            data={"username": "18892089999", "password": "123456", "verify_code": "8888"})
        print("响应结果 =", resp.json())
        # 断⾔:
        self.assertEqual(200, resp.status_code)
        self.assertEqual(1, resp.json().get("status"))
        self.assertEqual("登陆成功", resp.json().get("msg"))

    # 测试⼿机号不存在
    def test02_tel_not_exists(self):
        # 创建 session 实例
        session = requests.Session()
        # 使⽤实例,调⽤get 发送获取验证码请求
        session.get(url="http://127.0.0.1/index.php?m=Home&c=User&a=verify&r=0.47350402574416184")
        # 使⽤实例,调⽤post 发送登录请求
        resp = session.post(url="http://127.0.0.1/index.php?m=Home&c=User&a=do_login&t=0.04841131938292054",
                            headers={"Content-Type": "application/x-www-form-urlencoded"},
                            data={"username": "18892099999", "password": "123456", "verify_code": "8888"})
        print("响应结果 =", resp.json())
        # 断⾔:
        self.assertEqual(200, resp.status_code)
        self.assertEqual(-1, resp.json().get("status"))
        self.assertEqual("账号不存在!", resp.json().get("msg"))

    # 测试密码错误
    def test03_pwd_err(self):
        # 创建 session 实例
        session = requests.Session()
        # 使⽤实例,调⽤get 发送获取验证码请求
        session.get(url="http://127.0.0.1/index.php?m=Home&c=User&a=verify&r=0.47350402574416184")
        # 使⽤实例,调⽤post 发送登录请求
        resp = session.post(url="http://127.0.0.1/index.php?m=Home&c=User&a=do_login&t=0.04841131938292054",
                            headers={"Content-Type": "application/x-www-form-urlencoded"},
                            data={"username": "18892089999", "password": "999999", "verify_code": "8888"})
        print("响应结果 =", resp.json())
        # 断⾔:
        self.assertEqual(200, resp.status_code)
        self.assertEqual(-2, resp.json().get("status"))
        self.assertEqual("密码错误!", resp.json().get("msg"))

对以上代码进行封装:

封装接口对象层:

class TpshopLoginApi(object):

    # 发送验证码请求
    @classmethod
    def get_verify(cls, session):
        session.get(url="http://127.0.0.1/index.php?m=Home&c=User&a=verify&r=0.47350402574416184")

    # 发送登录请求
    @classmethod
    def login(cls, session, login_data):
        resp = session.post(
            url="http://127.0.0.1/index.php?m=Home&c=User&a=do_login&t=0.04841131938292054",
            data=login_data)
        return resp

断言方法封装:

def common_assert(self, resp, status_code, status, msg):
    # 断⾔:
    self.assertEqual(status_code, resp.status_code)
    self.assertEqual(status, resp.json().get("status"))
    self.assertEqual(msg, resp.json().get("msg"))

测试用例层封装结果:

import unittest
import requests
from TPshop_login_api import TpshopLoginApi
from tp_shop_assert import common_assert


class TestShopLogin(unittest.TestCase):
    # 添加类属性
    session = None

    @classmethod
    def setUpClass(cls) -> None:
        cls.session = requests.Session()

    def setUp(self) -> None:
        TpshopLoginApi.get_verify(self.session)

    # 测试登录成功
    def test01_login_ok(self):
        login_data = {"username": "18892089999", "password": "123456", "verify_code": "8888"}
        resp = TpshopLoginApi.login(self.session, login_data)
        print("登录成功的结果:", resp.json())
        common_assert(self, resp, 200, 1, "登陆成功")

    # 测试⼿机号不存在
    def test02_tel_not_exists(self):
        login_data = {"username": "18892099999", "password": "123456", "verify_code": "8888"}
        resp = TpshopLoginApi.login(self.session, login_data)
        print("登录成功的结果:", resp.json())
        # 断⾔:
        common_assert(self, resp, 200, -1, "账号不存在!")

    # 测试密码错误
    def test03_pwd_err(self):
        login_data = {"username": "18892089999", "password": "999999", "verify_code": "8888"}
        resp = TpshopLoginApi.login(self.session, login_data)
        print("登录成功的结果:", resp.json())
        # 断⾔:
        common_assert(self, resp, 200, -2, "密码错误!")

以上代码参数化:

# 参数化的数据,实际项目中需要单独保存
json_data = [
    {
        "req_body": {"username": "18892080505", "password": "123456", "verify_code": "8888"},
        "status_code": 200,
        "status": 1,
        "msg": "登陆成功"
    },
    {
        "req_body": {"username": "18892099999", "password": "123456", "verify_code": "8888"},
        "status_code": 200,
        "status": -1,
        "msg": "账号不存在!"
    },
    {
        "req_body": {"username": "18892080505", "password": "999999", "verify_code": "8888"},
        "status_code": 200,
        "status": -2,
        "msg": "密码错误!"
    }
]


# 封装函数,将 数据 转换为 元组列表。
def read_json_data():
    # 将[{},{},{},{}]格式转化成[(),(),(),()]
    list_data = []
    for item in json_data:
        tmp = tuple(item.values())
        list_data.append(tmp)

    print(list_data)
    return list_data

在通用方法中实现参数化:

class TestShopLogin(unittest.TestCase):
    # 添加类属性
    session = None

    @classmethod
    def setUpClass(cls) -> None:
        cls.session = requests.Session()

    def setUp(self) -> None:
        TpshopLoginApi.get_verify(self.session)

    # 测试登录
    @parameterized.expand(read_json_data())
    def test_tpshop_login(self, req_body, status_code, status, msg):
        resp = TpshopLoginApi.login(self.session, req_body)
        print("登录成功的结果:", resp.json())
        common_assert(self, resp, status_code, status, msg)

接口自动化测试框架思想

目录结构

5个目录、2个文件:

api/: 存储接口对象层(自己封装的 接口)

scripts/: 存储测试脚本层 (unittest框架实现的 测试类、测试方法)

data/: 存储 .json 数据文件

report/: 存储 生成的 html 测试报告

common/: 存储 通用的 工具方法

confifig.py: 存储项目的配置信息(全局变量)

run_suite.py: 组装测试用例、生成测试报告的 代码

日志

日志的级别

logging.DEBUG:调试级别【高】

logging.INFO:信息级别【次高】

logging.WARNING:警告级别【中】

logging.ERROR:错误级别【低】

logging.CRITICAL:严重错误级别【极低】

特性:日志级别设定后,只有比该级别低的日志会写入日志。

日志代码,无需手写实现。会修改、调用即可!

import logging.handlers
import logging
import time


def init_log_config(filename, when='midnight', interval=1, backup_count=3):
    # 1. 创建日志器对象
    logger = logging.getLogger()

    # 2. 设置日志打印级别
    logger.setLevel(logging.DEBUG)
    # logging.DEBUG 调试级别
    # logging.INFO 信息级别
    # logging.WARNING 警告级别
    # logging.ERROR 错误级别
    # logging.CRITICAL 严重错误级别

    # 3.1 创建 输出到控制台 处理器对象
    st = logging.StreamHandler()
    # 3.2 创建 输出到日志文件 处理器对象
    # when 字符串,指定日志切分间隔时间的单位。midnight:凌晨:12点。
    # interval 是间隔时间单位的个数,指等待多少个 when 后继续进行日志记录
    # backupCount 是保留日志文件的个数
    fh = logging.handlers.TimedRotatingFileHandler(filename, when=when, interval=interval, backupCount=backup_count, encoding='utf-8')

    # 4. 创建日志信息格式
    fmt = "%(asctime)s %(levelname)s [%(filename)s(%(funcName)s:%(lineno)d)] - %(message)s"
    formatter = logging.Formatter(fmt)

    # 5.1 日志信息格式 设置给 控制台处理器
    st.setFormatter(formatter)
    # 5.2 日志信息格式 设置给 日志文件处理器
    fh.setFormatter(formatter)

    # 6.1 给日志器对象 添加 控制台处理器
    logger.addHandler(st)
    # 6.2 给日志器对象 添加 日志文件处理器
    logger.addHandler(fh)


if __name__ == '__main__':
    # 初始化日志
    init_log_config('tp_shop_log.log', interval=3, backup_count=5)
    # 打印输出 日志信息
    logging.warning("这是警告日志的信息")
    logging.debug("这是debug日志信息")
    a = 9999
    logging.error(f"这是error级别的信息a = {a}")

全量字段的校验-对断言的补充

流程:

(1)定义json语法校验格式

(2)⽐对接口实际响应数据是否符合json校验格式

全量字段校验需要安装jsonschema

pip install jsonschema -i https://pypi.douban.com/simple/

在线工具校验:www.jsonschemavalidator.net

image.png

python代码入门:

# 1. 导包
import jsonschema

# 2. 创建校验规则
schema = {
  "type": "object",
  "properties": {
    "success": {
      "type": "boolean"
    },
    "code": {
      "type": "integer"
    },
    "message": {
      "type": "string"
    }
  },
  "required": ["success","code","message"]
}

# 准备待校验的数据
data = {
  "success": True,
  "code": 200,
  "message": "操作成功"
}

# 3. 调用 validate 方法,实现校验

result = jsonschema.validate(instance = data,schema=schema)
print("result = ", result)
# None: 代表校验通过
# ValidationError:数据与校验规则不符
# SchemaError: 校验规则语法有误

JSON Schema语法中常用的关键字(来源某视频课程):

image.png

(1)type关键字:约束数据类型

integer —— 整数
string —— 字符串
object —— 对象
array —— 数组 --> python:list 列表
number —— 整数/⼩数
null —— 空值 --> python:None
boolean —— 布尔值

语法:
{
    "type": "数据类型"
}

(2)properties关键字:是 type关键字的辅助。用于 type 的值为 object 的场景。指定对象中 每个字段的校验规则。 可以嵌套使用。

语法:
{
    "type": "object",
    "properties":{
    "字段名1":{规则},
    "字段名2":{规则},
......
}
}

(3)required关键字:校验对象中必须存在的字段。字段名必须是字符串,且唯⼀

语法:
{
"required": ["字段名1", "字段名2", ...]
}

(4)const关键字:校验字段值是⼀个固定值。

语法:
{
"字段名":{"const": 具体值}
}

(5)pattern关键字:指定正则表达式,对字符串进行模糊匹配

语法:

{
"字段名":{"pattern": "正则表达式"}
}

补充中......

行动吧,在路上总比一直观望的要好,未来的你肯定会感 谢现在拼搏的自己!如果想学习提升找不到资料,没人答疑解惑时,请及时加入扣群: 320231853,里面有各种软件测试+开发资料和技术可以一起交流学习哦。

最后感谢每一个认真阅读我文章的人,礼尚往来总是要有的,虽然不是什么很值钱的东西,如果你用得到的话可以直接拿走:

这些资料,对于【软件测试】的朋友来说应该是最全面最完整的备战仓库,这个仓库也陪伴上万个测试工程师们走过最艰难的路程,希望也能帮助到你!

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

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

相关文章

如何通过Linux pciehp sysfs接口控制PCIe Slot电源状态?-3

pciehp sysfs接口电源控制与NVME驱动卸载的区别 从NVMe SSD设计本身而言,当通过pciehp sysfs接口对PCIe插槽执行Power Off操作时,由于NVMe SSD作为PCIe设备,其电源供应是直接依赖于所连接的PCIe插槽提供的。当插槽电源被关闭时,会…

天工期刊投稿发表论文

《天工》杂志是由国家新闻出版总署批准,山西省科学技术协会主管、山西科技新闻出版传媒有限责任公司主办的工艺美术类专业期刊。杂志以“宣传中华工艺美术技艺,传播前沿工艺美术新成果,挖掘工艺美术人才,助推工美品牌打造”为办刊…

SpringCloudAlibaba之nacos的服务注册与发现

Nacos的服务注册与发现 照例放个妹子 本章节讲解nacos的服务注册与发现的简单使用 如图所示&#xff1a;按照图示搭建一个nacos作为服务注册中心的简单应用 创建provider服务提供者 创建nacos-discovery-provider模块引入依赖 <dependencies><dependency><…

vue3从精通到入门4:diff算法的实现

Vue 3 的 diff 算法相较于 Vue 2 有了一些改进和优化&#xff0c;主要是为了应对更复杂的组件结构和更高的性能需求。 以下是 Vue 3 diff 算法在处理列表更新时的大致步骤&#xff1a; 头头比较&#xff1a;首先&#xff0c;比较新旧列表的头节点&#xff08;即第一个节点&…

聚观早报 | 哪吒L上市定档;iPhone 16最新高清渲染图

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。 整理丨Cutie 4月10日消息 哪吒L上市定档 iPhone 16最新渲染图 华为太空表与问界M9联动 蔚来万里长城加电风景线正式贯通 Red…

transformer架构详细详解

一、transformer的贡献 transformer架构的贡献&#xff1a;该架构只使用自注意力机制&#xff0c;没有使用RNN或卷积网络。且可以实现并行计算&#xff0c;加快模型训练速度。 &#xff08;将所有的循环层全部换成&#xff1a;multi-headed self-attention&#xff09; 二、t…

leetcode刷题日记之全排列

题目描述 题目解释 这个题类似于之前做的某一道题&#xff0c;其实算法还是要追踪到树的深度遍历&#xff0c;相当于便利叶子节点的路径记录。不过递归的过程就相当于件数根据树进行遍历了。 代码如下 class Solution:def permute(self, nums: List[int]) -> List[List[i…

fiddler常用操作汇总

1、过滤 2、查看数据包内容 3、弱网测试 弱网测试其实就是提前设置好一个值&#xff0c;在这个环境下进行测试就行了。 &#xff08;1&#xff09;进入定制规则页面&#xff1a; (2) 点击CtrlF调起搜索&#xff0c;在Find what 中输入300进行查找&#xff0c;更改上行、下行网…

(四)C++自制植物大战僵尸游戏启动流程

植物大战僵尸游戏开发教程专栏地址http://t.csdnimg.cn/ErelL 一、启动方式 鼠标左键单机VS2022上方工具栏中绿色三角按钮&#xff08;本地Windows调试器&#xff09;进行项目启动。第一次启动项目需要编译项目中所有代码文件&#xff0c;编译生成需要一定的时间。不同性能的电…

LPRNet车牌识别模型训练及CCPD数据集预处理

LPRNet车牌识别模型训练及CCPD数据集预处理 1 LPRNet车牌识别模型训练 1.1 源码:LPRNet_Pytorch-master 源码官网:GitHub - sirius-ai/LPRNet_Pytorch: Pytorch Implementation For LPRNet, A High Performance And Lightweight License Plate Recognition Framework. 链…

内网渗透-cobaltstrike之cs上线获取shell

cobaltstrike之cs上线获取shell 文章目录 cobaltstrike之cs上线获取shell前言一、什么是cobaltstrike二、cs上线获取shell 1.环境搭建 CS安装windows连接 2. cs上线获取shell 总结 前言 一、什么是cobaltstrike CobaltStrike是一款渗透测试神器&#xff0c;被业界人称为CS神器…

U盘有很多空间不见,看这篇能不能帮你解决

文章目录 概要整体架构流程 概要 我本来想在u盘上&#xff0c;安装一个ubuntu系统&#xff0c;结果一直安装失败&#xff0c;最后u盘空间还有好多没有了就是显示不出来了 整体架构流程 按住winx&#xff0c;会弹出以下界面 选择磁盘管理 然后会看到 这个就是你的u盘&…

工业物联网网关

在数字化浪潮席卷全球的今天&#xff0c;工业物联网&#xff08;IIoT&#xff09;作为连接物理世界与数字世界的桥梁&#xff0c;正在逐渐改变传统工业的面貌。而作为IIoT的核心枢纽&#xff0c;工业物联网网关发挥着至关重要的作用。今天&#xff0c;我们就来深入了解一下工业…

OpenHarmony实战开发-Axios获取解析网络数据。

介绍 本示例介绍使用第三方库的Axios获取GBK格式的网络数据时&#xff0c;通过util实现GBK转换UTF-8格式。该场景多用于需要转换编码格式的应用。 效果图预览 使用说明 直接进入页面就可获取GBK格式的用户名信息并进行解码操作。 实现思路 1.使用第三方库Axios获取网络数据…

基于51单片机的自行车测速里程码表设计( proteus仿真+程序+设计报告+原理图+讲解视频)

基于51单片机的自行车测速里程码表设计 1. 主要功能&#xff1a;2. 讲解视频&#xff1a;3. 仿真设计4. 程序代码5. 设计报告6. 原理图7. 设计资料内容清单资料下载链接&#xff1a; 基于51单片机的自行车测速里程码表设计( proteus仿真程序设计报告原理图讲解视频&#xff09;…

内网渗透-Windows内网渗透

内网渗透-Windows内网渗透 文章目录 内网渗透-Windows内网渗透前言一、信息收集 1.1、SPN1.2、端口连接1.3、配置文件1.4、用户信息1.6、会话收集1.7、凭据收集 navicat&#xff1a;SecureCRT&#xff1a;Xshell&#xff1a;WinSCP&#xff1a;VNC: 1.8、DPAPI1.9、域信任1.10、…

Linux第87步_阻塞IO实验

阻塞IO是“应用程序”对“驱动设备”进行操作&#xff0c;若不能获取到设备资源&#xff0c;则阻塞IO应用程序的线程会被“挂起”&#xff0c;直到获取到设备资源为止。 “挂起”就是让线程进入休眠&#xff0c;将CPU的资源让出来。线程进入休眠后&#xff0c;当设备文件可以操…

字节跳动大佬把Python入门知识点整理成手册了,高清PDF开放下载_字节跳动 python 自学笔记

前言 无论是学习任何一门语言&#xff0c;基础知识一定要扎实&#xff0c;基础功非常的重要&#xff0c;找一个有丰富编程经验的老师或者师兄带着你会少走很多弯路&#xff0c; 你的进步速度也会快很多&#xff0c;无论我们学习的目的是什么&#xff0c;不得不说Python真的是一…

GPT 交互式提示工程

简介&#xff1a;交互式提示工程 人工智能领域&#xff0c;尤其是 GPT&#xff08;生成式预训练变压器&#xff09;等工具&#xff0c;凸显了即时工程的关键作用。 这篇扩展文章深入探讨了如何设计有效的提示&#xff0c;以从 GPT 等 AI 模型中获得出色的响应。 了解即时工程即…

Vue3(三):生命周期、路由、自定义hooks

这里终于明白了为什么一直有这个语法报错&#xff0c;就是在提示你哪里错的地方上方注释一行/*eslint-disable*/&#xff0c;之前一直警告这个错误感谢老师&#xff01; 一、vue2和vue3生命周期 还有一个问题就是父组件和子组件哪个先挂载完毕呢&#xff1f;答案是子组件先挂…