一文搞定unittest测试框架(TestCase、TestSuite、TextTestRunner、TestLoader、Fixture、参数化、断言、两种格式的测试报告)

*测试用例Test Case 思路就是和数据库中的数据进行对比,这就需要我们在进行测试的时候知道数据对应的是数据库中的哪个库,哪张表,有哪些字段。例如:拿淘宝来讲,用户登录,搜索商品,添加商品到购物车,生成订单,订单支付,查看物流;我们就可以进入到数据库中,通过时间倒序,用SQL查询到数据库中最新的商品信息,再和页面展示的商品进行一个比对。比如说输入框这种,写用例的时候我们就要分析输入数据的长度、类型,是否为空、是否重复等。对于手机端项目,我们要考虑:安装卸载、软件更新、UI界面、前后台切换、中断干扰、网络环境等方面的问题。 阅读详情

注意:

1、所有的测试用例,有两种方式加载成测试套件:

        (1)使用TestSuite一个个加;(2)使用TestLoader,一次性全部加进去。

2、所有的测试用例,加载成测试套件后有两种方式执行:(执行测试套件)

        (1)如果要生成文本样式的测试报告,就用TextTestRunner来执行。(unittest自带)

        (2)如果要生成html样式的测试报告,就用HTMLTestRunner来执行。(第三方插件)

3、UnitTest是python自带的一个单元测试框架,用来做单元测试。

核心要素:

(1)TestCase——定义测试类的时候要继承的父类,然后在这个类里编写方法(一个方法就是一条测试用例)。注意:类里面的函数称呼的时候不叫函数,而是要叫方法。

(2)TestSuite——测试套件,通过addTest方法,把测试用例一条一条加到测试套件中。

(3)TextTestRunner——执行测试用例,生成的是文本格式的测试报告。它是unittest中自带的,一般测试要生成测试报告的话,就不用它,而是会用一个第三方插件,HTMLTestRunner,它也是执行测试用例,生成的是html格式的测试报告,但它不是unittest自带的,使用它的时候,要先去网上下载一个HTMLTestRunner.py文件,然后把它放到自己电脑里python安装目录下的Lib\site-packages目录下。后期项目代码中使用from...import来进行调用。

from HTMLTestRunner import HTMLTestRunner

(4)TestLoader—— 也算是一个套件,它是一次性的把所有文件中的测试用例都加到测试套件中。

(5)Fixture——测试固件,用来在测试执行前和执行后执行一些代码。有三个控制级别:方法级、类级、模块级。比如,测试前做一些环境方面的初始化工作,测试结束后做一些收尾工作。

        除此之外,在进行参数化的时候,由于unittest框架本身不支持参数化,所以要进行参数化需要安装一个第三方插件parameterized。安装方法:win+r输入cmd进入dos窗口,切换到python的安装目录,输入python -m pip install parameterized即可进行下载。

小结:TestCase、TestSuite、TextTestRunner、TestLoader这四个都是unittest自带的,所以使用的时候都要写unittest. 而HTMLTestRunner、参数化是第三方插件,所以使用时候不用写unittest.。

4、参数化的使用场景:就一个功能点,我们要输入好多的数据去测试它,来找它的问题,这个时候就可以用参数化,这样能够减少冗余代码。

一、TestCase

就是测试用例的意思。只要定义的类继承自unittest.TestCase这个父类,那么这个类中每一个以test开头的方法就是一个测试用例。

TestCase的使用步骤:

第一步:导包,导入unittest模块。

第二步:定义一个类,这个类要继承unittest.TestCase类。类的命名要使用大驼峰命名法。

第三步:定义类的方法,方法名必须以test开头。类中的每一个方法就代表一个测试用例。

例如:定义一个函数,用来实现加法运算,并对该函数进行测试。新建一个py文件,命名为:testcase_01.py。

import unittest  # 导包


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


class MyTest(unittest.TestCase):  # 定义测试类。注意:【测试类必须要继承unittest.TestCase】
    def test01(self):  # 定义测试方法,方法名必须以test开头。
        print(my_sum(1, 2))  # 注意:一个测试方法就代表一个测试用例,所以test01是一条测试用例

    def test02(self):  # 这也是一条测试用例
        print(my_sum(3, 3))

# 运行:点击鼠标右键,选择【Unittests in 这个py文件】
结果:
Ran 2 tests in 0.000s

OK
3
6

进程已结束,退出代码 0

# 说明这两条测试用例通过了

注意:如果点击鼠标右键,没有运行【Unittests for 这个py文件】这个选项怎么办?

 上面例题中是在一个.py文件里,执行了两个测试用例,那么如果有多个.py文件怎么办?或者说,测试用例放在了不同的.py文件里,那么这些测试用例又该怎么执行?使用测试套件TestSuite或TestLoader。

二、TestSuite——测试套件,用来打包测试用例

用来把多个测试用例集合到一起,整合成一个测试套件。

TestSuite使用步骤:

第一步:导包,导入unittest模块,以及导入其它包含测试用例的.py文件。这里的py文件的命名规则与变量名的命名规则相同。

第二步:为unittest.TestSuite这个类,实例化一个对象。

第三步:调用对象的addTest方法,来添加测试用例。

利用addTest方法添加用例有两种方式:

第一种:对象名.addTest(py文件名.类名("方法名"))—— 一次只能添加类里面的一条测试用例。

第二种:对象名.addTest(unittest.makeSuite(py文件名.类名))—— 一次导入一个类里面所有的测试用例。即:指定类,然后将类里面所有的以test开头的方法都添加进去。但这种方法不咋样,写的时候,pycharm也会有警告提示。

下面分别对这两种方式进行演示。

第一种:这种方式代码量比较大,比较冗余,不方便。适合添加指定的、少量的测试用例。

以刚才编写的测试加法运算的那俩用例为例。它们所在文件名为:testcase_01.py。

现在在同级目录下,新建一个py文件,命名为:study_testsuite.py,并写入以下代码。

import unittest
import testcase_01  # 导入testcase_01.py这个文件

suite = unittest.TestSuite()  # 为类TestSuite实例化一个对象,名叫suite

# 根据对象名.addTest(测试用例所在的文件名.类名("方法名"))来添加测试用例
suite.addTest(testcase_01.MyTest("test01"))  # 添加第一条测试用例
suite.addTest(testcase_01.MyTest("test02"))  # 添加第二条测试用例

第二种:不咋用。

import unittest
import testcase_01  # 导入testcase_01.py这个文件

suite = unittest.TestSuite()  # 为类TestSuite实例化一个对象,名叫suite

suite.addTest(unittest.makeSuite(testcase_01.MyTest))  # 把testcase_01.py文件的类名添加进行

至此,两种方式添加testcase_01.py中的两个测试用例(也就是类里面的方法)已经添加完毕。

三、TextTestRunner——执行测试套件中的测试用例。

上面两种方式已经将test01、test02这两个测试用例添加到测试套件中。现在开始执行。

使用步骤:

第一步:为TextTestRunner这个类实例化一个对象。

第二步:调用对象的run方法,去执行测试套件。

        格式:对象名.run(套件名)

