1. UnitTest 命令行接口及测试用例自动发现

1.1 UnitTest 命令行接口

  1. unittest 模块可以通过命令行运行模块、类和独立测试方法的测试:
  2. python -m unittest test_module1 test_module2<br /> python -m unittest test_module.TestClass <br /> python -m unittest test_module.TestClass.test_method
  3. 这里-m 的作用是 意思是将库中的python模块用作脚本去运行
  4. 你可以传入模块名、类或方法名或他们的任意组合。

例子 4-1:

  **         文件目录: **

          ![image.png](https://cdn.nlark.com/yuque/0/2022/png/25630832/1642344454588-43dc9d60-3b07-476c-ab71-3f048ae56256.png#clientId=u241961ff-2caf-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=145&id=u21b4d674&margin=%5Bobject%20Object%5D&name=image.png&originHeight=82&originWidth=159&originalType=binary&ratio=1&rotation=0&showTitle=false&size=3271&status=done&style=none&taskId=u778cae10-740a-4631-be69-2323ad5de0f&title=&width=282)<br />           **   **<br />**               Test_A_B.py  代码**
# -*- coding:utf-8 -*-
# Author: tang_ren_li
# 2021-1-6 22:45

import unittest

class  Test_A(unittest.TestCase):

       def test_caseA1(self):
            print("test_case A1 is run !")
            pass

       def test_caseA2(self):
           print("test_case A2 is run !")
           pass

       def test_caseA3(self):
           print("test_case A3 is run !")
           pass


class Test_B(unittest.TestCase):

       def test_caseB1(self):
           print("test_case B1 is run !")
           pass

       def test_caseB2(self):
           print("test_case B2 is run !")
           pass

       def test_caseB3(self):
           print("test_case B3 is run !")
           pass

包含Test_A 和Test_B 类 里面各有3个测试用例

Test_C.py 代码

# -*- coding:utf-8 -*-
# Author: tang_ren_li
# 2021-1-6 22:45


import unittest


class Test_C(unittest.TestCase):

    def test_caseC1(self):
        print("test_case C1 is run !")
        pass

    def test_caseC2(self):
        print("test_case C2 is run !")
        pass

    def test_caseC3(self):
        print("test_case C3 is run !")
        pass

Test_C 也包含3个测试用例

因此通过命令行执行测试用例的方法是:

1 . 首先进入模块所在的目录:D:\test

  1. 执行多个模块的测试用例: python -m unittest Test_A_B Test_C

运行结果:
image.png
可见2个模块所有测试用例都被执行了

  1. 执行某个测试模块的某个测试类。 python -m unittest Test_A_B.Test_B

image.png

  1. 执行某个测试模块的某个测试类中的某个测试用例。 python -m unittest Test_C.Test_C.test_caseC3

image.png

1.2 UnitTest 测试用例自动发现

Unittest支持简单的测试搜索。若需要使用探索性测试,所有的测试文件必须是 模块 或包。

那么什么是模块,什么是包?

1.2.1 关于Python 中的模块和包

关于Python 中的模块

模块是包含 Python 定义和语句的文件。其文件名是模块名加后缀名 .py 。在模块内部,通过全局变量 name 可以获取模块名(即字符串)。简单理解就是我们一个一个的python文件。

通常我们可以通过IDE 运行模块 ,也可以在命令行通过Pyhton 命令运行模块。

比如 在当前目录, Python Test_A_B.py 注意一定要加后缀

标准模块:

Python 自带一个标准模块的库,它在 Python 库参考(此处以下称为”库参考” )里另外描述。 一些模块是内嵌到编译器里面的, 它们给一些虽并非语言核心但却内嵌的操作提供接口,要么是为了效率,要么是给操作系统基础操作例如系统调入提供接口。 这些模块集是一个配置选项, 并且还依赖于底层的操作系统

比如我们的Unittest 模块就被包含在标准库里。Pytest 则是第三方开发的开源包。

关于Python 中的包

包是一种用“点式模块名”构造 Python 模块命名空间的方法。例如,模块名 A.B 表示包 A 中名为 B 的子模块

从物理上看,包就是一个文件夹,在该文件夹下包含了一个 init.py 文件,该文件夹可用于包含多个模块源文件;从逻辑上看,包的本质依然是模块。

根据上面介绍可以得到一个推论,包的作用是包含多个模块,但包的本质依然是模块,因此包也可用于包含包

比如:
image.png
Unittest 就是一个包 ,而Test 文件夹也是一个包, 被包含在Unittest 里面,包可以包含包。 而 case.py 就是一个模块。

当然包的导入, 模块的导入,都是通过import 这里就不在赘述了。

1.2.2 Python中测试用例自动发现的实现

探索性测试在 TestLoader.discover() 中实现,但也可以通过命令行使用。它在命令行中的基本用法如下:cd project_directory python -m unittest discover

使用Python -m unittest 不带任何参数可以发现当前目录下的测试用例。Python -m unittest discover -v可以显示详细的测试结果。

image.png

Discover 可以使用的参数列表:
image.png

其中:
-f, —failfast
当出现第一个错误或者失败时,停止运行测试

2. UnitTest 测试用例的管理和组织

2.1 前言

    我们先来回顾一下 第三节 关于断言的那个例子:  

例子 3-2 example_3-2. py

# -*- coding:utf-8 -*-
# Author: tang_ren_li
# 2021-1-16 20:00
import unittest

str0="xiao zhu "
str1="xiao he"
str2="xiao bing"
str3="xiao"
str4="xiao zhu "

class A():
    pass
class B():
    pass

a=A() #实例化A

b=B() #实例化B


def Demo_no_return():
    print('no return')

def Demo_return():
    return 'return'


class  Assert_test_demo1(unittest.TestCase):

       def  test_case1(self):
           print('case 1  验证arg1==arg2,不等则fail')
           self.assertEqual(str0,str4,)

       def test_case2(self):
           print('case 2 验证arg1 != arg2, 相等则faill')
           self.assertNotEqual(str0, str1)

       def test_case3(self):
           print('case 3 验证expr是true,如果为false,则fail')
           self.assertTrue(1==1)

       def test_case4(self):
           print('case 4 验证expr是true,如果为false,则fail')
           self.assertFalse(1>2)

       def test_case5(self):
           print('case 5 验证arg1、arg2是同一个对象,不是则fail')
           self.assertIs(a,b,'a,b 不是一个对象 所以 Fail') #这里传入了测试Fail的msg

       def test_case6(self):
           print('case 6 验证arg1、arg2不是同一个对象,是则fail')
           self.assertIsNot(a,b)

       def test_case7(self):
            print('case 7 验证expr是None,不是则fail') #可以用例判断是否采集或抓取到数据
            self.assertIsNone(Demo_no_return())

       def test_case8(self):
            print('case 8 验证expr不是None,是则fail')
            self.assertIsNotNone(Demo_return())

       def test_case9(self):
           print('case 9 验证arg1是arg2的子串,不是则fail')
           self.assertIn(str3,str1) #

       def test_case10(self):
           print('case 10 验证arg1不是arg2的子串,是则fail')
           self.assertNotIn(str1,str3)

       def test_case11(self):
           print('case 11 验证obj是cls的实例,不是则fail')  #
           self.assertIsInstance(a,A)

       def test_case12(self):
           print('case 12 验证obj不是cls的实例,是则fail')
           self.assertNotIsInstance(b,A)


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

执行结果:

image.png

我们已经知道, 通过unittest.main可以收集执行本模块的所有测试用例, 但发现当前的测试用例执行的顺序并没有按照我们case代码编写的顺序执行。 那么该如何解决这个问题, 那么就需要用我们unitest的其它关键组件,对测试用例进行管理和组织

注:

unittest执行测试用例,默认是根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z
但在本例中, testcase10 11 12 由于是数字1开头,反而在test_case2 之前执行。

2.2 TestSuite与TextTestRunner结合-Testsuit.addTest()

先看下面的一个例子:

例子 4-2:

目录结构:

![image.png](https://cdn.nlark.com/yuque/0/2022/png/25630832/1642483491468-3175ab9b-cad4-44a0-8b42-490609fff4ca.png#clientId=ufa85ceb5-c586-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=239&id=u28a70cc1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=364&originWidth=350&originalType=binary&ratio=1&rotation=0&showTitle=false&size=17469&status=done&style=none&taskId=ubd3d364d-66cf-4388-8c4d-9c221dfc589&title=&width=230)<br />**    **<br />**      run 包:**<br />       **case_make_suit.py** :    对test_case包里的测试用例进行组织 ,形成测试套件test_suit   <br />       **run.py** :  程序的入口, 运行所有测试套件

   **test_case  包:**<br />       包含所有测试模块, 测试模块的测试类,及测试类中的测试用例<br />       <br />**     代码:**<br />    <br />       Test_A_B. py  和  Test_C.py  就是  例子4-1   <br />       Test_D.py  是例子 3-2  , 然后去掉  if __name__ == '__main__':  函数<br />   <br />**      case_make_suit.py  **
# -*- coding:utf-8 -*-
# Author: tang_ren_li
# 2021-1-18 20:00

#导入test_case 包中的测试用例
from example_4_2.test_case.Test_A_B import *
from example_4_2.test_case.Test_C import *
from example_4_2.test_case.Test_D import *


def suit_1():

    suit = unittest.TestSuite()#实例化 suit 对象

    #增加 测试用例 

    suit.addTest(Test_A('test_caseA2'))
    suit.addTest(Test_A('test_caseA1'))
    suit.addTest(Test_A('test_caseA3'))
    suit.addTest(Assert_test_demo1('test_case1'))
    suit.addTest(Assert_test_demo1('test_case2'))
    suit.addTest(Assert_test_demo1('test_case3'))
    suit.addTest(Assert_test_demo1('test_case4'))
    suit.addTest(Assert_test_demo1('test_case5'))
    suit.addTest(Assert_test_demo1('test_case6'))
    suit.addTest(Assert_test_demo1('test_case7'))
    suit.addTest(Assert_test_demo1('test_case9'))
    suit.addTest(Assert_test_demo1('test_case10'))
    suit.addTest(Assert_test_demo1('test_case11'))
    suit.addTest(Assert_test_demo1('test_case12'))

    return suit  # 范围suit对象


run.py


# -*- coding:utf-8 -*-
# Author: tang_ren_li
# 2021-1-18 20:00

import unittest
from case_make_suit import *
if __name__ == '__main__':

    runner = unittest.TextTestRunner(verbosity=2)#实例化运行对象

    runner.run(suit_1())#调用run 方法并传入 suit_1()

运行结果:

test_caseA2 (example_4_2.test_case.Test_A_B.Test_A) … ok
test_caseA1 (example_4_2.test_case.Test_A_B.Test_A) … ok
test_caseA3 (example_4_2.test_case.Test_A_B.Test_A) … ok
test_case1 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case2 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case3 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case4 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case5 (example_4_2.test_case.Test_D.Assert_test_demo1) … FAIL
test_case6 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case7 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case9 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case10 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case11 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case12 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok

说明:

  1. runner 运行了所有添加到suit_1 的测试用例 ,并且是按照添加顺序执行测试用例
  2. textTestRunner可以传入参数,来定制测试数据的形式。 verbosity=2 和unittest.mian()函数

    里面参数是一个意思,显示详细测试结果,      
    

很明显如果测试用例很多,一条一条加不现实, TestSuite 类还提供了addTests() 方法 通过列表形式传入

2.3 TestSuite与TextTestRunner结合-Testsuit.addTests()

例子 4-3:

在4-2的基础上增加一个suit_2

case_make_suit.py :


# -*- coding:utf-8 -*-
# Author: tang_ren_li
# 2021-1-18 20:00

#导入test_case 包中的测试用例
from example_4_2.test_case.Test_A_B import*
from example_4_2.test_case.Test_C import *
from example_4_2.test_case.Test_D import *

def suit_2():

    suit = unittest.TestSuite()

    test_case_list= [Test_A('test_caseA1'),Test_A('test_caseA2'),Test_A('test_caseA3'),
                Assert_test_demo1('test_case1'),Assert_test_demo1('test_case2'),Assert_test_demo1('test_case3'),
                Assert_test_demo1('test_case4'), Assert_test_demo1('test_case5'), Assert_test_demo1('test_case6'),
                Assert_test_demo1('test_case7'), Assert_test_demo1('test_case8'), Assert_test_demo1('test_case9'),
                Assert_test_demo1('test_case10'), Assert_test_demo1('test_case11'), Assert_test_demo1('test_case12'),
                   ]
    suit.addTests(test_case_list)

    return suit

run.py :

import unittest
from case_make_suit import *
if __name__ == '__main__':

    runner = unittest.TextTestRunner(verbosity=2)#实例化运行对象

    runner.run(suit_2())#调用run 方法并传入 suit_2()

运行结果:

test_caseA2 (example_4_2.test_case.Test_A_B.Test_A) … ok
test_caseA1 (example_4_2.test_case.Test_A_B.Test_A) … ok
test_caseA3 (example_4_2.test_case.Test_A_B.Test_A) … ok
test_case1 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case2 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case3 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case4 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case5 (example_4_2.test_case.Test_D.Assert_test_demo1) … FAIL
test_case6 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case7 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case9 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case10 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case11 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case12 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok

说明:

  1. 由于addTests 方法传入的是一个列表 ,而列表是可以循环操作的。 这样增加多个case 可以通过,case命名的规则进行批量添加


    当然依然不够简便

2.4 使用加载器Testloader

       unittest.TestLoader()提供了创建test suite的几种方法:  

   1.TestLoader().loadTestsFromTestCase(testCaseClass)<br />       2.TestLoader().loadTestsFromModule(module, pattern=None)<br />       3. TestLoader().loadTestsFromName(name, module=None)<br />       4.TestLoader().loadTestsFromNames(name, module=None)<br />       5.TestLoader().discover  #  前面的 discover 出现了

    下面一一列举其用法,并会感叹unittest的精妙之处。

  - loadTestsFromTestCase(testCaseClass)<br />testCaseClass必须是TestCase的子类(或孙类也行)
  - loadTestsFromModule(module, pattern=None)<br />test case所在的module
  - loadTestsFromName(name, module=None)<br />name是一个string,string需要是是这种格式的“module.class.method”
  - loadTestsFromNames(name, module=None)<br />names是一个list,用法与上同
  - discover(start_dir, pattern=’test*.py’, top_level_dir=None)<br />从python文件中获取test cases

2.4.1 loadTestsFromTestCase(testCaseClass)

代码:

case_make_suit.py : 通过加载指定测试用例类,增加suit_load()_1实现

# -*- coding:utf-8 -*-
# Author: tang_ren_li
# 2021-1-18 20:00

#导入test_case 包中的测试用例

from example_4_2.test_case.Test_A_B import *
from example_4_2.test_case.Test_C import *
from example_4_2.test_case.Test_D import *

def suit_loadCase_1():

    suit = unittest.TestSuite()

    testcase_1=unittest.TestLoader().loadTestsFromTestCase(Test_A)
    testcase_2=unittest.TestLoader().loadTestsFromTestCase(Assert_test_demo1)

    suit.addTests(testcase_1)
    suit.addTests(testcase_2)

    return suit

对应得run.py 模块也要做相应的修改呀,这里就不啰嗦了

运行结果:

test_caseA1 (example_4_2.test_case.Test_A_B.Test_A) … ok
test_caseA2 (example_4_2.test_case.Test_A_B.Test_A) … ok
test_caseA3 (example_4_2.test_case.Test_A_B.Test_A) … ok
test_case1 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case10 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case11 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case12 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case2 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case3 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case4 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case5 (example_4_2.test_case.Test_D.Assert_test_demo1) … FAIL
test_case6 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case7 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case8 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case9 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok

说明:

  1. 通过Testloader() 实例化对象, 然后调用 loadTestsFromTestCase ,传入类名做为

    参数,传入类必须继承testcase 类

  2. 一个测试类可以包含很多测试用例, 而且只需传一次参就可以,当然很方便

    1. 但每个类里的测试用例的执行顺序还是默认的,可以通过把需要先执行的测试用例
      放到一个类中, 把后执行的测试用例放到另外的类中,来实现控制测试用例执行的顺序

      2.4.2 loadTestsFromModule(module, pattern=None)

      代码:

case_make_suit.py : 通过加载指定测试用例类,增加suit_load()_2实现

# -*- coding:utf-8 -*-
# Author: tang_ren_li
# 2021-1-18 20:00

import unittest

#这里直接从包里导出模块就行了
from example_4_2.test_case import Test_A_B
from example_4_2.test_case import Test_D


def suit_loadCase_2():

    suit = unittest.TestSuite()

    testcase_1=unittest.TestLoader().loadTestsFromModule(Test_A_B)
    testcase_2 = unittest.TestLoader().loadTestsFromModule(Test_D)

    suit.addTests(testcase_1)
    suit.addTests(testcase_2)


    return suit

运行结果:

test_caseA1 (example_4_2.test_case.Test_A_B.Test_A) … ok
test_caseA2 (example_4_2.test_case.Test_A_B.Test_A) … ok
test_caseA3 (example_4_2.test_case.Test_A_B.Test_A) … ok
test_caseB1 (example_4_2.test_case.Test_A_B.Test_B) … ok
test_caseB2 (example_4_2.test_case.Test_A_B.Test_B) … ok
test_caseB3 (example_4_2.test_case.Test_A_B.Test_B) … ok
test_case1 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case10 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case11 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case12 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case2 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case3 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case4 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case5 (example_4_2.test_case.Test_D.Assert_test_demo1) … FAIL
test_case6 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case7 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case8 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok
test_case9 (example_4_2.test_case.Test_D.Assert_test_demo1) … ok

说明:

  1. 通过模块导入 也之需要传入一个参数,那就是模块名称 ,前提是模块已经被导入

2.4.3 loadTestsFromName(name, module=None)

代码:

import unittest

from example_4_2.test_case.Test_A_B import *
from example_4_2.test_case.Test_C import *
from example_4_2.test_case.Test_D import *

from example_4_2.test_case import Test_A_B
from example_4_2.test_case import Test_D


import sys

sys.path.append(r'D:\test\example_4_2\test_case') 
#需要将testcase 所在模块路径加入到python系统路径     


def suit_loadCase_3():

    suit = unittest.TestSuite()

    testcase_1 = unittest.TestLoader().loadTestsFromName("Test_A_B.Test_A.test_caseA1")
                                                          #模块名.类名.方法名 
    testcase_2 = unittest.TestLoader().loadTestsFromName("Test_C.Test_C.test_caseC2")

    suit.addTests(testcase_1)

    suit.addTests(testcase_2)

    return suit

运行结果:
image.png

说明 :

  1. 这个方法和addTest 方法功能类似, 由于是一个一个测试用例加入,在一般情况不建议使用 ,要注意一下这里传入的是一个引人格式的字符串

2.4.4 loadTestsFromNames(name, module=None)

代码:

import unittest

from example_4_2.test_case.Test_A_B import *
from example_4_2.test_case.Test_C import *
from example_4_2.test_case.Test_D import *

from example_4_2.test_case import Test_A_B
from example_4_2.test_case import Test_D


import sys
sys.path.append(r'D:\test\example_4_2\test_case') 
#需要将testcase 所在模块路径加入到python系统路径    


def suit_loadCase_4():

    suit = unittest.TestSuite()

    testcaselist=["Test_A_B.Test_A.test_caseA1","Test_C.Test_C.test_caseC2"]

    testcase_1 = unittest.TestLoader().loadTestsFromNames(testcaselist)

    suit.addTests(testcase_1)


    return suit


运行结果:

image.png

说明 :

  1. 这个方法和addTests 方法功能类似, 这里传入的是一个引人格式的字符串list ,如果需要保证测试用例严格的执行次序要求可以通过这个方法

2.4.5 discover(start_dir,pattern=’test*.py’top_level_dir=None) (重要)

代码:

# -*- coding:utf-8 -*-
# Author: tang_ren_li
# 2021-1-18 20:00

import unittest

from example_4_2.test_case.Test_A_B import *
from example_4_2.test_case.Test_C import *
from example_4_2.test_case.Test_D import *

from example_4_2.test_case import Test_A_B
from example_4_2.test_case import Test_D

import sys
sys.path.append(r'D:\test\example_4_2\test_case')


def suit_loadCase_5():

    suit = unittest.TestSuite()

    testcase1 = unittest.TestLoader().discover(r'D:\test\example_4_2\test_case')
    testcase2= unittest.TestLoader().discover(r'D:\test\example_4_2\test_case','Test_A*')

    suit.addTests(testcase1)
    suit.addTests(testcase2)

    return suit

执行结果:

#testcase1 执行:

test_caseA1 (Test_A_B.Test_A) … ok
test_caseA2 (Test_A_B.Test_A) … ok
test_caseA3 (Test_A_B.Test_A) … ok
test_caseB1 (Test_A_B.Test_B) … ok
test_caseB2 (Test_A_B.Test_B) … ok
test_caseB3 (Test_A_B.Test_B) … ok
test_caseC1 (Test_C.Test_C) … ok
test_caseC2 (Test_C.Test_C) … ok
test_caseC3 (Test_C.Test_C) … ok
test_case1 (Test_D.Assert_test_demo1) … ok
test_case10 (Test_D.Assert_test_demo1) … ok
test_case11 (Test_D.Assert_test_demo1) … ok
test_case12 (Test_D.Assert_test_demo1) … ok
test_case2 (Test_D.Assert_test_demo1) … ok
test_case3 (Test_D.Assert_test_demo1) … ok
test_case4 (Test_D.Assert_test_demo1) … ok
test_case5 (Test_D.Assert_test_demo1) … FAIL
test_case6 (Test_D.Assert_test_demo1) … ok
test_case7 (Test_D.Assert_test_demo1) … ok
test_case8 (Test_D.Assert_test_demo1) … ok
test_case9 (Test_D.Assert_test_demo1) … ok

#testcase2 执行:

test_caseA1 (Test_A_B.Test_A) … ok
test_caseA2 (Test_A_B.Test_A) … ok
test_caseA3 (Test_A_B.Test_A) … ok
test_caseB1 (Test_A_B.Test_B) … ok
test_caseB2 (Test_A_B.Test_B) … ok
test_caseB3 (Test_A_B.Test_B) … ok

说明:

  1. discover()方法在 章节 1.2.2 Python中测试用例自动发现的实现 已经提到
  2. 这里使用了2个参数 , 第一个参数表示搜索的开始目录, 第二个参数指定模糊搜索的条件 , 通过2个参数的组合可以准确定义模块级别执行的测试用例
  3. dicover()使用相对简单, 适用于测试模块多, 测试用例数目的情况,是当前主要的收集组织测试用例的方法