python测试工程师 之 unittest框架总结

news2024/11/29 10:53:42

unittest

  • 学习目标
    • unittest 框架的基本使⽤⽅法(组成)
    • 断⾔的使⽤ (让程序⾃动的判断预期结果和实际结果是否相符)
    • 参数化(多个测试数据, 测试代码写⼀份 传参)
    • ⽣成测试报告
  • 复习python
  • unittest 框架的介绍
    • 核⼼要素(组成)
        • 1. TestCase 测试⽤例, 这个测试⽤例是 unittest 的组成部分,作⽤是 ⽤来书写真正的⽤例代码(脚本)
        • 2. Testsuite 测试套件, 作⽤是⽤来组装(打包)
        • 3. TestRunner 测试执⾏(测试运⾏), 作⽤ 是⽤例执⾏TestSuite(测试套件)的
        • 4. TestLoader 测试加载, 是对 TestSuite(测试套件) 功能的补充, 作⽤是⽤来组装(打包) TestCase(测试⽤例) 的
        • 5. Fixture 测试夹具, 是⼀种代码结构, 书写 前置⽅法(执⾏⽤例之前的⽅法)代码 和后置⽅法(执⾏⽤例之后的⽅法) 代码 ,即 ⽤例执⾏顺序 前置 ---> ⽤例 ---> 后置
  • TestCase 测试⽤例
  • TestSuite 和 TestRunner
    • TestSuite(测试套件)
    • TestRunner(测试执⾏)
    • 整体步骤
    • 代码案例
  • TestLoader 测试加载
  • 练习
    • TestLoader 练习
    • 练习 2
  • Fixture
    • ⽅法级别 Fixture
    • 类级别 Fixture
    • 模块级别Fixture(了解)
    • 登录练习
  • 断言
    • 练习
  • 参数化
    • 使用
    • 练习
  • 测试报告 HTMLTestReport
  • 获取当前路径
  • 案例
    • 测试的方法
    • 测试的数据
    • 读取测试数据
    • 测试用例代码
    • suit报告代码
  • 跳过

学习目标

unittest 框架的基本使⽤⽅法(组成)

断⾔的使⽤ (让程序⾃动的判断预期结果和实际结果是否相符)

参数化(多个测试数据, 测试代码写⼀份 传参)

⽣成测试报告

复习python

在这里插入图片描述

unittest 框架的介绍

什么是框架

  1. framework
  2. 为了解决⼀类事情的功能集合

Unittest 框架

是 Python ⾃带的单元测试框架

  • ⾃带的, 可以直接使⽤, 不需要单外安装
  • 测试⼈员 ⽤来做⾃动化测试, 作为⾃动化测试的执⾏框架,即 管理和执⾏⽤例的

核⼼要素(组成)

1. TestCase 测试⽤例, 这个测试⽤例是 unittest 的组成部分,作⽤是 ⽤来书写真正的⽤例代码(脚本)
2. Testsuite 测试套件, 作⽤是⽤来组装(打包)

TestCase(测试⽤例) 的,即 可以将多个⽤例脚本⽂件 组装到⼀起

3. TestRunner 测试执⾏(测试运⾏), 作⽤ 是⽤例执⾏TestSuite(测试套件)的
4. TestLoader 测试加载, 是对 TestSuite(测试套件) 功能的补充, 作⽤是⽤来组装(打包) TestCase(测试⽤例) 的
5. Fixture 测试夹具, 是⼀种代码结构, 书写 前置⽅法(执⾏⽤例之前的⽅法)代码 和后置⽅法(执⾏⽤例之后的⽅法) 代码 ,即 ⽤例执⾏顺序 前置 —> ⽤例 —> 后置

TestCase 测试⽤例

书写真正的⽤例代码(脚本)
单独⼀个测试⽤例 也是可以执⾏

  • 步骤
  1. 导包 unittest
  2. 定义测试类, 需要继承 unittest.TestCase 类, 习惯性类名以 Test 开头
  3. 书写测试⽅法, 必须以 test 开头
  4. 执⾏

注意事项

  1. 代码⽂件名字 要满⾜标识符的规则
  2. 代码⽂件名 不要使⽤中⽂
"""
学习 TestCase(测试用例) 的使用
"""

# 1. 导包 unittest
import unittest

