Fork me on GitHub

Linux

  • 父子进程不共享变量,子进程和父进程分别执行程序

  • 创建子进程(父子进程程序相同,进程号不同)并执行时,父子进程分别为2个程序,同时执行各自程序

  • 线程共享

  • terminal运行./a.out &,’&’表示后台运行 相关链接

实验8

1.1

  • 可靠信号(Reliable Signals): 这种信号在发送时不会丢失,系统会确保信号最终被接收。当进程处于阻塞状态时,可靠信号会被排队,直到进程解除阻塞后才被传递。SIGINT通常被认为是可靠信号。

  • 不可靠信号(Unreliable Signals): 这种信号可能在发送时丢失,而且不会在信号过多导致排队不足时保存。进程在信号未被处理完全之前,可能不会接收到新的信号。SIGIO和SIGURG通常被认为是不可靠信号。

    不可靠信号和可靠信号的区别在于前者不支持排队,可能会造成信号丢失,而后者不会。非可靠信号一般都有确定的用途及含义,可靠信号则可以让用户自定义使用。

阅读更多...

实验9

1.1

​ 操作系统中进程通信的作用是允许不同的进程之间交换信息和共享资源,以实现协同工作和数据共享。这有助于多任务处理和分布式系统的有效管理。进程通信可通过各种机制实现,包括共享内存、消息传递、管道等。通过进程通信,不同的进程可以协调完成任务、共享数据,提高系统的整体效率。


阅读更多...

测试笔记

安全测试-主要针对的是sql注入

sql注入:允许攻击者将恶意SQL代码插入到应用程序的输入参数中,这些参数随后被传递给‌数据库服务器执行。

SQL注入攻击的总体思路

  • 寻找到SQL注入的位置
  • 判断服务器类型和后台数据库类型
  • 针对不同的服务器和数据库特点进行SQL注入攻击

通用用例编写

正逆向:主要考虑以下方面

  1. 为空(逆向)
  2. 类型
  3. 长度
  4. 规则
    • 可选项
    • 存在与否
    • 已登录?
  • 正向用例:选最多那一个,尽可能覆盖
  • 逆向用例:全部加起来

接口测试

一、接口测试用例

接口测试正向:

  1. 必填参数
  2. 全部参数

接口测试逆向,主要考虑必填参数以下方面(同功能测试):

  1. 为空
  2. 类型
  3. 长度
  4. 规则

测试用例预期结果内容:

  1. 响应状态码
  2. 响应数据

postman代码与断言:

  1. 将响应数据(json格式)的某些数据保存到环境变量:
1
2
3
4
5
//保存json数据
const jsonData = pm.response.json()

//将json数据的key为uuid的值保存到环境变量
pm.environment.set("uuid2",jsonData.uuid)
  1. 响应状态码断言:
1
2
3
4
5
6
7
8
9
10
//判断响应状态码是否等于200
pm.test("status code is 200", () => {
pm.response.to.have.status(200);
});

pm.test()函数:
参数1:字符串-测试断言名称
参数2:回调函数一具体断言语句

pm.response.to.have.statuscode:Number):判断是否包含指定的状态码
  1. 包含指定字符串断言:
1
2
3
4
5
6
7
8
9
10
//判断响应结果是否包含指定字符串
pm.test("Body matches string",() => {
pm.expect(pm.response.text()).to.include("string_you_want_to_search") ;
);

//通过一系列调用链判断是否符合预期
pm.expect():接收实际结果
.to:连接符,用于连接断言与判断
.include():用于指定断言方式和预期结果
pm.presponse.text():获取响应结果的文本格式数据
  1. JSON数据断言
1
2
3
4
5
6
7
8
//校验响应的JSON数据
pm.test("Your test name", () => {
const jsonData = pm.response.json();
pm.expect(jsonData.value).to.eql(100);
});

pm.response.json()获取响应结果的json数据
.eq1():用于指定断言方式和预期结果

.to:连接符,用于连接断言与判断

例子:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//针对状态码
pm.test("响应状态码为200",()=>{
pm.response.to.have.status(200)
})

//针对文本
pm.test("响应数据包含成功",()=>{
pm.expect(pm.response.text()).to.include("成功")
})

//针对json的某个key是否等于某个值
pm.test("msg为操作成功",()=>{
pm.expect(pm.response.json().msg).to.eql('操作成功')
})

文档参数化

请求数据+预期结果放到json文件参数化

将测试数据放到json文件,只需一个请求就可以使用多个测试数据。

  1. 请求数据参数化,请求体数据参数化直接读取json文件,{{key}}

  2. 预期结果参数化,断言数据参数化直接读取json文件,data.key

pytest自动化接口测试

文件命名:

  1. 文件以test开头或结尾
  2. 类名,函数名以test开头或结尾

项目结构

allure使用步骤:

  1. 将pytest配置文件中的命令行参数加上如下下代码
1
--alluredir report
  1. 编写好测试脚本后,在命令行行中运行pytest

pytest.ini

1
2
3
4
5
6
[pytest]
addopts = -s --alluredir report # 运行模式 allure 目录
testpaths = ./scripts # 脚本目录
python_files = test*.py # 需要运行的文件test开头
python_classes = Test* # 文件内的测试类
python_functions = test* # 文件内的测试方法
  1. 程序运行结束后,会在项目的report目录中生成一些json文件
  2. 使用allure生成在线报告
1
2
3
4
5
6
安装:
1. https://github.com/allure-framework/allure2/releases 下载 allure
2.解压缩安装包到一个不包含中文路径的目录
3.将压缩包内的 bin 目录配置到 path 系统环境变量
4.右键我的电脑-属性-高级设置-环境变量-找到系统环境变量的path项-增加 allure到bin目录
5.在命令行中输入 allure--version 命令,能显示allure版本信息,即为成功
  1. 运行项目生成测试文件(json)

pytest

  1. 生成报告

    allure serve report

配置文件config.py

1
2
3
4
5
6
7
8
9
10
# 存放被测试项目基本信息,如baseURL地址等

# 操作系统库
import os

# 设置项目环境域名
BASE_URL = "http://kdtx-test.itheima.net"

# 获取项目根路径
BASE_PATH = os.path.dirname(__file__)

pytest数据驱动

概念:以测试数据驱动脚本执行,维护焦点从脚本转向测试数据文件

好处:提高代码可维护性。脚本只需要介绍请求体数据即可,脚本不会有什么变化,只有测试数据会有变化

pytest中parametrize装饰器

作用:遍历所有测试数据并运行测试方法。

语法:

1
2
3
4
5
6
7
@pytest.mark.parametrize(②保存数据参数名,①测试数据)
def test_method(self, ③参数名)
pass

测试数据:格式列表嵌套元组
保存数据参数名:参数个数必须与数据个数相等
参数名:直接复制②即可

示例:

1
2
3
4
5
6
7
8
9
10
11
# 测试数据
test_data = [
# 用户名 密码 响应码 msg code
("admin", "HM_2023_test", 200, '成功', 200),
("", "HM_2023_test", 200, '错误', 500),
("coffeelin", "HM_2023_test", 200, '错误', 500)
]

@pytest.mark.parametrize("username,password,status,message,code",test_data)
def test_login(self,username,password,status,message,code):
pass
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 前提:准备测试数据的json文件

# 读取json文件,转换为列表格式
def build_data(json_file):
# 定义空列表
test_data = []
# 打开json文件
with open(json_file,"r",encoding='utf-8') as f:
# 加载json
json_data = json.load(f)
# 遍历json_data,并添加到test_data
for case_data in json_data:
# 转换数据格式[{key:val},{key:val}]==>[(val),(val)]
username = case_data.get("username")
passwoed = case_data.get("passwoed")
status = case_data.get("status")
message = case_data.get("message")
code = case_data.get("code")
test_data.append((username,passwoed,status,message,code))
# 返回处理后数据
return test_data

@pytest.mark.parametrize("username,password,status,message,code",build_data(json_file="../data/login.json"))
def test_login(self,username,password,status,message,code):
pass

Axure快捷键

添加元件类:

  1. R:矩形;
  2. L:线段;
  3. 0:圆形;
  4. P:绘画;
  5. T:文本;

操作类:

  1. S:图片切割;
  2. >:预览原型;
  3. c:图片裁剪;
  4. /:发布原型到Axure云;
  5. x:创建交互;
  6. 0:元件透明度0%和100%切换;
  7. N:添加说明;
  8. 1-9:元件透明度10%-90%;
  • 动态面板可以固定到浏览器窗口,也可以多状态切换。

    1.动态面板应用:列表1改变时,列表2也变。

    实现:列表2用动态面板。操作是将列表2转换为面板,然后设置相应的状态。列表1使用选项改变时交互条件,然后选择设置动态面板,点击列表1对应选项后出现列表2不同面板状态用情形/条件即可。

    2.动态面板应用:状态改变,轮播图等。

    3.动态面板应用:拖动、固定位置的按钮、置顶按钮等。

  • 热区放在底部可以作为锚点,保证页面能下滑到一定位置

  • 中继器类似于组件,可以复用。中继器可排序筛选等

  • 快速制作中继器:先用矩形制作表头,然后删除中继器原有的一个矩形,再复制表头到中继器。中继器每一行就是一个item项。

中继器应用场景:重复的组件操作,表单数据操作(增删改查,分页分项、排序等)

母版:创建一个母版,可以为多个页面添加相同的组件,母版变则所有页面也变。

母版引发事件:当母版上的某个选项在不同页面触发事件时执行结果不同,需要在母版里设置引发事件(相当于设置了专属于这个选项的一个事件等待触发),再到具体页面的母版位置触发该引发事件并设置动作。(母版里设置引发事件,具体页面里触发事件和设置动作。)

母版里设置了一个针对某一选项的事件(引用事件),在具体页面里对母版新建交互时,触发该事件并设置动作。

变量

局部变量:作用域是单个组件内。可以获取到元件对象、数值、文字、被选项等,对象需要先获取并赋值给局部变量。

全局变量:作用域是不同页面间。在项目中设置全局变量

先获取到局部变量->再赋值给全局变量

获取元件

  1. this:当前元件

  2. target:目标元件

  3. 局部变量:获取任意元件

怎么安装多版本的node?

怎么安装多版本的node

要在同一台机器上安装多个版本的Node.js,可以使用nvm(Node Version Manager)。以下是安装和使用nvm来管理多版本Node.js的步骤:

  1. 安装nvm

    • 对于macOS和Linux,可以使用curlwget

      1
      2
      3
      curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
      # 或者
      wget -qO- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
    • 对于Windows,可以使用nvm-windows

  2. 安装Node.js特定版本:

    1
    2
    nvm install 14.17.0
    nvm install 16.0.0
  3. 切换到特定版本的Node.js:

    1
    nvm use 14.17.0
  4. 确认当前使用的Node.js版本:

    1
    node -v

使用nvm,您可以轻松切换和使用不同版本的Node.js,从而在同一台机器上安装和管理多个版本。

解决nvm下载慢的问题

在nvm安装目录的settings.txt下添加配置项

node_mirror: https://npmmirror.com/mirrors/node/
npm_mirror: https://npmmirror.com/mirrors/npm/

使用fnm

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# layouts.download.codeBox.installsFnm
winget install Schniz.fnm

# layouts.download.codeBox.fnmEnvSetup
fnm env --use-on-cd | Out-String | Invoke-Expression

# layouts.download.codeBox.downloadAndInstallNodejs
fnm use --install-if-missing 18

# layouts.download.codeBox.verifiesRightNodejsVersion
node -v # layouts.download.codeBox.shouldPrint

# layouts.download.codeBox.verifiesRightNpmVersion
npm -v # layouts.download.codeBox.shouldPrint

洗牌算法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
function shuffle(array) {
let currentIndex = array.length;
let temporaryValue, randomIndex;

// 检查是否所有元素都已经处理过
while (0 !== currentIndex) {

// 随机选取一个元素
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;

// 交换元素
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}

return array;
}

// 使用示例
const myArray = [1, 2, 3, 4, 5];
const shuffledArray = shuffle(myArray);
console.log(shuffledArray); // 输出的顺序会因随机性而不同
1
2
3
4
5
6
7
8
9
const shuffle = (arr) => {
for(let i = 0;i < arr.length;i++){
let randomIndex = Math.floor(Math.random() * arr.length + 1)
if(randomIndex !== i)
[arr[i],arr[randIndex]]=[arr[randIndex],arr[i]]
}

return arr
}

js操作数组方法

js操作数组方法

  1. Array.map(function),map 方法用于遍历数组,并对数组中的每个元素执行提供的函数生成一个新的数组。原数组不变。
1
2
//示例:根据pets数组,每次执行函数返回pets每一项的url,返回一个只有url的新数组urls
let urls = pets.value.map(item => item.url)
  1. 遍历:Array.forEach(function),forEach 方法用于遍历数组,为数组中的每个元素执行一次提供的函数。原数组不变。
1
2
3
4
const numbers = [1, 2, 3, 4];
numbers.forEach((number, index) => {
console.log(`Index: ${index}, Value: ${number}`);
});

map和foreach的区别:

  1. forEach 没有返回值,总是返回 undefined;

  2. forEach 无法终止或跳出循环(除非抛出一个异常);

  3. map 返回一个新的数组,数组中的元素是原数组元素执行提供的函数后的结果;

  4. map因为返回数组所以可以链式操作,forEach不能;

  5. map 的速度大于forEach;

  1. Array.filter((item) => 条件),过滤数组中,符合条件的元素并返回一个新的数组。原数组不变。
1
2
3
var arr = [1, 2, 3, 4, 5]
var newArr = arr.filter(x => x>3);
//4,5
  1. Array.every((item) => 条件)对数组中的每一项进行判断,若都符合则返回true,否则返回false。原数组不变。

​ 应用场景:单选框全选后,全选框要自动选上。

Array.every((item) => item.selected === true),

  1. Array.find((item) => 条件),找到符合条件的那一项

    const item = cartList.value.find((item) => item.skuId === skuId)

  2. Array.findIndex( (item) => 条件),找到符合条件的下标

    const index = cartList.value.findIndex(item => skuId === item.skuId) //找到要删除的下标

  3. 累加:cartList.value.reduce((a,c)=>a+c.count,0),a为累加总数,c为cartList的每一项

  4. Array.includes(),判断数组中是否存在某个值

1
2
3
4
const numbers = [1, 2, 3, 4, 5]

console.log(numbers.includes(3)) // true
console.log(numbers.includes(6)) // false
  1. Array.slice(a,b),截取数组下标a到b的元素并返回一个新数组,原数组不变
1
2
3
const arr = ['a','b','c','d'];

console.log(arr.slice(1, 4));//只保存(从第一开始数(不包括第一个),数到第四个)// ["b", "c", "d"]
  1. Array.splice(a,b),从下标为a开始删除b个元素。原数组改变

push,pop,shift,unshift,sort

  • Copyrights © 2022-2024 CoffeeLin
  • Visitors: | Views:

请我喝杯咖啡吧~

支付宝
微信