例如:接着上面的代码,把下面代码写入study_testsuite.py中。

runner = unittest.TextTestRunner() # 为TextTestRunner这个类实例化一个对象,名叫runner
runner.run(suite)  # 调用对象的run方法,参数为套件名称

所以,study_testsuite.py完整代码是:

import unittest
import testcase_01  # 导入testcase_01.py这个文件


suite = unittest.TestSuite()    # 为类TestSuite实例化一个对象,名叫suite

# 根据对象名.addTest(测试用例所在的文件名.类名("方法名"))来添加测试用例

suite.addTest(testcase_01.MyTest("test01"))  # 添加第一条测试用例
suite.addTest(testcase_01.MyTest("test02"))  # 添加第二条测试用例


# 执行测试套件
runner = unittest.TextTestRunner()  # 为TextTestRunner这个类实例化一个对象,名叫runner
runner.run(suite)   # 调用对象的run方法,参数为套件名称

# 鼠标右键【运行study_testsuite.py】

结果:
3
6
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

进程已结束,退出代码 0


# 或显示

..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK
3
6

进程已结束,退出代码 0

四、TestLoader

TestSuite是用来将测试用例进行打包,整合成一个测试套件。但是它的两种添加用例的方式都不太好,尤其是当测试用例在多个py文件中的时候,会非常繁琐、代码量大、重复的代码比较多,所以都不常用。用的比较多的是TestLoader。

TestLoader也是用来把测试用例整合到测试套件中,相比TestSuite,TestLoader会更加的方便。它可以从指定的目录中,查找指定的py文件中所有的测试用例(也就是类中以test开头的所有方法),然后自动的加载到测试套件中。也就是说,它可以把满足条件的测试用例一次性的全部封装成测试套件。

使用步骤:

用TestLoader对象的discover方法来自动查找py文件,并自动加载文件里的测试用例到测试套件中。

格式:unittest.TestLoader().discover("从哪里找py文件","指定要查找的py文件的文件名")

当然也可以使用通配符。

例如:suite=unittest.TestLoader().discover("./","test*.py")

./表示从当前目录开始查找,./也可以只写个点,即.也表示当前目录。

./或者. 都表示当前目录
/表示根目录
..表示上级目录

test*.py表示查找以test开头的所有.py文件。

总结起来就是:从当前目录下,查找所有以test开头的.py文件中所有的测试用例,然后把它们一起加载到测试套件中。

例如:在当前目录下新建study_taseloader.py文件,写入以下内容,并执行。

import unittest

suite = unittest.TestLoader().discover("./", "test*.py")
# 当前目录下查找以test开头的.py文件中所有的测试用例,只要找到就生成一个测试套件suite

runner = unittest.TextTestRunner()
runner.run(suite)

# 鼠标右键运行
结果:
..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK
3
6

进程已结束,退出代码 0

从上面代码中可以看到:同样是把test01、test02这两个测试用例添加到测试套件,然后再运行,上面这种方式显得更加方便。但如果只是把一部分用例拿出来去执行,显然就不能用上面这种方式了,得用TestSuite 。

小结:TestSuite   VS   TestLoader

1、TestSuite

可以添加指定的测试用例。比如,一个py文件里有10个测试用例,而我们只想执行俩,那就把要执行的这俩添加进去执行即可。也就是说,你想执行哪个用例就把哪个用例加进去。

2、TestLoader

不能添加指定的测试用例,只要满足查找的条件,那么对应文件里的所有用例就会全部加进去。

当然,如果不用通配符*进行模糊匹配也可以,这时候查找的就是这一个具体文件,然后把这个文件里面所有的测试用例都加载进去,再去执行。但是,倘若这个文件里的用例我们不想全部执行,而是想有选择的性的挑几个去执行,此时,这个方法就不行了。所以,TestLoader适用于执行所有py文件中的所有测试用例,而TestSuite适用于执行指定的几个测试用例。

五、Fixture

它是unittest框架的固件,在测试开始前和测试结束后调用指定的函数或方法,来进行一些操作。

为什么叫调用指定的函数或方法?因为类级、方法级因为是要写在类里面,所以就方法,而模块级是写在类的外面所以叫函数。

setUpxxx:一般是做初始化工作,tearDownxxx是在测试结束后做一些收尾的工作。

比如,在测试网站的时候会,第一步是要先打开网站,这个就可以写到setUp里,最后一步是关闭网站,就可以写到tearDown里。

fixture的控制级别:方法级、类级、模块级。

(1)方法级:setUp、tearDown,是在每个方法执行前和执行后自动调用。

(2)类级:setUpClass、tearDownClass,是在每个类的执行前和执行后自动调用。注意要用@classmethod进行修饰。

(3)模块级:一个py文件就是一个模块。setUpModule、tearDownModule,每个py文件执行前和执行后自动调用。

1、方法级:setUp、tearDown

setUp——测试用例执行前,自动被调用。

tearDown——测试用例执行后,自动被调用。

有多少个测试用例,那么它们就会被自动调用多少次。即:每个方法执行前后都会自动调用一次。既然是方法级别,那么在定义的时候就要写到类里面去(要写到测试用例所在的class中),至于写在测试用例上面还是下面都可以,结果都一样。例如下面的代码中,就把它写到了测试用例test02的下面。

例如:新建一个study_fixture.py文件,内容如下:定义两个方法级的fixture。即:setUp、tearDown。然后执行代码。

import unittest


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


class MyTest(unittest.TestCase):  # 注意:【测试类必须要继承unittest.TestCase】
    def test01(self):  # 定义测试方法,方法名必须以test开头。
        print(my_sum(1, 2))  # 注意:一个测试方法就是一个测试用例,所以test01是一条测试用例

    def test02(self):
        print(my_sum(3, 3))

    def setUp(self):           # 方法级别
        print("setUp被调用了")
  
    def tearDown(self):          # 方法级别
        print("tearDown被调用了")
# 鼠标右键【运行Unittests in study_fixture.py】
结果:
setUp被调用了
3
tearDown被调用了
setUp被调用了
6
tearDown被调用了

要执行上面这段代码有两种方式:

(1)直接在unittest框架里运行。步骤:在文件的最后敲一个空行出来,光标点到这,然后鼠标右键【运行Unittests in study_fixture.py】。

(2)专门写个py文件来执行它。做法:新建一个py文件,然后在这个文件里添加用例再执行。学习阶段,为了方便找这俩文件,可以把这个文件建在跟上面代码同级目录上。例如:新建一个名为run_fixture.py的文件,内容如下:

import unittest

suite = unittest.TestLoader().discover(".", "study_fixture.py")  # 当前目录下,把study_fixture.py里的所有测试用例加载到测试套件
runner = unittest.TextTestRunner()  # 创建TextTestRunner类的实例
runner.run(suite)  # 调用run方法

#运行:鼠标右键 run run_fixture.py
结果:
D:\anzhuang\Python37\python.exe D:/study_python/yy_daima/ceshikuangjia/one_study_fixture/run_fixture.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK
setUp被调用了
3
tearDown被调用了
setUp被调用了
6
tearDown被调用了

进程已结束,退出代码 0