# 2. 定义测试类, 只要继承 unittest.TestCase 类, 就是 测试类
class TestDemo(unittest.TestCase):
    # 3. 书写测试方法, 方法中的代码就是真正用例代码, 方法名必须以 test 开头
    def test_method1(self):
        print('测试方法一')

    def test_method2(self):
        print('测试方法二')

# 4. 执行
# 4.1 在类名或者方法名后边右键运行
# 4.1.1 在类名后边, 执行类中的所有的测试方法
# 4.1.2 在方法名后边, 只执行当前的测试方法

# 4.1 在主程序使用使用 unittest.main()  来执行,
if __name__ == '__main__':
    unittest.main()

TestSuite 和 TestRunner

TestSuite(测试套件)

将多条⽤例脚本集合在⼀起,就是套件, 即⽤来组装⽤例的

1. 导包 unittest
2. 实例化套件对象 unittest.TestSuite()
3. 添加⽤例⽅法

TestRunner(测试执⾏)

1. 导包 unittest
2. 实例化 执⾏对象 unittest.TextTestRunner()
3. 执⾏对象执⾏ 套件对象 执⾏对象.run(套件对象)

整体步骤

1. 导包 unittest
2. 实例化套件对象 unittest.TestSuite()
3. 添加⽤例⽅法
3.1 套件对象.addTest(测试类名('测试⽅法名'))
4. 实例化 执⾏对象 unittest.TextTestRunner()
5. 执⾏对象执⾏ 套件对象 执⾏对象.run(套件对象)

代码案例

# 1. 导包 unittest
import unittest
# 2. 定义测试类, 只要继承 unittest.TestCase 类, 就是测试类
class TestDemo1(unittest.TestCase):
	# 3. 书写测试⽅法, ⽅法中的代码就是真正⽤例代码,⽅法名必须以 test 开头
	def test_method1(self):
		print('测试⽅法1-1')
	def test_method2(self):
		print('测试⽅法1-2')
# 1. 导包  unittest
import unittest
from hm_02_testcase1 import TestDemo1
from hm_02_testcase2 import TestDemo2

# 2. 实例化套件对象 unittest.TestSuite()
suite = unittest.TestSuite()

# 3. 添加用例方法
# 3.1 套件对象.addTest(测试类名('测试方法名'))  # 建议复制
suite.addTest(TestDemo1('test_method1'))
suite.addTest(TestDemo1('test_method2'))
suite.addTest(TestDemo2('test_method1'))
suite.addTest(TestDemo2('test_method2'))
# 4. 实例化 执行对象 unittest.TextTestRunner()
runner = unittest.TextTestRunner()
# 5. 执行对象执行 套件对象 执行对象.run(套件对象)
runner.run(suite)

TestLoader 测试加载

作⽤和 TestSuite 作⽤⼀样,组装⽤例代码, 同样也需要使⽤TextTestRunner() 去执⾏
10 个⽤例脚本 makeSuite()

import unittest
# 实例化加载对象并加载⽤例,得到套件对象
# suite = unittest.TestLoader().discover('⽤例所在的⽬录', '⽤例代码⽂件名*.py')
suite = unittest.TestLoader().discover('.','hm_02*.py')
# 实例化执⾏对象并执⾏
# runner = unittest.TextTestRunner()
# runner.run(suite)
unittest.TextTestRunner().run(suite)

练习

TestLoader 练习

1. 创建⼀个⽬录 case, 作⽤就是⽤来存放⽤例脚本,
2. 在这个⽬录中创建 5 个⽤例代码⽂件 , test_case1.py...
3. 使⽤ TestLoader 去执⾏⽤例

将来的代码 ⽤例都是单独的⽬录 中存放的
test_项⽬_模块_功能.py

在这里插入图片描述

import unittest


class TestDemo(unittest.TestCase):
    def test_1(self):
        print('测试方法1')
import unittest


class TestDemo(unittest.TestCase):
    def test_1(self):
        print('测试方法2')
import unittest

suite = unittest.TestLoader().discover('case', 'test*.py')

unittest.TextTestRunner().run(suite)

练习 2

1. 定义⼀个 tools 模块, 在这个模块中 定义 add 的⽅法,可以对两个数字求和,返回求和结果
2. 书写⽤例, 对 add() 函数进⾏测试
1, 1, 2
1, 2, 3
3, 4, 7
4, 5, 9
-----
之前的测试⽅法,直接⼀个 print
这个案例中的 测试⽅法,调⽤ add 函数, 使⽤ if 判断,来判断
预期结果和实际结果是否相符
预期结果 2 3 7 9
实际结果 调⽤ add()
import unittest

