【unittest学习】unittest框架主要功能

news2025/7/28 2:06:55

1.认识unittest

在 Python 中有诸多单元测试框架,如 doctest、unittest、pytest、nose 等,Python 2.1 及

其以后的版本已经将 unittest 作为一个标准模块放入 Python 开发包中。

2.认识单元测试

不用单元测试框架能写单元测试吗?答案是肯定的。单元测试本质上就是通过一段代

码去验证另外一段代码,所以不用单元测试框架也可以写单元测试。下面就通过例子演示。

创建一个被测试文件 calculator.py。

# _*_ coding:utf-8 _*_
"""
name:zhangxingzai
date:2023/2/22
"""


# 创建一个计算器类
class Calculator:
    """ 用于完成两个数的加、减、乘、除 """

    def __init__(self, a, b):
        self.a = int(a)
        self.b = int(b)

    # 加法
    def add(self):
        return self.a + self.b

    # 减法
    def sub(self):
        return self.a - self.b

    # 乘法
    def mul(self):
        return self.a * self.b

    # 除法
    def div(self):
        return self.a / self.b

程序非常简单,创建一个 Calculator 类,通过__init__()方法接收两个参数,并做 int 类

型转换。创建 add()、sub()、mul()、div()方法分别进行加、减、乘、除运算。

根据上面实现的功能,创建 test_calculator.py 文件。

# _*_ coding:utf-8 _*_
"""
name:zhangxingzai
date:2023/2/22
"""

from calculator import Calculator


def test_add():
    c = Calculator(3, 6)
    result = c.add()
    assert result == 9, '加法运算失败!'


def test_sub():
    c = Calculator(7, 2)
    result = c.sub()
    assert result == 5, '减法运算失败!'


def test_mul():
    c = Calculator(3, 3)
    result = c.mul()
    assert result == 10, '乘法运算失败!'


def test_div():
    c = Calculator(6, 2)
    result = c.div()
    assert result == 3, '除法运算失败!'


if __name__ == '__main__':
    test_add()
    test_sub()
    test_mul()
    test_div()

运行结果如下:

在测试代码中,首先引入 calculator 文件中的 Calculator 类,并对测试数据进行初始化。

接下来调用该类下面的方法,得到计算结果,并断言结果是否正确。

这样的测试存在着一些问题。首先,我们需要自己定义断言失败的提示;其次,当一

个测试函数运行失败后,后面的测试函数将不再执行;最后,执行结果无法统计。

当然,我们可以通过编写更多的代码来解决这些问题,但这就偏离了我们做单元测试

的初衷。我们应该将重点放在测试本身,而不是其他上面。引入单元测试框架可以很好地

解决这些问题。

下面通过 unittest 单元测试框架重新编写测试用例:

import unittest
from calculator import Calculator


class TestCalculator(unittest.TestCase):

    def test_add(self):
        c = Calculator(3, 6)
        result = c.add()
        self.assertEqual(result, 9)

    def test_sub(self):
        c = Calculator(7, 2)
        result = c.sub()
        self.assertEqual(result, 5)

    def test_mul(self):
        c = Calculator(3, 3)
        result = c.mul()
        self.assertEqual(result, 10)

    def test_div(self):
        c = Calculator(6, 2)
        result = c.div()
        self.assertEqual(result, 3)


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

运行结果如下:

引入 unittest 模块。如果想用 unittest 编写测试用例,那么一定要遵守它的“规则”。

(1)创建一个测试类,这里为 TestCalculator 类,必须要继承 unittest 模块的 TestCase

类。

(2)创建一个测试方法,该方法必须以“test”开头。

接下来的测试步骤与前面测试代码相同。

首先,调用被测试类,传入初始化数据。

其次,调用被测试方法,得到计算结果。通过 unittest 提供的 assertEqual()方法来断言

结果是否与预期结果相同。该方法由 TestCase 父类提供,由于继承了该类,所以可以通过

self 调用。