两种方式结果都是一样的,代码中,有两个测试用例,分别是test01、test02,定义了方法级别的fixture那就是在每个方法执行前、执行后各执行一次,setUp、tearDown。

2、类级——setUpClass、tearDownClass

不管类里面有多少方法,一个类执行前后自动调用一次。

既然是类级别,那么在定义的时候就要写到类里面去,至于写在测试用例上面还是下面都可以,结果都一样,需要注意的是,类方法需要用@classmethod来进行修饰,且第一个参数是cls。

例如:现在把study_fixture.py这个文件内容改了,把方法级的改成类级别的。

import unittest


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


class MyTest(unittest.TestCase):  # 注意:【测试类必须要继承unittest.TestCase】
    @classmethod   # 类方法
    def setUpClass(cls):   # 这是类级别的fixture
        print("setUpClass被调用了")

    @classmethod
    def tearDownClass(cls):   # 这是类级别的fixture
        print("tearDownClass被调用了")

    def test01(self):  # 定义测试方法,方法名必须以test开头。
        print(my_sum(1, 2))  # 注意:一个测试方法就是一个测试用例,所以test01是一条测试用例

    def test02(self):
        print(my_sum(3, 3))

用第二种方式执行下,结果如下:

D:\anzhuang\Python37\python.exe D:/study_python/yy_daima/ceshikuangjia/one_study_fixture/run_fixture.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK
setUpClass被调用了
3
6
tearDownClass被调用了

进程已结束,退出代码 0

3、模块级——setUpModule、tearDownModule

一个py文件就是一个模块。模块在执行前后自动调用一次。也就是说,整个模块只会运行一次setUpModule、tearDownModule。既然是模块级别那就不能写类里了,得写在类的外面,至于写类的上面还是下面都可以,结果都是一样的,但为了更直观更方面查看,通常是写在文件最上面,也就是类的上面。

例如:现在把study_fixture.py这个文件内容改了,把类级的改成模块级别的。

import unittest


def setUpModule():   # 模块级别
    print("setUpModule自动调用了")


def tearDownModule():  # 模块级别
    print("tearDownModule自动调用了")


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


class MyTest(unittest.TestCase):  # 注意:【测试类必须要继承unittest.TestCase】
    def test01(self):  # 测试用例名必须以test开头。
        print(my_sum(1, 2))  # 注意:一个测试方法就是一个测试用例,所以test01是一条测试用例

    def test02(self):
        print(my_sum(3, 3))

再次执行run_fixture.py,结果如下:

D:\anzhuang\Python37\python.exe D:/study_python/yy_daima/ceshikuangjia/one_study_fixture/run_fixture.py
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK
setUpModule自动调用了
3
6
tearDownModule自动调用了

进程已结束,退出代码 0

4、所有级别放一起演示

为了更好的展示三者的区别,现在把三种级别都加上,进行演示。

例如:现在把study_fixture.py这个文件内容改了,把所有级别的fixture都加上。

import unittest


def setUpModule():  # 模块级别
    print("setUpModule自动调用了")


def tearDownModule():
    print("tearDownModule自动调用了")


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


class MyTest(unittest.TestCase):  # 注意:【测试类必须要继承unittest.TestCase】
    @classmethod
    def setUpClass(cls):  # 类级别
        print("setUpClass被调用了")

    @classmethod
    def tearDownClass(cls):
        print("tearDownClass被调用了")

    def setUp(self):  # 方法级别
        print("setUp被调用了")

    def tearDown(self):
        print("tearDown被调用了")

    def test01(self): 
        print(my_sum(1, 2))  

    def test02(self):
        print(my_sum(3, 3))

执行run_fixture.py,结果如下:

D:\anzhuang\Python37\python.exe D:/study_python/yy_daima/ceshikuangjia/one_study_fixture/run_fixture.py
setUpModule自动调用了
setUpClass被调用了
setUp被调用了
3
tearDown被调用了
setUp被调用了
6
tearDown被调用了
tearDownClass被调用了
tearDownModule自动调用了
..
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

进程已结束,退出代码 0

可以发现:

测试前执行的顺序是:先调用模块级,再调用类级、最后调用方法级。

测试结束后调用的顺序是:先调用方法级、再调用类级、最后才调用模块级。

这个很好理解,首先它们是在同一个文件,那么同一个文件内,代码的执行顺序都是从上到下依次执行。所以初始化时候就会先调用模块级,然后是类级、方法级;结束的时候,相反。

六、断言

让程序来判断测试用例执行的结果是否符合预期。也就是说,让程序自动的帮我们判断代码执行的结果是否正确。

注意:使用断言的时候,这个类,必须要继承unittest.TestCase这个父类,例如:

class MyTest(unittest.TestCase): 

这样才可以使用unittest里的断言方法。

unittest常用的断言方法:

(1)assertEqual(参数1,参数2)

这两个参数用来存放实际结果和预期结果。哪个写在前面,哪个写在后面,都可以。

如果参数1和参数2的值相等,则断言成功,否则断言失败。

(2)assertNotEqual(参数1,参数2)

跟上面一样,只是,如果参数1和参数2的值不相等,则断言成功,否则断言失败。

(3)assertIn(参数1,参数2)

如果参数1在参数2里面,则断言成功,否则断言失败。

(4)assertNotIn(参数1,参数2) 

如果参数1不在参数2里面,则断言成功,否则断言失败。

小结:

断言方法

用来检查

assertEqual(a,b)

a == b

assertNotEqual(a,b)

a != b

assertTrue(x)

bool(x) is True

assertFalse(x)

bool(x) is False

assertIs(a,b)

a is b

assertIsNot(a,b)

a is not b

assertIsNone(x)

x is None

assertIsNotNone(x)

x is not None

assertIn(a,b)

a in b

assertNotIn(a,b)

a not in b

 例如:assertEqual(参数1,参数2)举例。新建study_assert.py文件,内容如下:

import unittest


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


class MyTest(unittest.TestCase):

    def test01(self):
        num1 = my_sum(1, 2)  # 定义变量num1,用来接收my_sum函数的返回值
        self.assertEqual(num1, 3)  # num1存放的是实际结果,3是预期结果
        # 实际结果与预期结果一致,则说明测试用例测试通过,否则,用例不通过,测试失败

    def test02(self):
        num1 = my_sum(3, 3)
        self.assertEqual(num1, 6)

新建run_assert.py,内容如下:

# 单纯的用来执行study_assert.py这个文件里的测试用例
import unittest

# 查找当前目录下的study_assert.py,然后把这个文件里所有的测试用例加载到测试套件中
suite = unittest.TestLoader().discover(".", "study_assert.py")
runner = unittest.TextTestRunner()
runner.run(suite)

执行run_assert.py,结果如下:

..
----------------------------------------------------------------------
Ran 2 tests in 0.000s

OK

进程已结束,退出代码 0

# 说明断言成功

现在为了演示断言失败的情况,把study_assert.py文件中,第一个测试用例的self.assertEqual(num1, 3) 里的3改成4 。显然1+2=3,这里改成4肯定失败。

再次运行run_assert.py,结果如下:

F.
======================================================================
FAIL: test01 (study_assert.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\study_python\yy_daima\ceshikuangjia\two_study_assert\study_assert.py", line 12, in test01
    self.assertEqual(num1, 4)  
AssertionError: 3 != 4

----------------------------------------------------------------------
Ran 2 tests in 0.001s

FAILED (failures=1)

进程已结束,退出代码 0

注意:用例执行成功与否看运行的结果的第一行就知道了,如果都是点,就代表成功,有几个点就代表执行了几个测试用例,F代表失败。例如:上面的结果中,第一行是F.说明,本次一共执行了两个测试用例,其中,第一个用例失败,第二个用例成功了。

例如:assertIn(参数1,参数2)举例。将study_assert.py内容进行修改,如下:

import unittest
import random


def MyNumber():  # 定义一个函数,要求返回1~4之间的一个随机数
    return random.randint(1, 4)


class MyTest(unittest.TestCase):
    def test1(self):
        num1 = MyNumber()  # 调用函数
        self.assertIn(num1, [1, 2, 3, 4])  # 判断num1是否是1234中的一个数


# 第一种执行方法,直接在框架里执行,即鼠标右键运行,选择Unittests in study_assert.py
结果:
Ran 1 test in 0.002s

OK

进程已结束,退出代码 0

# 第二种执行方法:执行run_assert.py
结果:
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

进程已结束,退出代码 0

注意:都有两种执行方式,一个是直接在测试用例那个文件里直接执行,即:右键【运行Unittests in这个py文件名】。另一个是再另外建个文件专门用来执行测试用例,此时就是【运行 文件名】。

把study_assert.py内容进行修改,来验证断言失败的情况。修改后内容如下:

把函数定义的范围由原来的1~4改成,10~40,断言时候依然判断这个数是否在1~4之间,显然肯定不在,所以就会断言失败。

import unittest
import random


def MyNumber():  # 定义一个函数,要求返回10~40之间的一个随机数
    return random.randint(10, 40)   


class MyTest(unittest.TestCase):
    def test1(self):
        num1 = MyNumber()  # 调用函数
        self.assertIn(num1, [1, 2, 3, 4])  # 判断num1是否是1234中的一个数

结果:
D:\anzhuang\Python37\python.exe D:/study_python/yy_daima/ceshikuangjia/two_study_assert/run_assert.py
F
======================================================================
FAIL: test1 (study_assert.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\study_python\yy_daima\ceshikuangjia\two_study_assert\study_assert.py", line 31, in test1
    self.assertIn(num1, [1, 2, 3, 4])  # 判断num1是否是1234中的一个数
AssertionError: 18 not found in [1, 2, 3, 4]

----------------------------------------------------------------------
Ran 1 test in 0.000s

FAILED (failures=1)

进程已结束,退出代码 0

上面的报错信息中,清楚的写出来了18不在1~4里面。 

七、参数化

从之前的代码中可以看到,测试用例test01、test02的区别就是,代码基本一样,只是数据和预期结果不同,测试的都是同一个加法函数。显然这种方式,代码看起来冗余度特别高,比如,要拿100个数据来测那个功能,就要写100次差不多一模一样的代码,这样写起来就会很麻烦,重复代码也会特别多,此时就可以使用参数化这个技术。即:通过参数化的方式来传递数据,这样不仅可以减少代码的冗余,后期还能很好的进行维护。也就是说,用一个方法通过传递不同的参数就可以实现。

1、安装第三方插件——parameterized

unittest本身是不支持参数化的,但是可以通过安装第三方插件parameterized来实现参数化。

安装方法:

win+R输入cmd进入dos窗口,切换到python的安装目录,输入:

python -m pip install parameterized  即可进行下载。效果如下:

D:\anzhuang\Python37>python -m pip install parameterized
Looking in indexes: http://pypi.douban.com/simple
Collecting parameterized
  Downloading http://pypi.doubanio.com/packages/31/13/fe468c8c7400a8eca204e6e160a29bf7dcd45a76e20f1c030f3eaa690d93/parameterized-0.8.1-py2.py3-none-any.whl
Installing collected packages: parameterized
Successfully installed parameterized-0.8.1
WARNING: You are using pip version 19.3.1; however, version 22.3.1 is available.
You should consider upgrading via the 'python -m pip install --upgrade pip' command.

D:\anzhuang\Python37>

踩坑1:输入pip  install  parameterized,报错

D:\anzhuang\Python37>pip  install  parameterized
Traceback (most recent call last):
  File "d:\anzhuang\python37\lib\runpy.py", line 193, in _run_module_as_main
    "__main__", mod_spec)
  File "d:\anzhuang\python37\lib\runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "D:\anzhuang\Python37\Scripts\pip.exe\__main__.py", line 9, in <module>
TypeError: 'module' object is not callable

检验是否安装成功:

方法1:去电脑里找到python的安装目录,然后进入Lib\site-packages目录下就可以看到多了三个文件夹,分别是:nose_parameterized、parameterized、parameterized-0.8.1.dist-info。

方法2:win+R输入cmd进入dos窗口,输入python回车,进入python编译器,输入:

from parameterized import parameterized回车,不报错说明安装成功。

C:\Users\Lenovo>python
Python 3.7.0 (v3.7.0:1bf9cc5093, Jun 27 2018, 04:59:51) [MSC v.1914 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from parameterized import parameterized
>>> exit
Use exit() or Ctrl-Z plus Return to exit
>>> exit()

C:\Users\Lenovo>

2、测试用例中使用参数化的场景

多个测试用例的代码相同,只是测试数据和预期结果不同,这时候就可以把多个测试用例通过参数化技术合并为一个测试用例。也就是说,就一个功能点,我们要输入好多的数据去测试它,来找它的问题,这个时候就可以用参数化,这样能够减少冗余代码。

3、参数化操作步骤

第一步:导包,from parameterized import parameterized。

第二步:在需要参数化的方法上面用@parameterized.expand()进行装饰。

        其中,expand( )里面是一个列表套元组。即:列表里面放多个元组,每个元组中的成员就代表调用方法时候所使用的实参,列表中有几个元组,就说明有几组测试数据,方法就会被自动调用几次。

例如:把最开始的测试加法运算的函数那个代码进行优化,加上断言、参数化,代码如下:

新建canshuhua.py文件。

import unittest
from parameterized import parameterized


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


class MyTest(unittest.TestCase):
    @parameterized.expand([(1, 2, 3), (3, 3, 6), (5, 5, 10), (-1, 10, 9)])
    def test01(self, a, b, c):
        num1 = my_sum(a, b)
        self.assertEqual(num1, c)  

# 注释:
# 元组里面写三个数,前两个数代表调用函数时候传的实参,后一个数代表预期结果
# 有多少个测试数据,就写多少个元组,每一个元组代表一组测试数据,例如,上面一共有4组测试数据
# a、b、c的含义:
# a是调用my_sum函数的第一个参数,b是调用my_sum的第二个参数
# c是预期结果
# 定义变量num1,用来接收my_sum函数的返回值,即:num1代表实际结果

结果:

# 两种执行方式
# 法1,直接在这个测试用例文件里面用unittest框架执行,鼠标右键【运行Unittests in canshuhua.py】
结果:
Ran 4 tests in 0.000s

OK

进程已结束,退出代码 0


# 法2,新建一个py文件,另写代码,专门用来执行测试用例,也就是在框架外执行
# 新建run_canshuhua.py,写入以下内容并执行

import unittest

# 查找当前目录下的canshuhua.py,然后把这个文件里所有的测试用例加载到测试套件中
suite = unittest.TestLoader().discover(".", "canshuhua.py")
runner = unittest.TextTestRunner()
runner.run(suite)
结果:
....
----------------------------------------------------------------------
Ran 4 tests in 0.000s

OK

进程已结束,退出代码 0

4、参数化的三种写法

第一种:就是上面那种,把参数化的那行数据代码写到类里,方法的上面。

第二种:在类的外面,定义一个全局变量,用来存放测试数据,然后在类的里面调用这个全局变量。例如:其实,本质上跟第一种一样,只是单纯把数据拿出来了而已。

# 参数化的第2种写法
import unittest
from parameterized import parameterized


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


# 定义一个全局变量名叫list1,用来存放测试数据
list1 = [(1, 2, 3), (3, 3, 6), (5, 5, 10), (-1, 10, 9)]


class MyTest(unittest.TestCase):
    @parameterized.expand(list1)  # 调用全局变量list1
    def test01(self, a, b, c):
        num1 = my_sum(a, b)
        self.assertEqual(num1, c)

第三种:定义个函数,返回一个列表,这个列表里放的是测试数据。

import unittest
from parameterized import parameterized


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


def gat_data():  # 定义一个函数
    return [(1, 2, 3), (3, 3, 6), (5, 5, 10), (-1, 10, 9)]


class MyTest(unittest.TestCase):
    @parameterized.expand(gat_data())  # 调用函数
    def test01(self, a, b, c):
        num1 = my_sum(a, b)
        self.assertEqual(num1, c)

 小结:三种方式本质上都一样,只是写法上略有不同,推荐前两种方法。

八、测试报告

有两种格式的测试报告。常用第二种。

(1)文本格式的测试报告,它是unittest自带的一种测试报告,测试结束后生成的是一个.txt文本文件。

(2)html格式的测试报告,它是一个第三方插件,使用之前要先去网上下载【HTMLTestRunner.py 】,然后把它放到电脑里python安装目录下的Lib\site-packages目录下,后期项目代码中通过from...import来进行调用。

from HTMLTestRunner import HTMLTestRunner

测试结束后,生成的是一个.html文件,然后用浏览器就能打开了。这种用的比较多。

小结:其实两种测试报告的区别主要是在最后执行测试套件的方式上有所不同,使用TextTestRunner,得到的是.txt格式的测试报告;使用HTMLTestRunner,得到的是.html格式的测试报告。

1、生成文本格式的测试报告

操作步骤:

第一步:导包,import unittest

第二步:生成测试套件。

suite = unittest.TestLoader().discover("文件查找路径", "要查找的文件名/用通配符查找多个文件")

第三步:打开一个文件,写入测试结果,注意编码方式。这个文件就是所说的测试报告。

file = open("a.txt", "w", encoding="utf8")  # 写方式打开文件,如果没有则创建,有,则覆盖里面内容。

第四步:为TextTestRunner实例化一个对象。在实例化时候要注意写两个参数:

runner = unittest.TextTestRunner(stream=file, verbosity=2)

第一个参数:stream,表示用open打开的文件流

verbosity=2是个固定写法,2表示用第二个模板 。

通常都是写简化的写法:

runner = unittest.TextTestRunner(file, verbosity=2)

第五步:执行测试套件。

第六步:关闭文件。

例如:新建study_txt_report.py,内容如下:

# 文本样式的测试报告是unittest自带的
import unittest
from parameterized import parameterized


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


# 定义一个全局变量名叫list1,用来存放测试数据
list1 = [(1, 2, 3), (3, 3, 6), (5, 5, 10), (-1, 10, 9)]


class MyTest(unittest.TestCase):
    @parameterized.expand(list1)  # 调用全局变量list1
    def test01(self, a, b, c):
        num1 = my_sum(a, b)
        self.assertEqual(num1, c)

新建run_txt_report.py,用来执行上面代码,并生成测试报告,内容如下:

# 生成TextTestRunner的测试报告
import unittest

suite = unittest.TestLoader().discover(".", "study_txt_report.py")
file = open("a.txt", "w", encoding="utf8")  # 写方式打开文件,如果没有则创建,有,则覆盖里面内容
runner = unittest.TextTestRunner(file, verbosity=2)
runner.run(suite)
file.close()

# 执行
结果:
D:\anzhuang\Python37\python.exe D:/study_python/yy_daima/ceshikuangjia/study_report/txt_report/run_txt_report.py

进程已结束,退出代码 0

 说明结果已经写到了同目录下的a.txt。打开该文件,内容如下:

test01_0 (study_txt_report.MyTest) ... ok
test01_1 (study_txt_report.MyTest) ... ok
test01_2 (study_txt_report.MyTest) ... ok
test01_3 (study_txt_report.MyTest) ... ok

----------------------------------------------------------------------
Ran 4 tests in 0.000s

OK

可以看到,其实就是把之前控制台输出的内容,以一种更具体的方式,保存到了一个文本文件里。

#以前没用测试报告时候
D:\anzhuang\Python37\python.exe D:/study_python/yy_daima/ceshikuangjia/three_study_canshuhua/run_canshuhua.py
....
----------------------------------------------------------------------
Ran 4 tests in 0.000s

OK

进程已结束,退出代码 0

演示断言失败时,文本样式测试报告的特点

        刚才全是断言成功,现在为了更好的演示文本样式的测试报告的特点,现在专门写一个错误的数据,来进行测试。这样就会断言失败,此时就能清楚的看到文本样式的测试报告,面对用例失败时具体是什么样子的了。

例如:把list1 中的第一组测试数据的1,2,3改成1,2,4,也就是说把原来的1+2等于3改成了等于4,显然实际结果与预期结果不符,此时就会断言失败。

执行run_txt_report.py,结果a.txt内容如下:

test01_0 (study_txt_report.MyTest) ... FAIL
test01_1 (study_txt_report.MyTest) ... ok
test01_2 (study_txt_report.MyTest) ... ok
test01_3 (study_txt_report.MyTest) ... ok

======================================================================
FAIL: test01_0 (study_txt_report.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "D:\anzhuang\Python37\lib\site-packages\parameterized\parameterized.py", line 533, in standalone_func
    return func(*(a + p.args), **p.kwargs)
  File "D:\study_python\yy_daima\ceshikuangjia\study_report\txt_report\study_txt_report.py", line 18, in test01
    self.assertEqual(num1, c)
AssertionError: 3 != 4

----------------------------------------------------------------------
Ran 4 tests in 0.001s

FAILED (failures=1)

可以清楚的看到,是第一组测试数据失败,原因是3不等于4 。

2、生成html格式的测试报告

操作步骤:步骤跟用TextTestRunner差不多,只是执行套件的方法不一样。

第一步:导包。

import unittest
from HTMLTestRunner import HTMLTestRunner

第二步:生成测试套件。

第三步:以二进制只写的方式打开测试报告。file = open("a.html", "wb")

第四步:实例化HTMLTestRunner对象。实例化时候,第一个参数是open打开的文件,后面有一些可选参数,比如,加title,表示报告的标题。

第五步:执行测试套件。

第六步:关闭文件。

例如:生成网页版的测试报告

把新建一个study_html_report.py,把study_txt_report.py内容全部复制进行。再新建run_html_report.py,用来生成网页版的测试报告,内容如下:

# 生成HTMLTestRunner的测试报告
import unittest
from HTMLTestRunner import HTMLTestRunner

suite = unittest.TestLoader().discover(".", "study_html_report.py")
file = open("a.html", "wb")
runner = HTMLTestRunner(file, title="测试报告——测试加法运算")
runner.run(suite)
file.close()

# 注意:
# 文件名就要改成.html后缀
# wb用二进制写方式,就不用指定字符集utf8了
# title就是给这个测试报告起个名字


运行结果:
D:\anzhuang\Python37\python.exe D:/study_python/yy_daima/ceshikuangjia/study_report/html_report/run_html_report.py
<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'> 
Time Elapsed: 0:00:00.000997
....
进程已结束,退出代码 0

四个点,说明四个测试用例全部通过,打开当前目录下的a.html文件,即可查看测试报告。

这里使用的是谷歌浏览器打开,效果如下:

 

 演示断言失败时,网页版测试报告的特点:

刚才全是断言成功,现在为了更好的演示网页样式测试报告的特点,现在专门写一个错误的数据,来进行测试。这样就会断言失败。

例如:把list1 中的第一组测试数据的1,2,3改成1,2,4,也就是说把原来的1+2等于3改成了等于4,显然实际结果与预期结果不符,此时就会断言失败。

执行run_html_report.py,就会有一个F三个点,说明,四组数据中,第一个失败,后三个成功。

D:\anzhuang\Python37\python.exe D:/study_python/yy_daima/ceshikuangjia/study_report/html_report/run_html_report.py
F...<_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'> 
Time Elapsed: 0:00:00.000997

进程已结束,退出代码 0

再来看测试报告,用谷歌浏览器打开a.html,效果如下:

可以看到,总共执行了四个测试用例,三个通过,一个不通过。 点开Detail可以具体看到是哪个测试失败了。

 

 点开fail也可以看到详细的报错信息。是由于3不等于4所以断言失败。

九、跳过

对于测试类中的方法,如果有一些代码还没有写完或者错误还没调试完的代码,在测试的时候可以先跳过,不执行它。注意:只适用于测试类中定义的方法。也就是说,在测试类中定义的方法,可以使用@unittest.skip进行跳过;而在类外面定义的函数用这个就会报错,此时,如果这个函数想跳过不执行的话就只能打#注释掉。

具体操作:在需要跳过的方法上面写上:@unittest.skip即可。

例如:比如一个测试类里面有三个方法,(类里面的一个方法就代表一个测试用例),也就是说它有三个测试用例,如果有一个不想执行,怎么办?两种办法,第一种:用例加载到测试套件的时候用TestSuite,把要执行的用例加进去,不想执行的就不加。第二种:用TestLoader,然后在不想执行的用例上面加上@unittest.skip。

例如:新建study_skip.py,内容如下:

import unittest


def func1():  # 定义一个函数
    print("函数1被执行了")


class MyTest(unittest.TestCase):
    def test01(self):  # 方法1
        func1()  # 调用函数1
        print("方法1被执行了")

    def test02(self):  # 方法2
        print("方法2被执行了")

    def test03(self):  # 方法3
        print("方法3被执行了")

运行:

# 第一种运行方式:鼠标右键【运行Unittests in 文件名】
结果:
Testing started at 10:01 ...
D:\anzhuang\Python37\python.exe "D:\anzhuang\PyCharm 2020.1\plugins\python\helpers\pycharm\_jb_unittest_runner.py" --path D:/study_python/yy_daima/ceshikuangjia/four_study_skip/study_skip.py


Ran 3 tests in 0.003s
Launching unittests with arguments python -m unittest D:/study_python/yy_daima/ceshikuangjia/four_study_skip/study_skip.py in D:\study_python\yy_daima\ceshikuangjia\four_study_skip

OK

函数1被执行了
方法1被执行了
方法2被执行了
方法3被执行了

进程已结束,退出代码 0


# 第二种方式:新建run_study_skip.py文件,内容如下:

import unittest

suit = unittest.TestLoader().discover(".", "study_skip.py")
runner = unittest.TextTestRunner()
runner.run(suit)
#鼠标右键【运行 文件名】
结果:
...
----------------------------------------------------------------------
Ran 3 tests in 0.001s

OK
函数1被执行了
方法1被执行了
方法2被执行了
方法3被执行了

进程已结束,退出代码 0

现在不想执行函数1和方法3,怎么办?因为函数1不是方法,所以不能使用@unittest.skip ,只能用#把它注释掉,而方法3可以直接使用@unittest.skip 进行跳过。

# 修改study_skip.py内容如下:
import unittest

# def test_func1():
#     print("函数1被执行了")

class MyTest(unittest.TestCase):
    def test01(self): 
        # test_func1()  # 调用函数1
        print("方法1被执行了")

    def test02(self): 
        print("方法2被执行了")

    @unittest.skip  # 跳过
    def test03(self): 
        print("方法3被执行了")

运行run_study_skip.py查看结果:

...
----------------------------------------------------------------------
Ran 3 tests in 0.000s

OK
方法1被执行了
方法2被执行了

进程已结束,退出代码 0

虽然结果中,显示的是运行了三条测试用例,但没有输出第三个测试用例中的“方法3被执行了”,说明实际上根本没有执行方法3 。只是在用例个数上算上这个用例了而已。

实际上,如果真不想执行哪段代码直接注释掉就好,没必要用这个@unittest.skip。用这个反倒看起来有点复杂。

UnitTest基本使用 概念: UnitTest是Python自带的一个单元测试框架, 用它来做单元测试 特点: 1. 能够组织多个用例去执行 2. 提供丰富的断言方法 3. 能够生成测试报告 UnitTest核心要素 1. TestCase 测试用例 2. TestSuite 测试套件 3. TextTestRunner 以文本的形式执行测试用例 4. TestLoader 批量执行测试用例,搜索指定文件夹内指定字母开头的... 阅读详情

相关推荐

iOS开发之进阶篇(6)—— 单元测试(Unit Tests 和 UI Tests)

版本 Xcode 11.5 目录版本1. 概念1.1 单元测试1.2 测试用例1.3 断言2. 准备工作3. Unit Tests4. UI Tests 1. 概念 1.1 单元测试 单元测试是指对软件中的最小可测试单元进行检查和验证. Xcode中有两种单元测试 (Unit Tests 和 UI Tests), Unit Tests 用于测试功能模块; UI Tests用于测试UI交互. Unit Tests 用于测试功能模块, 这些功能模块应尽量单一, 避免与其他功能耦合. 比如测试一个比大小的函数

看影成痴 1696

unittest单元测试框架总结--转载

unittest单元测试框架不仅可以适用于单元测试,还可以适用WEB自动化测试用例的开发与执行,该测试框架可组织执行测试用例,并且提供了丰富的断言方法,判断测试用例是否通过,最终生成测试结果。今天笔者就总结下如何使用unittest单元测试框架来进行WEB自动化测试。 目录 一、unittest模块的各个属性说明 二、使用unittest框架编写测试用例思路 三、使用unittest框架编写测试用...

weixin_39650679的博客 627

Python单元测试框架深度对比:unittest与pytest的实战选择指南

单元测试是保障软件质量、提升代码可维护性的核心工程实践。其基本原理是通过编写自动化测试用例,验证代码单元(如函数、方法)在各种输入下的行为是否符合预期,从而在开发早期发现缺陷,并为后续重构提供安全网。在Python生态中,unittest和pytest是两个主流的单元测试框架,它们代表了不同的设计哲学与技术路径。unittest作为Python标准库,提供了基于xUnit模式的、面向对象的严谨结构,适合需要严格规范和环境受限的场景。而pytest作为第三方框架,以其极简的语法、强大的Fixture依赖注入系

weixin_30591551的博客 289

unittest——TextTestRunner与HTMLTestRunner 生成测试报告的区别

TextTestRunner与HTMLTestRunner区别 及 测试报告样式

释梦燃的博客 1229

YOLOv8 ultralytics使用笔记----labelme标记数据,训练模型、追踪目标。

Ultralytics是一个Python库,它是为执行高级计算机视觉任务而创建的,如对象检测、实例分割、图像分类等。Ultralytics为YOLO模型发布了一个全新的存储库,它被构建为用于机器视觉统一框架。这里先利用,并激活。

qq_48050838的博客 1万+

RTX 4060笔记本也能跑!保姆级教程:用Ollama在Windows上部署DeepSeek-R1-8B模型

本文详细介绍了如何在RTX 4060笔记本上通过Ollama本地部署DeepSeek-R1-8B模型,提供从环境配置到性能调优的全流程优化指南。针对笔记本用户的显存、散热等问题,给出了量化模型选择、启动参数优化及散热解决方案,帮助用户在消费级硬件上高效运行大语言模型。

weixin_28745067的博客 524

Python实战:UnitTest,Fixture,断言,参数化

UnitTest 一、UnitTest 基本使用 1. 什么是 UnitTest 框架? 概念:UnitTest 是 Python 自带的一个单元测试框架,用它来做单元测试。 2. 为什么使用 UnitTest 框架? 能够组织多个用例去执行; 提供丰富的断言方法; 能够生成测试报告; 3. UnitTest 核心要素 TestCase; TestSuite; TestRunner; TestLoader; Fixture; 4. TestCase .

wwwkm123的博客 886

深度学习驱动材料科学:晶体生成与性质预测技术综述

深度学习作为人工智能的核心技术,通过模拟人脑神经网络处理复杂数据,在多个领域展现出强大的模式识别与生成能力。其原理在于构建多层非线性变换,从海量数据中自动学习特征表示与映射关系。这一技术价值在于能够高效处理高维、非结构化数据,解决传统方法计算成本高、探索空间有限的问题。在工程实践中,深度学习已广泛应用于计算机视觉、自然语言处理等领域,并正深刻变革材料科学的研究范式。具体到材料领域,它通过学习已知材料的构效关系,实现对新材料性能的快速预测与逆向设计。应用场景包括但不限于新能源材料、半导体、催化剂等领域的高通量

weixin_28695161的博客 414

Python单元测试实战:unittest框架核心架构与工程化实践

单元测试是软件工程中保障代码质量的核心实践,它通过自动化验证代码单元的正确性,确保软件在迭代过程中保持稳定。其原理在于隔离被测代码,模拟各种输入与边界条件,通过断言验证输出是否符合预期。在Python生态中,unittest作为标准库内置的测试框架,提供了严谨的测试骨架和完整的测试生命周期管理,对于构建长期维护的大型项目或基础库具有独特的工程价值。它能有效支持软件测试项目实战,通过模拟(Mock)技术隔离外部依赖,实现快速、稳定的测试执行,并可与CI/CD流水线无缝集成,是构建健壮软件交付流程的关键环节。本

diaohuyi6830的博客 467

DGX Spark上PyTorch GPU环境配置实战:CUDA 13.0与ARM架构全流程

在深度学习中,CUDA作为GPU加速计算的底层基础,其版本与深度学习框架(如PyTorch)的匹配直接影响模型训练的效率与稳定性。GPU环境配置不仅涉及驱动、CUDA工具链与框架运行时的协同,还依赖于硬件架构与预构建包的兼容性。在AI开发机Ubuntu系统上,正确对齐CUDA版本、计算能力架构及安装源,是避免环境故障、发挥硬件算力的关键。无论是面向个人AI超算还是通用GPU服务器,掌握版本对齐、路径隔离与验证方法,都能大幅提升开发效率。本文以DGX Spark为例,详解从环境摸底到PyTorch GPU版本

weixin_29483277的博客 219

告别设备管理器混乱!3分钟学会用STM32CubeMX+Zadig定制专属虚拟串口名称

本文详细介绍了如何利用STM32CubeMX和Zadig工具,为STM32的USB虚拟串口(VCP)定制专属设备名称,从而彻底解决多设备连接时设备管理器端口混乱的难题。通过修改产品字符串描述符并替换驱动,开发者可以在设备管理器中清晰识别不同开发板,显著提升调试效率,尤其适用于多设备协同的竞赛或项目开发场景。

a2b3c4d5e的博客 478

Python测试框架对比:doctest、unittest与pytest选型指南

在软件开发中,单元测试是确保代码质量与可靠性的核心实践,它通过验证代码单元的行为是否符合预期来预防缺陷。其原理在于隔离代码片段,模拟各种输入与场景,以自动化方式验证输出。这一实践的技术价值在于提升代码可维护性、支持重构并促进持续集成。在Python生态中,测试框架的选择直接影响开发效率与工程实践。doctest将文档与测试结合,适合快速验证与示例演示;unittest提供结构化、标准化的测试组织,适合大型项目与团队协作;而pytest以其简洁的语法、强大的固件系统和丰富的插件生态,成为现代Python项目的

cnmik42448的专栏 416

28-手把手教你手写CPU-Verilog - 乘法器设计:Booth算法与Wallace树乘法器

文章摘要: 本文详细介绍了两种高效乘法器设计方法:Booth算法和Wallace树乘法器。Booth算法通过检测乘数连续1/0减少部分积,适合有符号数运算;Wallace树采用树形结构压缩部分积,显著降低延迟。文章包含算法原理、具体示例、Verilog实现代码(4位乘法器)及性能对比表,指出Booth适用于通用处理器,Wallace树更适合高性能DSP/GPU。最后强调实际设计中需根据速度、面积和功耗需求选择合适方案。

2301_79143213的博客 206

Python接口自动化测试:UnitTest框架核心原理与实战应用

在软件测试领域,自动化测试是提升效率和保障质量的关键技术。其核心原理在于通过脚本模拟用户操作,自动执行测试用例并验证结果,从而替代重复的人工测试。这一技术价值在于能够实现快速回归测试、提高测试覆盖率,并支持持续集成流程。在接口测试这一重要应用场景中,自动化测试能够高效验证API的功能、性能和稳定性。Python作为主流编程语言,其标准库中的UnitTest框架为构建自动化测试提供了坚实基础。该框架通过TestCase、TestSuite、TestRunner和TestFixture四大核心要素,构建了结构化

weixin_30367169的博客 364

调节桌面图标大小的方法(编程)

如果你对其他操作系统或编程语言有类似的需求,可以根据具体的情况进行相应的调整和搜索相关的库和方法。在编程中,我们可以使用各种桌面应用程序来调节桌面图标的大小。库提供的函数,我们获取了桌面图标的窗口句柄,并使用Windows消息发送方式设置图标的大小。你可以根据自己的需求修改代码中的图标大小值,并在运行代码后观察桌面图标的变化。函数并传入所需的图标大小,这里设置为48x48像素。首先,我们需要使用Python的第三现的方法。首先,我们需要使用Python的第三方库。首先,我们需要使用实现的方法。

CyberFlare的博客 438

基于Python的电商平台商品信息爬取与价格监控系统设计与实现

本文详细介绍了一个基于Python的电商平台商品信息爬取与价格监控系统的设计与实现。系统采用最新的Python爬虫技术栈,包括Scrapy框架、Selenium自动化测试工具、BeautifulSoup解析库等,实现了对主流电商平台商品信息的自动化采集、存储、分析和可视化展示。文章从系统架构设计、关键技术实现、核心代码解析等方面进行了全面阐述,并提供了完整的代码实现。该系统不仅适用于毕业设计,也可作为商业价格监控系统的原型。关键词:Python爬虫;电商数据采集;价格监控;Scrapy;Selenium;

2201_76125261的博客 963

深入解析unittest单元测试原理与Python接口自动化实战

单元测试是软件质量保障的基石,其核心在于对程序最小可测试单元进行验证。其原理遵循“隔离、自动化、可重复”的原则,通过断言机制对比预期与实际结果。在工程实践中,单元测试思想的价值在于构建快速反馈环,提升代码可维护性与重构信心。对于接口自动化测试而言,将每个接口调用及其验证视为一个测试单元,并应用单元测试框架的组织与执行能力,是实现高效、健壮自动化测试的关键。本文以Python标准库unittest为例,剖析其基于xUnit架构的核心组件(如TestCase、TestSuite、TestFixture)与模板方

weixin_33851177的博客 385

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

Python单元测试实战:unittest框架核心概念与工程实践指南

单元测试是软件工程中保障代码质量的基础实践,通过隔离验证最小代码单元的功能正确性。其核心原理在于构建自动化、可重复的验证流程,以替代低效的手动测试。在Python生态中,unittest作为标准库提供的测试框架,基于经典的xUnit架构,为组织测试用例、管理测试环境提供了标准化方案。通过测试夹具(TestFixture)管理前置与清理操作,结合丰富的断言方法,能有效验证业务逻辑。在工程实践中,unittest常用于构建持续集成流水线中的自动化测试环节,尤其适合验证数据处理、API接口等模块的稳定性。本文以u

weixin_30634661的博客 423

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

unittest之TextTestRunner类详解

TextTestRunner 不知道如何翻译这个单词才好,我就叫它文本类测试用例运行器吧,大概就这个意思。 通过前两篇对TestCase和TestSuite类的详解,我们都知道他们都有一个自己的run方法,其实我们可以直接调用他们各自的run方法就可以执行我们的测试用例或测试集了,我们只需要初始化一个TestResult类或者其子类的实例传入到第一个参数即可,比如: import sys...

fengguangke的博客 1万+

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

unittest之TestCase类详解

TestCase 测试用例类,我们做单元测试时编写的测试用例就是继承TestCase类来实现具体的测试用例 \ 例如: import unittest class UserCase(unittest.TestCase): def testAddUser(self): print(&amp;quot;add a user&amp;quot;) def testDelUser(self): ...

fengguangke的博客 3万+

unittest篇3-测试套件(TestSuite)详解

1、前言 1、前面unittest篇博客中,有提到怎么去编写一个简单的TestCase,那么多个用例(TestCase)集合在一起就是TestSuite。 2、测试套件就是用来负责组织测试运行的。 2、实现 2.1 创建一个测试套件 suite = suite=unittest.TestSuite() 2.2 加载case到Suite中 2.2.1 通过单条case进行加载到测试套件中 测试用例以上篇博客的测试用例为例 import unittest class TestCaseDemo(unittes

m0_47127594的博客 8623

测试用例(Test Case)如何编写?

一、什么是测试用例? 测试用例(Test Case)是指对一项特定的软件产品进行测试任务的描述,体现测试方案、方法、技术和策略。其内容包括测试目标、测试环境、输入数据、测试步骤、预期结果、测试脚本等,最终形成文档。简单地认为,测试用例是为某个特殊目标而编制的一组测试输入、执行条件以及预期结果,用于核实是否满足某个特定软件需求。 二、测试用例的作用? 1、指导测试的实施 测试用例主要适用于集成测试、...

weixin_44218159的博客 7万+

3.3 unittest框架报告生成-- 常用三种

测试代码如下(测试用例类): @ddt class TestRegister(unittest.TestCase): @data(*cases) def test_register(self, case_data): case_row = int(case_data.case_id.split("_")[1]) + 1 actual_result = register(*case_data.data) # *进行解包,调用login re

Following my own heart 707

python软件测试框架——unittest

介绍了unittest框架的核心要素和使用。

qq_52331239的博客 911

《基于Python的全栈自动化测试》之unittest.TextTestRunner、HTMLTestRunnerNew --- 生成测试报告

前言: 上章讲过,使用 TextTestRunner 执行测试用例,实际上TextTestRunner和HTMLTestRunner 都是在TestRunner进行的拓展,它们都是调用父类(TestRunner)的方法来执行测试用例,只不过生成的测试报告样式不同! TextTestRunner: 首先来看 TextTestRunner的参数和使用方法: ...

waitan2018的博客 7458

自动化测试 | UnitTest框架

2. suite.addTest(unittest.makeSuite(类名)) # 添加指定类中所有已test开头的方法。2. 实例化后去执行套件对象 runner = unittest.TextTestRunner()1. suite.addTest(类名("方法名称")) # 添加指定类中指定的测试方法。2. 获取测试套件对象 suite = unittest.TestSuite()1. 运行测试类所有的测试方法,光标定位到类当前行右键运行。2. 运行单个测试方法:光标放到测试方法当前行。

大胆尝试,小心实践 1333
上一篇: python之文件操作、对.txt文本文件的操作(读、写、修改、复制、合并)、对json文本文件的操作、json字符串与字典的相互转换。
下一篇: python之异常、异常的捕获、else、finally、主动抛出异常raise
马到成功.
博客等级 码龄6年 103粉丝 44原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值