from tools import add


class TestAdd(unittest.TestCase):
    def test_1(self):
        """1,1,2"""
        if 2 == add(1, 1):
            print(f'用例 {1}, {1}, {2}通过')
        else:
            print(f'用例 {1}, {1}, {2}不通过')

    def test_2(self):
        if 3 == add(1, 2):
            print(f'用例 {1}, {2}, {3}通过')
        else:
            print(f'用例 {1}, {2}, {3}不通过')

    def test_3(self):
        if 7 == add(3, 4):
            print(f'用例 {3}, {4}, {7}通过')
        else:
            print(f'用例 {3}, {4}, {7}不通过')

    def test_4(self):
        if 9 == add(4, 5):
            print(f'用例 {4}, {5}, {9}通过')
        else:
            print(f'用例 {4}, {5}, {9}不通过')

from hm_06_test_add import TestAdd

suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestAdd))

unittest.TextTestRunner().run(suite)

Fixture

代码结构, 在⽤例执⾏前后会⾃动执⾏的代码结构
tpshop 登录
1. 打开浏览器 (⼀次)
2. 打开⽹⻚,点击登录 (每次)
3. 输⼊⽤户名密码验证码1,点击登录 (每次, 测试⽅法)
4. 关闭⻚⾯ (每次)
2. 打开⽹⻚,点击登录 (每次)
3. 输⼊⽤户名密码验证码2,点击登录 (每次, 测试⽅法)
4. 关闭⻚⾯ (每次)
2. 打开⽹⻚,点击登录 (每次)
3. 输⼊⽤户名密码验证码3,点击登录 (每次, 测试⽅法)
4. 关闭⻚⾯ (每次)
5. 关闭浏览器 (⼀次)

⽅法级别 Fixture

在每个⽤例执⾏前后都会⾃动调⽤, ⽅法名是固定的

def setUp(self): # 前置
 # 每个⽤例执⾏之前都会⾃动调⽤
 pass
def tearDown(self): # 后置
 # 每个⽤例执⾏之后 都会⾃动调⽤
 pass
# ⽅法前置 ⽤例 ⽅法后置
# ⽅法前置 ⽤例 ⽅法后置

类级别 Fixture

在类中所有的测试⽅法执⾏前后 会⾃动执⾏的代码, 只执⾏⼀次

# 类级别的 Fixture 需要写作类⽅法
@classmethod
def setUpClass(cls): # 类前置
 pass
@classmethod
def tearDownClass(cls): # 后置
 pass
# 类前置 ⽅法前置 ⽤例 ⽅法后置 ⽅法前置 ⽤例 ⽅法后置类后置

模块级别Fixture(了解)

模块, 就是代码⽂件
模块级别 在这个代码⽂件执⾏前后执⾏⼀次

# 在类外部定义函数
def setUpModule():
 pass
def tearDownModule():
 pass

登录练习

import unittest


class TestLogin(unittest.TestCase):
    def setUp(self) -> None:
        print('2. 打开网页, 点击登录')

    def tearDown(self) -> None:
        print('4. 关闭网页')

    @classmethod
    def setUpClass(cls) -> None:
        print('1. 打开浏览器')

    @classmethod
    def tearDownClass(cls) -> None:
        print('5. 关闭浏览器')

    def test_1(self):
        print('3. 输入用户名密码验证码1,点击登录 ')

    def test_2(self):
        print('3. 输入用户名密码验证码2,点击登录 ')

    def test_3(self):
        print('3. 输入用户名密码验证码3,点击登录 ')

断言

使用代码自动的判断预期结果和实际结果是否相符
assertEqual(预期结果,实际结果)
- 判断预期结果和实际结果是否相等,如果相等, 用例通过,如果不相等,抛出异常, 用例不通过
assertIn(预期结果,实际结果)
- 判断预期结果是否包含在 实际结果中, 如果存在,用例通过, 如果不存在,抛出异常,用例不通过
class TestAssert(unittest.TestCase):
    def test_equal_1(self):
        self.assertEqual(10, 10)  # 用例通过

    def test_assert_2(self):
        self.assertEqual(10, 11)  # 用例不通过

    def test_in(self):
        # self.assertIn('admin', '欢迎 admin 登录')  # 包含 通过
        # self.assertIn('admin', '欢迎 adminnnnnnnn 登录')  # 包含 通过
        # self.assertIn('admin', '欢迎 aaaaaadminnnnnnnn 登录')  # 包含 通过
        # self.assertIn('admin', '欢迎 adddddmin 登录')  # 不包含 不通过
        self.assertIn('admin', 'admin')  # 包含 通过