最后,调用 unittest 的 main()来执行测试用例,它会按照前面的两条规则查找测试用例

并执行。

3.unittest重要的概念

unittest 文档中有四个重要的概念:Test Case、Test Suite、Test Runner 和 Test Fixture。只有理解了这几个概念,才能理解单元测试的基本特征。

1.Test Case

Test Case 是最小的测试单元,用于检查特定输入集合的特定返回值。unittest 提供了

TestCase 基类,我们创建的测试类需要继承该基类,它可以用来创建新的测试用例。

2.Test Suite

测试套件是测试用例、测试套件或两者的集合,用于组装一组要运行的测试。unittest

提供了 TestSuite 类来创建测试套件。

3.Test Runner

Test Runner 是一个组件,用于协调测试的执行并向用户提供结果。Test Runner 可以使

用图形界面、文本界面或返回特殊值来展示执行测试的结果。

unittest 提供了 TextTestRunner类运行测试用例,为了生成 HTML 格式的测试报告,后面会选择使用 HTMLTestRunner 运行类。

4.Test Fixture

Test Fixture 代表执行一个或多个测试所需的环境准备,以及关联的清理动作。例如,

创建临时或代理数据库、目录,或启动服务器进程。unittest 中提供了 setUp()/tearDown()、

setUpClass()/tearDownClass()等方法来完成这些操作。

在理解了上面几个概念之后,我们对前面的测试用例做如下修改:

import unittest
from calculator import Calculator

class TestCalculator(unittest.TestCase):

    # 测试用例前置动作
    def setUp(self):
        print("test start:")

    # 测试用例后置动作
    def tearDown(self):
        print("test end")

    def test_add(self):
        c = Calculator(3, 5)
        result = c.add()
        self.assertEqual(result, 8)

    def test_sub(self):
        c = Calculator(7, 2)
        result = c.sub()
        self.assertEqual(result, 5)

    def test_mul(self):
        c = Calculator(3, 3)
        result = c.mul()
        self.assertEqual(result, 10)

    def test_div(self):
        c = Calculator(6, 2)
        result = c.div()
        self.assertEqual(result, 3)

if __name__ == '__main__':
    # 创建测试套件
    suit = unittest.TestSuite
    suit.addTest(TestCalculator('test_add'))
    suit.addTest(TestCalculator("test_sub"))
    suit.addTest(TestCalculator("test_mul"))
    suit.addTest(TestCalculator("test_div"))

    # 创建测试运行器
    runner = unittest.TextTestRunner()
    runner.run(suit)

首先,创建一个测试类并继承 TestCase 类,在该类下面创建一条以“test”开头的方法

为测试用例。这个前面已有说明,这里再次说明是为了强调它的重要性。

其次,在测试类中增加了 setUp()/tearDown()方法,用于定义测试用例的前置和后置动

作。因为在当前测试中暂时用不上,所以这里定义了一些简单的打印。

接下来,是测试用例的执行,这里做了很大的改动。首先,抛弃了 unittest 提供的 main()

方法,而是调用 TestSuite 类下面的 addTest()来添加测试用例。因为一次只能添加一条用例,

所以需要指定测试类及测试方法。然后,再调用 TextTestRunner 类下面的 run()运行测试套

这样做确实比直接使用 main()方法要麻烦得多,但也并非没有优点。

首先,测试用例的执行顺序可以由测试套件的添加顺序控制,而 main()方法只能按照

测试类、方法的名称来执行测试用例。例如,TestA 类比 TestB 类先执行,test_add()用例比

test_div()用例先执行。

其次,当一个测试文件中有很多测试用例时,并不是每次都要执行所有的测试用例,

尤其是比较耗时的 UI 自动化测试。因而通过测试套件和测试运行器可以灵活地控制要执行

的测试用例。

执行结果如下:

test start:
test end
test start:
test end
test start:
test end

Ran 4 tests in 0.013s
FAILED (failures=1)
10 != 9
预期:9
实际:10
<点击以查看差异>

Traceback (most recent call last):
  File "C:\Users\Administrator\PycharmProjects\AutoFunction\test_calculator.py", line 28, in test_mul
    self.assertEqual(result, 10)
AssertionError: 9 != 10

test start:
test end

从执行结果可以看到,setUp/tearDown 作用于每条测试用例的开始之处与结束之处。

4.断言方法

在执行测试用例的过程中,最终测试用例执行成功与否,是通过测试得到的实际结果

与预期结果进行比较得到的。unittest 框架的 TestCase 类提供的用于测试结果的断言方法如

下表所示。

断言方法的使用如下所示:

# _*_ coding:utf-8 _*_

import unittest

class TestAssert(unittest.TestCase):
    def test_equal(self):
        self.assertEqual(2 + 2, 4)
        self.assertEqual("python", "python")
        self.assertNotEqual("hello", "python")

    def test_in(self):
        self.assertIn("hello", "hello world")
        self.assertNotIn("hi", "hello")

    def test_true(self):
        self.assertTrue(True)
        self.assertFalse(False)


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

运行上面的测试用例,即可通过测试结果推断出这些断言方法是如何使用的。

5.测试用例的组织与 discover 方法

我们可以在一个测试文件中定义多个测试类,只要它们遵循测试用例的“规则”,main()

方法就可以找到并执行它们。但是,我们要测试的类或方法可能有很多。

下面开发一个功能,用于判断某年是否为闰年。创建 leap_year.py 文件。

# _*_ coding:utf-8 _*_
"""
name:zhangxingzai
date:2023/2/23
"""


class LeapYear:
    """计算某年是否为闰年"""

    def __init__(self, year):
        self.year = int(year)

    def answer(self):
        year = self.year
        if year % 100 == 0:
            if year % 400 == 0:  # 整百年能被 400 整除的是闰年
                return "{0}是闰年".format(year)
            else:
                return "{0}不是闰年".format(year)
        else:
            if year % 4 == 0:  # 非整百年能被 4 整除的是闰年
                return "{0}是闰年".format(year)
            else:
                return "{0}不是闰年".format(year)

创建对应的测试文件 test_leap_year.py

# _*_ coding:utf-8 _*_
"""
name:zhangxingzai
date:2023/2/23
"""
import unittest
from leap_year import LeapYear


class TestLeapYear(unittest.TestCase):
    def test_2000(self):
        ly = LeapYear(2000)
        self.assertEqual(ly.answer(), "2000是闰年")

    def test_2004(self):
        ly = LeapYear(2004)
        self.assertEqual(ly.answer(), "2004是闰年")

    def test_2017(self):
        ly = LeapYear(2017)
        self.assertEqual(ly.answer(), "2017不是闰年")

    def test_2100(self):
        ly = LeapYear(2100)
        self.assertEqual(ly.answer(), "2100不是闰年")


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

显然,这里的判断闰年功能(leap_year.py)和计算器功能(calculator.py)并不相关,

它们的代码分别写在两个文件当中,所以对应的测试用例最好分开,分别为test_calculator.py

和 test_leap_year.py。

当前目录结构如下:

如何执行多个测试文件呢?unittest中的TestLoader类提供的discover()方法可以从多个

文件中查找测试用例。

该类根据各种标准加载测试用例,并将它们返回给测试套件。正常情况下,不需要创

建这个类的实例。unittest 提供了可以共享的 defaultTestLoader 类,可以使用其子类或方法

创建实例,discover()方法就是其中之一。

discover(start_dir,pattern='test*.py',top_level_dir=None)

找到指定目录及其子目录下的所有测试模块,只有匹配的文件名才能被加载。如果启

动的不是顶层目录,那么顶层目录必须单独指定。

  • start_dir :待测试的模块名或测试用例目录。

  • pattern='test*.py' :测试用例文件名的匹配原则。此处匹配文件名以“test”开头

的“.py”类型的文件,星号“*”表示任意多个字符。

  • top_level_dir=None:测试模块的顶层目录,如果没有顶层目录,则默认为 None。