from hm_02_assert import TestAssert

suite = unittest.TestSuite()

suite.addTest(unittest.makeSuite(TestAssert))
unittest.TextTestRunner().run(suite)

练习

1. 定义一个 tools 模块, 在这个模块中 定义 add 的方法,可以对两个数字求和,返回求和结果
2. 书写用例, 对 add() 函数进行测试
1, 1, 2
1, 2, 3
3, 4, 7
4, 5, 9
class TestAdd(unittest.TestCase):
    def test_1(self):
        self.assertEqual(2, add(1, 1))

    def test_2(self):
        self.assertEqual(3, add(1, 2))

    def test_3(self):
        self.assertEqual(7, add(3, 4))

    def test_4(self):
        self.assertEqual(9, add(4, 5))

参数化

  • 通过参数的方式来传递数据,从而实现数据和脚本分离。并且可以实现用例的重复执行。(在书写用例方法的时候,测试数据使用变量代替,在执行的时候进行据说传递)
  • unittest 测试框架,本身不支持参数化,但是可以通过安装unittest扩展插 件 parameterized 来实现。

环境准备

因为参数化的插件 不是 unittest 自带的,所以想要使用 需要进行安装
Python 中 包(插件,模块) 的安装,使用 pip 工具
pip install parameterized
pip install -i https://pypi.douban.com/simple/ parameterized
# 在终端(cmd)中执行

使用

1. 导包 from para... import para...
2. 修改测试方法,将测试方法中的测试数据使用 变量表示
3. 组织测试数据,格式 [(), (), ()], 一个元组就是一组测试数据
4. 参数化,在测试方法上方使用装饰器 @parameterized.expand(测试数据)
5. 运行(直接 TestCase 或者 使用 suite 运行)
import unittest

from tools import add
from parameterized import parameterized

data = [(1, 1, 2), (1, 2, 3), (2, 3, 5), (4, 5, 9)]


class TestAdd(unittest.TestCase):
    @parameterized.expand(data)
    def test_add(self, a, b, expect):
        print(f'a:{a}, b:{b}, expect:{expect}')
        self.assertEqual(expect, add(a, b))


if __name__ == '__main__':
    unittest.main()

练习

将测试数据 定义为 json 文件, 读取 json 文件,完成参数化

json 文件

[
  [1, 1, 2],
  [1, 2, 3],
  [2, 3, 5],
  [4, 5, 9],
  [10, 20, 30]
]

读取 json 文件

import json
from app import BASE_DIR

def build_add_data():
    with open('../data/add_data.json') as f:
        data = json.load(f)  # [[], [], []]  ---> [(), ()]

    return data


def build_add_data_1():
    with open('../data/add_data_1.json') as f:
        data_list = json.load(f)  # [{}, {}, {}]  ----> [(), ()]

        new_list = []
        for data in data_list:  # data 字典
            # 字典中的值,是否都需要
            a = data.get('a')
            b = data.get('b')
            expect = data.get('expect')
            new_list.append((a, b, expect))

        return new_list


def build_add_data_2():
    with open(BASE_DIR + '/data/add_data_1.json') as f:
        data_list = json.load(f)  # [{}, {}, {}]  ----> [(), ()]

        new_list = []
        for data in data_list:  # data 字典
            # 字典中的值,是否都需要
            new_list.append(tuple(data.values()))

        return new_list


def build_login_data():
    with open(BASE_DIR + '/data/login_data.json', encoding='utf-8') as f:
        data_list = json.load(f)  # [{}, {}] ---> [()]
        new_list = []
        for data in data_list:
            # 字典中的 desc 不需要
            username = data.get('username')
            password = data.get('password')
            expect = data.get('expect')
            new_list.append((username, password, expect))

        return new_list


if __name__ == '__main__':
    # print(build_add_data_2())
    print(build_login_data())
import unittest

from common.read_data import build_add_data_2
from tools import add
from parameterized import parameterized