现在通过 discover()方法重新实现 run_tests.py 文件的功能。

import unittest
# 定义测试用例的目录为当前目录中的AutoFunction/目录
test_dir = './AutoFunction'
suits = unittest.defaultTestLoader.discover(test_dir, pattern='test*.py')
if __name__ == '__main__':
 runner = unittest.TextTestRunner()
 runner.run(suits)

discover()方法会自动根据测试用例目录(test_dir)查找测试用例文件(test*.py),并

将找到的测试用例添加到测试套件中,因此,可以直接通过 run()方法执行测试套件 suits。

这种方式极大地简化了测试用例的查找,我们需要做的就是按照文件的匹配规则创建测试

文件即可。

6.测试用例的执行顺序

测试用例的执行顺序涉及多个层级:多个测试目录 > 多个测试文件 > 多个测试类 >

多个测试方法(测试用例)。unittest 提供的 main()方法和 discover()方法是按照什么顺序查

找测试用例的呢?

我们先运行一个例子,再解释 unittest 的执行策略。

# _*_ coding:utf-8 _*_
"""
name:zhangxingzai
date:date:2023/2/23
"""

import unittest


class TestBdd(unittest.TestCase):

    def setUp(self):
        print('test TestBdd:')

    def test_ccc(self):
        print('test ccc')

    def test_aaa(self):
        print('test aaa')


class TestAdd(unittest.TestCase):

    def setUp(self):
        print("test TestAdd:")

    def test_bbb(self):
        print("test bbb")


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

执行结果如下:

无论执行多少次,结果都是一样的。通过上面的结果,相信你已经找到 main()方法执

行测试用例的规律了。

因为unittest默认根据ASCII码的顺序加载测试用例的(数字与字母的顺序为0~9,A~Z,

a~z),所以 TestAdd 类会优先于 TestBdd 类被执行,test_aaa()方法会优先于 test_ccc()方法

被执行,也就是说,它并不是按照测试用例的创建顺序从上到下执行的。

discover()方法和 main()方法的执行顺序是一样的。对于测试目录与测试文件来说,上

面的规律同样适用。test_aaa.py 文件会优先于 test_bbb.py 文件被执行。所以,如果想让某

个测试文件先执行,可以在命名上加以控制。

除命名外,有没有其他办法控制测试用例的执行顺序呢?答案是肯定的,前面也有介

绍,我们可以声明测试套件 TestSuite 类,通过 addTest()方法按照一定的顺序来加载测试用

例。

修改上面的例子如下:

# _*_ coding:utf-8 _*_
"""
name:zhangxingzai
date:date:2023/2/23
"""

import unittest


class TestBdd(unittest.TestCase):

    def setUp(self):
        print('test TestBdd:')

    def test_ccc(self):
        print('test ccc')

    def test_aaa(self):
        print('test aaa')


class TestAdd(unittest.TestCase):

    def setUp(self):
        print("test TestAdd:")

    def test_bbb(self):
        print("test bbb")


if __name__ == '__main__':
    # 构造测试集
    suite = unittest.TestSuite()
    suite.addTest(TestBdd("test_aaa"))
    suite.addTest(TestAdd("test_bbb"))
    suite.addTest(TestBdd("test_ccc"))

    # 执行测试
    runner = unittest.TextTestRunner()
    runner.run(suite)

执行结果如下:

现在的执行顺序与 addTest()方法加载测试用例的顺序相同。不过,当测试用例非常多

时,不推荐用这种方法创建测试套件,原因前面也有说明,最好的方法是通过命名控制执

行顺序。如果测试用例在设计时不产生相互依赖,那么测试用例的执行顺序就没那么重要

了。

7.跳过测试和预期失败

在运行测试时,有时需要直接跳过某些测试用例,或者当测试用例符合某个条件时跳

过测试,又或者直接将测试用例设置为失败。unittest 提供了实现这些需求的装饰器。

无条件地跳过装饰的测试,需要说明跳过测试的原因:

unittest.skip(reason) 

如果条件为真,则跳过装饰的测试:

unittest.skipIf(condition, reason)

当条件为真时,执行装饰的测试:

unittest.skipUnless(condition, reason)

不管执行结果是否失败,都将测试标记为失败:

unittest.expectedFailure()

举例如下:

import unittest


class MyTest(unittest.TestCase):
    @unittest.skip("直接跳过测试")
    def test_skip(self):
        print("test aaa")

    @unittest.skipIf(3 > 2, "当条件为真时跳过测试")
    def test_skip_if(self):
        print('test bbb')

    @unittest.skipUnless(3 > 2, "当条件为真时执行测试")
    def test_skip_unless(self):
        print('test ccc')

    @unittest.expectedFailure
    def test_expected_failure(self):
        self.assertEqual(2, 3)


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

执行结果如下:

Skipped: 直接跳过测试
Skipped: 当条件为真时跳过测试
test ccc
Ran 4 tests in 0.010s
OK (skipped=2, expected failures=1)

上面的例子创建了四条测试用例。

第一条测试用例通过@unittest.skip()装饰,直接跳过测试。

第二条测试用例通过@unittest.skipIf()装饰,当条件为真时跳过测试;3>2 条件为真

(True),所以跳过测试。

第三条测试用例通过@unittest.skipUnless()装饰,当条件为真时执行测试;3>2 条件为

真(True),执行测试。

第四条测试用例通过@unittest.expectedFailure 装饰,不管执行结果是否失败,都将测

试标记为失败,但不会抛出失败信息。

8.Fixtuer(测试夹具)

我们可以把 Fixture 看作夹心饼干外层的两片饼干,这两片饼干就是 setUp/tearDown,

中间的奶油就是测试用例。除此之外,unittest 还提供了更大范围的 Fixture,如测试类和模

块的 Fixture。

# _*_ coding:utf-8 _*_
"""
name:zhangxingzai
"""
import unittest


def setUpModule():
    print("test module start >>>>>>>>>>>>>>")


def tearDownModule():
    print("test module end >>>>>>>>>>>>>>")


class MyTest(unittest.TestCase):
    @classmethod
    def setUpClass(cls):

        print("test class start =======>")

    @classmethod
    def tearDownClass(cls):

        print("test class end =======>")

    def setUp(self):

        print("test case start -->")

    def tearDown(self):

        print("test case end -->")

    def test_case1(self):

        print("test case1")

    def test_case2(self):

        print("test case2")


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

执行结果如下:

test module start >>>>>>>>>>>>>>
test class start =======>
test case start -->
test case1
test case end -->
test case start -->
test case2
test case end -->
test class end =======>
test module end >>>>>>>>>>>>>>
Ran 2 tests in 0.005s
OK

setUpModule/tearDownModule:在整个模块的开始与结束时被执行。

setUpClass/tearDownClass:在测试类的开始与结束时被执行。

setUp/tearDown:在测试用例的开始与结束时被执行。

需要注意的是,setUpClass/tearDownClass 为类方法,需要通过@classmethod 进行装饰。

另外,方法的参数为 cls。其实,cls 与 self 并没有什么本质区别,都只表示方法的第一个

参数。

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

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

相关文章

UNIAPP实战项目笔记58 注册成功信息存储到数据库