data = [(1, 1, 2), (1, 2, 3), (2, 3, 5), (4, 5, 9)]


class TestAdd(unittest.TestCase):
    # @parameterized.expand(build_add_data())
    # @parameterized.expand(build_add_data_1())
    @parameterized.expand(build_add_data_2())
    def test_add(self, a, b, expect):
        print(f'a:{a}, b:{b}, expect:{expect}')
        self.assertEqual(expect, add(a, b))


if __name__ == '__main__':
    unittest.main()

测试报告 HTMLTestReport

使用第三方的报告模版,生成报告 HTMLTestReport, 本质是 TestRunner
- 安装
pip install -i https://pypi.douban.com/simple/ HTMLTestReport
- 使用
1. 导包 unittest、HTMLTestReport
2. 组装用例(套件, loader )
3. 使用 HTMLTestReport 中的 runner 执行套件
4. 查看报告
import unittest

from htmltestreport import HTMLTestReport
from hm_04_pa1 import TestAdd

# 套件

suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestAdd))

# 运行对象
# runner = HTMLTestReport(报告的文件路径后缀.html, 报告的标题, 其他的描述信息)
# runner = HTMLTestReport('test_add_report.html', '加法用例测试报告', 'xxx')
# runner = HTMLTestReport('./report/test_add_report.html', '加法用例测试报告', 'xxx')
runner = HTMLTestReport('report/test_add_report.html', '加法用例测试报告', 'xxx')
runner.run(suite)

使用绝对路径

将来的项目是分目录书写的, 使用相对路径,可能会出现找不到文件的情况,此时需要使用 绝对路径
方法:
1. 在项目的根目录,创建一个 Python 文件(app.py 或者 config.py)
2. 在这个文件中 获取项目的目录,在其他代码中使用 路径拼接完成绝对路径的书写

获取当前路径

在这里插入图片描述

import os

# __file__ 特殊的变量,表示当前代码文件名
# path1 = os.path.abspath(__file__)
# print(path1)
# path2 = os.path.dirname(path1)
# print(path2)

# BASE_DIR = os.path.dirname(os.path.abspath(__file__))
BASE_DIR = os.path.dirname(__file__)


if __name__ == '__main__':
    print(BASE_DIR)

案例

1, 对登录函数进行测试, 登录函数 定义在 tools.py 中
2, 在 case 目录中书写用例对login 函数进行测试, 使用断言
3, 将 login 函数的测试数据定义在 json 文件中,完成参数化, data 目录中
4, 生成测试报告 report 目录中

测试的方法

def login(username, password):
    if username == 'admin' and password == '123456':
        return '登录成功'
    else:
        return '登录失败'


def add(a, b):
    return a + b


测试的数据

[
  {
    "desc": "正确的用户名和密码",
    "username": "admin",
    "password": "123456",
    "expect": "登录成功"
  },
  {
    "desc": "错误的用户名",
    "username": "root",
    "password": "123456",
    "expect": "登录失败"
  },
  {
    "desc": "错误的密码",
    "username": "admin",
    "password": "123123",
    "expect": "登录失败"
  },
  {
    "desc": "错误的用户名和密码",
    "username": "root",
    "password": "123123",
    "expect": "登录失败"
  }
]

读取测试数据

def build_login_data():
    with open(BASE_DIR + '/data/login_data.json', encoding='utf-8') as f:
        data_list = json.load(f)  # [{}, {}] ---> [()]
        new_list = []
        for data in data_list:
            # 字典中的 desc 不需要
            username = data.get('username')
            password = data.get('password')
            expect = data.get('expect')
            new_list.append((username, password, expect))

        return new_list

测试用例代码

import unittest

from common.read_data import build_login_data
from tools import login
from parameterized import parameterized


class TestLogin(unittest.TestCase):
    @parameterized.expand(build_login_data())
    def test_login(self, username, password, expect):
        print(f'username: {username}, password: {password}, expect: {expect}')
        self.assertEqual(expect, login(username, password))

suit报告代码

import unittest

from app import BASE_DIR
from case.test_login import TestLogin
from htmltestreport import HTMLTestReport

suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestLogin))

runner = HTMLTestReport(BASE_DIR + '/report/login_report.html', '登录测试报告', 'V1.0')
runner.run(suite)

跳过

跳过:对于一些未完成的或者不满足测试条件的测试函数和测试类,可以跳过执行(简单来说, 不想执行的测试方法,可以
设置为跳过)
- 直接将测试函数标记成跳过
@unittest.skip('跳过的原因')
- 根据条件判断测试函数是否跳过
@unittest.skipIf(判断条件, reason='原因') # 判断条件为 True, 执行跳过
class TestSkip(unittest.TestCase):
    @unittest.skip('没什么原因,就是不想执行')
    def test_1(self):
        print('方法一')

    @unittest.skipIf(version >= 30, '版本号大于等于 30, 测方法不用执行')
    def test_2(self):
        print('方法二')

    def test_3(self):
        print('方法三')


if __name__ == '__main__':
    unittest.main()
import unittest

from hm_06_skip import TestSkip

suite = unittest.TestSuite()
suite.addTest(unittest.makeSuite(TestSkip))

unittest.TextTestRunner().run(suite)

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

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

相关文章

2024亚马逊Prime Day备战攻略:卖家要做好这些准备!

2024年的Prime Day是亚马逊的第十个会员日,对卖家而言,Prime Day不仅仅是一次简单的促销活动,更是一个可以提升销售业绩、增强品牌影响力并加深与消费者关系的黄金机会。肯定还有不少卖家在为活动做准备,今天就为大家准备了一份全…

奔驰EQS SUV升级原厂主动式氛围灯效果展示

以下是一篇关于奔驰 EQs 升级原厂主动氛围灯案例的宣传文案: 在汽车科技不断演进的今天,我们自豪地为您呈现奔驰 EQs 升级原厂主动氛围灯的精彩案例。 奔驰 EQs,作为豪华电动汽车的典范,其卓越品质与高端性能有目共睹。而此次升…

ADC + 数码管显示

REVIEW 前面已经学习过: ADC:ADC模-数转换原理与实现-CSDN博客 key:基于状态机的按键消抖实现-CSDN博客 数码管:SPI接口的74HC595驱动数码管实现_用spi和hc74595通信-CSDN博客 1. 今日摸鱼计划 按键启动ADC 将结果显示在数码管…

Reddit、Discord等社媒网站抓取总结:如何更高效实现网页抓取?

有效的网络抓取需要采取战略方法来克服挑战并确保最佳数据提取。让我们深入研究一些关键实践,这些实践将使您能够掌握复杂的网络抓取。 一、了解 Web 抓取检测 在深入探讨最佳实践之前,让我们先了解一下网站如何识别和抵御网络爬虫。了解您在这一过程中…

2024.6.23周报

目录 摘要 ABSTRACT 一、文献阅读 一、题目 二、摘要 三、网络架构 四、创新点 五、文章解读 1、Introduction 2、Method 3、实验 4、结论 二、代码实验 总结 摘要 本周阅读了一篇题目为NAS-PINN: NEURAL ARCHITECTURE SEARCH-GUIDED PHYSICS-INFORMED NEURAL N…

【vLLM】核心技术PagedAttention,调度原理

vLLM 简介 来自加州大学伯克利分校、斯坦福大学、加州大学圣迭戈分校的研究人员基于操作系统中经典的虚拟(Virtual)内存和分页(Page)技术,提出了一个新的注意力算法 PagedAttention,并打造了一个LLM服务系统——vLLM,官网为:http…

OS复习笔记ch11-4

磁盘调度 磁盘的物理结构 经典的温彻斯特盘 其中的几个概念: 盘面:可以看成是一个操场的平面,不同的盘面通过中间的轴串在一起磁道:磁道可以看成是操场的跑道,我们知道操场上有外道和内道,最内道中间往…

【FlowShop流水线作业排班问题【数学规划的应用(含代码)】阿里达摩院MindOpt】

本文主要讲述使用MindOpt工具优化FlowShop流水线作业排班的数学规划问题。 一、案例场景 FlowShop流水线作业排班也有称为生产下料问题,它涉及到多台机器、多个工序以及多个作业调度安排。在这个问题中,我们需要对多个作业在一组流水线上的处理顺序进行…

矩阵中严格递增的单元格数

题目链接:leetcode:矩阵中严格递增的单元格数 描述 给你一个下标从 1 开始、大小为 m x n 的整数矩阵 mat,你可以选择任一单元格作为 起始单元格 。 从起始单元格出发,你可以移动到 同一行或同一列 中的任何其他单元格,但前提是目…