UNIAPP实战项目笔记58 注册成功信息存储到数据库 注册时候验证手机验证码 验证码通过后讲用户信息存入数据库 实际案例图片 后端接口文件 index.js var express require(express); var router express.Router(); var connection require(../db/sql.js); var user require(…

爱奇艺“资产重定价”:首次全年运营盈利是拐点,底层逻辑大改善

长视频行业历时一年有余的降本增效、去肥增瘦&#xff0c;迎来首个全周期圆满收官的玩家。 北京时间2月22日美股盘前&#xff0c;爱奇艺发布2022年Q4及全年财报&#xff0c;Q4 Non-GAAP净利润明显超越预期&#xff0c;且首次实现全年运营盈利。受业绩提振&#xff0c;爱奇艺盘…

SpringSecurity源码分析(二) SpringBoot集成SpringSecurity即Spring安全框架的执行过程

在上一篇文章中我们描述了SpringSecurity的执行过程。我们我们了解到了以下内容 在SpringSecurity框架中有三个非常核心的类和接口&#xff0c;分别是 1.SecurityFilterChain接口 2.FilterChainProxy类 3.DelegatingFilterProxy类 springboot项目中&#xff0c;客户端向Tomcat …

day51【代码随想录】动态规划之回文子串、最长回文子序列

文章目录前言一、回文子串&#xff08;力扣647&#xff09;二、最长回文子序列&#xff08;力扣516&#xff09;前言 1、回文子串 2、最长回文子序列 一、回文子串&#xff08;力扣647&#xff09; 给你一个字符串 s &#xff0c;请你统计并返回这个字符串中 回文子串 的数目…

从网易到支付宝,3年外包生涯做完,我这人生算是彻底废了......

我为什么一直做外包呢&#xff0c;原因是薪资和技术方面。 在华三做了一年外包&#xff0c;薪资5k&#xff0c;功能测试&#xff0c;接触Linux和网络&#xff0c;但是说实在的技术很难沉淀&#xff0c;就像雾里看花一样&#xff0c;过年之后&#xff0c;想走的人都走了&#x…

Word处理控件Aspose.Words功能演示:使用 C# VB.NET 将 DOCX 转换为 DOC 或将 DOC 转换为 DOCX

Aspose.Words 是一种高级Word文档处理API&#xff0c;用于执行各种文档管理和操作任务。API支持生成&#xff0c;修改&#xff0c;转换&#xff0c;呈现和打印文档&#xff0c;而无需在跨平台应用程序中直接使用Microsoft Word。此外&#xff0c; Aspose API支持流行文件格式处…

深度学习编译器CINN(1):框架概览和编译安装

目录 框架概览 编译安装 参考 框架概览 CINN是一种在不改变模型代码的条件下加速飞桨模型运行速度的深度学习编译器。CINN致力于创造训推一体自动调优、分布式编译加速等特色功能&#xff0c;对深度学习模型提供全自动、极致的性能优化&#xff0c;并在科研界和工业界建立影…

【布隆过滤器(Bloom Filter)基本概念与原理、Bloom Filter优点与缺点、以及应用场景】

布隆过滤器&#xff08;Bloom Filter&#xff09;基本概念与原理、Bloom Filter优点与缺点、以及应用场景 Bloom Filter 基本概念 布隆过滤器是1970年由一个叫布隆的小伙子提出的。它实际上是一个很长的二进制向量和一系列随机映射函数。布隆过滤器可以用于检索一个元素是否在…

DualCor: Event Causality Extraction with Event Argument Correlations论文解读

Event Causality Extraction with Event Argument Correlations(带有事件论元相关性的事件因果关系抽取) 论文&#xff1a;2301.11621.pdf (arxiv.org) 代码&#xff1a;cuishiyao96/ECE: Dataset and code for COLING2022 paper Event Causality Extraction with Event Argum…

【vue 10 第一个vue-cli程序】

1.什么是vue-cli vue-cli官方提供的一个脚手架&#xff0c;用于快速生成一个vue的项目模版&#xff1b; 预先定义好的目录结构及基础代码&#xff0c;就好比咱们在创建Maven项目时可以选择创建一个骨架项目&#xff0c;这个骨架项目就是脚手架&#xff0c;我们的开发更加的快速…

FC总线知识点小结

FC总线 &#xff08;一&#xff09;特点&#xff1a; FC具备通道和网络双重优势&#xff0c;具备高带宽、高可靠性、高稳定性&#xff0c;抵抗电磁干扰等优点&#xff0c;能够提供非常稳定可靠的光纤连接&#xff0c;容易构建大型的数据传输和通信网络&#xff0c;目前支持1x…

2022阿里,字节跳动,JAVA岗(一线企业校招、社招)面试题合集

前言 以下面试题全属于一线大厂社招以及校招的面试真题&#xff0c;各位在做这些题目对照自己的时候请平凡心对待&#xff0c;不要信心受挫。其实 做为致力于一线企业校招或者社招的你来说&#xff0c;能把每个知识模块的一小部分问题去深入学习和总结&#xff0c;已经很棒了&…

SpringBoot整合阿里云OSS文件上传、下载、查看、删除

SpringBoot整合阿里云OSS文件上传、下载、查看、删除1、开发准备1.1 前置知识1.2 环境参数1.3 你能学到什么2. 使用阿里云OSS2.1 创建Bucket2.2 管理文件2.3 阿里云OSS文档3. 项目初始化3.1 创建SpringBoot项目3.2 Maven依赖3.3 安装lombok插件4. 后端服务编写4.1 阿里云OSS配置…

Ask林曦|来回答,30个你关心的日常问题(三)

在林曦老师的线上书法直播课上&#xff0c;上课前后的聊天时间里&#xff0c;时常有同学向林曦老师提问&#xff0c;这些问题涵盖了日常生活的诸多方面&#xff0c;从身体的保养&#xff0c;到快乐的法门&#xff0c;皆是大家感兴趣的&#xff0c;也都共同关切的。      暄…

Spring Cloud @RefreshScope 原理分析:扫描 Bean 定义

背景 最近读了一下 spring cloud 的 RefreshScope 生效的源码&#xff0c;总结一下该注解的 refresh 类型的类实例化的过程。 关键技术点&#xff1a; 扫描过程中对 RefreshScope 注解做了特殊处理&#xff0c;会额外注册两个BeanDefinition。GenericScope 实现了 BeanDefin…

医疗影像工具LEADTOOLS 入门教程: 从 PDF 中提取附件 - 控制台 C#

LEADTOOLS 是一个综合工具包的集合&#xff0c;用于将识别、文档、医疗、成像和多媒体技术整合到桌面、服务器、平板电脑、网络和移动解决方案中&#xff0c;是一项企业级文档自动化解决方案&#xff0c;有捕捉&#xff0c;OCR&#xff0c;OMR&#xff0c;表单识别和处理&#…

ARM平台搭建Python环境

ARM平台搭建Python环境写在最前常见问题1. 主机&#xff08;Ubuntu&#xff09;安装Python3.8.101.1 安装前的准备1.2 Ubuntu安装Python3.8.101.3 Ubuntu配置Python3.8.102. 宿主机&#xff08;AMR&#xff09;安装Python3.8.102.1 主机安装交叉编译工具2.2 交叉编译zlib库2.3 …

简析RE中python的exe文件

0x00. 前置学习 简单了解 python为什么要打包成exe文件&#xff1f;在日常生活中的应用是因为传输源文件以及源代码给他人是需要配置好一定的环境才能进行编译操作&#xff0c;而打包成exe文件就可以跟电脑软件一样打开就可以运行也可以分享给他人。 而对于ctf比赛来说&…

(三十三)大白话MySQL运行时多个事务同时执行是什么场景?

到目前为止&#xff0c;我们已经给大家深入讲解了MySQL的buffer pool机制、redo log机制和undo log机制&#xff0c;相信大家现在对我们平时执行一些增删改语句的实现原理&#xff0c;都有了一定较为深入的理解了&#xff01; 因为平时我们执行增删改的时候&#xff0c;无非就…

Python|Leetcode刷题日寄Part04

Python|Leetcode刷题日寄Part0401&#xff1a;环形链表02&#xff1a;跳跃游戏03&#xff1a;括号生成04&#xff1a;二分查找05&#xff1a;打家劫舍06&#xff1a;搜索旋转排序数组07&#xff1a;Z字形变换08&#xff1a;买卖股票的最佳时机Ⅱ09&#xff1a;最后一个单词的长…