修复kazam意外中断的视频文件

0. Problem 在用kazam录视频的过程中,PC意外重启了,然后kazam没有把文件自动转换成MP4,而是存为以下两个文件: kazam_xxxxx.movie kazam-xxxxx.movie.mux这两个文件一个0k,另一个是有size的,但是没办法直…

[SAP ABAP] 变量与常量

1.变量 定义变量的基本方式 DATA <name> TYPE <type> [VALUE <val>]. <name>&#xff1a;指定变量的名称 <type>&#xff1a;指定变量的数据类型 <val>&#xff1a;指定<name>的初始值 示例1 定义变量lv_data1和lv_data3 输出结果…

【CMake】CMake从入门到实战系列(十七)—— CMake添加环境检查

&#x1f525;博客简介&#xff1a;开了几个专栏&#xff0c;针对 Linux 和 rtos 系统&#xff0c;嵌入式开发和音视频开发&#xff0c;结合多年工作经验&#xff0c;跟大家分享交流嵌入式软硬件技术、音视频技术的干货。   ✍️系列专栏&#xff1a;C/C、Linux、rtos、嵌入式…

【C语言】16.动态内存管理

文章目录 1.为什么要有动态内存分配2.malloc和free2.1 malloc2.2 free 3.calloc和realloc3.1 calloc3.2 realloc 4.常见的动态内存的错误4.1 对NULL指针的解引⽤操作4.2 对动态开辟空间的越界访问4.3 对⾮动态开辟内存使⽤free释放4.4 使⽤free释放⼀块动态开辟内存的⼀部分4.5…

redis高可用-集群部署

一&#xff1a;背景 前面我们实现了redis的主从同步和哨兵模式&#xff0c;解决了单机redis的故障转移和流量分担&#xff0c;但是不管是主从或者哨兵模式都是一个主服务对应一个或者多个从服务&#xff0c;并且主服务和从服务的数据是一样的&#xff0c;这样就实现不了redis大…

JSP基础知识概述

目录 JSP一、什么是JSP1.1 概念1.2 创建JSP1.3 JSP编写Java代码1.4 JSP实现原理 二、JSP与HTML集成2.1 普通脚本2.2 声明脚本2.3 输出脚本2.4 JSP指令2.5 动作标签 三、内置对象3.1 四大域对象 JSP 一、什么是JSP 1.1 概念 简化的Servlet设计&#xff0c;在HTMl标签中嵌套Jav…

Python学习打卡:day12

day12 笔记来源于&#xff1a;黑马程序员python教程&#xff0c;8天python从入门到精通&#xff0c;学python看这套就够了 目录 day1292、全国疫情地图构建数据整理获取数据数据整体结构&#xff08;全国&#xff09;省数据结构获取每个省份的确诊数据上述代码执行后输出&…

Homebrew使用

官网&#xff1a;https://brew.sh/ 安装&#xff1a; 简介&#xff1a;https://www.jianshu.com/p/f4c9cf0733ea 比如&#xff0c;安装maven: 1、brew install maven 2、查看安装路径&#xff1a;brew list maven 具体参考&#xff1a;https://blog.csdn.net/m0_67402970/arti…

创业众筹网

摘 要 创业是社会经济发展的重要动力&#xff0c;其在任何经济发展时期任何国家都最具活力与桃战性。然而创业的资金却是90%创业者面临的首要问题。包括积蓄不足、无不动产、负债、不知如何向银行申贷,及无法预估所创行业之总资金、成本。部分创业者虽然有心创业&#xff0c;但…

Python学习笔记16:进阶篇(五)异常处理

异常 在编程中&#xff0c;异常是指程序运行过程中发生的意外事件&#xff0c;这些事件通常中断了正常的指令流程。它们可能是由于错误的输入数据、资源不足、非法操作或其他未预料到的情况引起的。Python中&#xff0c;当遇到这类情况时&#xff0c;会抛出一个异常对象&#…

抖音开放平台代开发小程序,上传模板代码

大家好&#xff0c;我是小悟 抖音小程序第三方平台开发着力于解决抖音生态体系内的小程序管理问题&#xff0c;一套模板&#xff0c;随处部署。能尽可能地减少服务商的开发成本&#xff0c;服务商只用开发一套小程序代码作为模板就可以快速批量的孵化出大量的商家小程序。 第…