Package: test-auto
自动化测试框架，支持多线程和参数化测试，且自带HTML测试报告！主要特性支持IDE和命令行方式执行测试用例。支持多线程测试。支持参数化测试。自带HTML测试报告。支持设置终止策略、重试策略和超时时间。易扩展，开发者可自定义测试任务、测试记录器和测试执行器等。安装在线安装执行以下命令即可安装testauto的最新版本：pip install test-auto如需安装指定版本，比如安装1.0.0版本，可执行以下命令：pip install test-auto==1.0.0离线安装如果已经下载了test_auto-X.X.X-py3-none-any.whl或test-auto-X.X.X.tar.gz安装文件，那么可以使用离线安装方式安装testauto。你可以在PyPI的以下地址找到安装文件：https://pypi.org/project/test-auto/#files或者GitHub的以下地址找到安装文件：https://github.com/lujiatao2/testauto/releases若使用test_auto-X.X.X-py3-none-any.whl安装文件，执行以下命令即可安装testauto：pip install path/to/test_auto-X.X.X-py3-none-any.whl若使用test-auto-X.X.X.tar.gz安装文件，执行以下命令即可安装testauto：pip install path/to/test-auto-X.X.X.tar.gz第一个测试用例来开始使用testauto编写第一个测试用例吧！# case_for_doc.pyfromtestautoimportmainfromtestauto.caseimportTestCaseclassTestCase01(TestCase):deftest_case(self):...if__name__=='__main__':main()执行结果如下：======================================================================================================================================================
执行总数：1
开始时间：2021-01-24 14:48:21    结束时间：2021-01-24 14:48:21    执行耗时：00时00分00秒
------------------------------------------------------------------------------------------------------------------------------------------------------
执行结果      数量        百分比（%）
通过        1         100.0
失败        0         0.0
阻塞        0         0.0
超时        0         0.0
未执行       0         0.0
======================================================================================================================================================测试用例基本用法测试用例使用一个Python类来表示，且该类必须直接或间接继承至TestCase抽象基类才能被testauto识别为测试用例。classTestCase02(TestCase):deftest_case(self):print(self.__class__.__name__)classTestCase03(TestCase02):deftest_case(self):print(self.__class__.__name__)classTestCase04:deftest_case(self):print(self.__class__.__name__)执行以上代码后，可以看到只有TestCase02和TestCase03的类名被打印了。初始化和清理操作测试用例支持添加初始化和清理操作，只需重写setup()和teardown()方法即可。classTestCase05(TestCase):defsetup(self):print('这是初始化操作')deftest_case(self):print('这是测试用例')defteardown(self):print('这是清理操作')执行结果如下：这是初始化操作
这是测试用例
这是清理操作测试用例属性project：测试工程名称，默认为：Default Project。module：测试模块名称，默认为：Default Module。title：测试用例标题，默认为：Default Title。description：测试用例描述，默认：无。priority：测试用例优先级，默认：P0。designer：测试用例设计者，默认：Anonymous。version：测试用例版本号，默认：1.0.0。completed：测试用例完成状态，默认：已完成。以上属性都可以修改，只需在测试用例中显式声明即可。classTestCase06(TestCase):title='登录成功'priority=TestCasePriority.P1completed=Falsedeftest_case(self):...从以上代码可以看出：测试用例优先级使用枚举表示，而不是字符串；而测试用例完成状态是一个布尔类型。测试任务基本用法testauto的执行单元是测试任务，而不是测试用例，即使只有一个测试用例，testauto也会自动将该测试用例转换为测试任务。为什么需要测试任务？比如一个测试项目有1000个测试用例，但对于不同的测试策略（冒烟测试？回归测试？），需要执行的测试用例显然是不同的，因此我们可以创建不同的测试任务。# task_for_doc.pyfromtestauto.taskimportDefaultTestTaskfromtestauto_test.case_for_docimport*# 冒烟测试用例对应的测试任务test_task_01=DefaultTestTask()test_task_01.add_test_cases(TestCase01(),TestCase02())# 回归测试用例对应的测试任务test_task_02=DefaultTestTask()test_task_02.add_test_cases(TestCase01(),TestCase03())if__name__=='__main__':main(test_task=test_task_01)# 执行冒烟测试main(test_task=test_task_02)# 执行回归测试以上代码中的测试用例是上一节case_for_doc.py中的测试用例。添加测试用例除了上一小节介绍的add_test_cases()方法外，还支持多种添加测试用例方法，以下为完整列表：add_test_case()：添加单个测试用例。add_test_cases()：添加多个测试用例。add_test_cases_by_classes()：通过类名增加测试用例，格式：path.to.module.Classadd_test_cases_by_modules()：通过模块名增加测试用例，格式：path.to.moduleadd_test_cases_by_files()：通过文件增加测试用例，格式：Windows：E:\path\to\dictionary\module.pymacOS/Linux：/path/to/dictionary/module.pyadd_test_cases_by_paths()：通过路径增加测试用例，格式：Windows：E:\path\to\dictionarymacOS/Linux：/path/to/dictionary以下演示add_test_cases_by_files()方法的使用：test_task_03=DefaultTestTask()test_task_03.add_test_cases_by_files(r'E:\Software_Testing\Software Development\Python\PycharmProjects\testauto\testauto_test\case_for_doc.py')if__name__=='__main__':main(test_task=test_task_03)除了添加，也可以删除测试用例，对应的方法是remove_test_case()和remove_test_cases()。过滤器过滤器是一个抽象类TestCaseFilter，它的作用是过滤掉不满足要求的测试用例。testauto内置了2个过滤器：TestCaseCompletedShouldBe：根据测试用例完成状态来过滤测试用例。TestCasePriorityShouldBe：根据测试用例优先级来过滤测试用例。比如我们只想执行P0优先级的测试用例，可以这么做：test_task_03=DefaultTestTask()test_task_03.add_test_cases_by_files(r'E:\Software_Testing\Software Development\Python\PycharmProjects\testauto\testauto_test\case_for_doc.py')test_task_03.add_filter(TestCasePriorityShouldBe(OperationMethod.EQUAL,TestCasePriority.P0))test_task_03.filter_test_cases()if__name__=='__main__':main(test_task=test_task_03)从以上代码可以看出：在添加了过滤器后，要真正执行过滤操作，需要调用filter_test_cases()方法。除了添加，也可以删除过滤器，对应的方法是remove_test_filter()和remove_test_filters()。另外，DefaultTestTask默认包含TestCaseCompletedShouldBe过滤器，且过滤条件为OperationMethod.EQUAL和True，即测试用例完成状态等于True的测试用例才会被保留。当然你可以调用clear_test_task()
方法来阻止该行为，该方法会清空测试任务中的所有测试用例和过滤器。命令行执行testauto提供了命令行执行的功能，执行以下命令获取帮助信息：python -m testauto -h执行结果如下：usage: testauto [-h] [-m [TEST_MODULES [TEST_MODULES ...]]] [-t TEST_TASK]
                [-r TEST_RECORDER] [-rn TEST_RUNNER] [-s STOP_STRATEGY]
                [-rt RETRY_STRATEGY] [-to TIMEOUT] [-p PARALLEL]

optional arguments:
  -h, --help            显示帮助信息。
  -m [TEST_MODULES [TEST_MODULES ...]], --test-modules [TEST_MODULES [TEST_MODULES ...]]
                        测试模块。示例：-m E:\path\to\dictionary\module.py
  -t TEST_TASK, --test-task TEST_TASK
                        测试任务。示例：-t path.to.module.callable，其中callable为返回TestTask对象的可调用对象。
  -r TEST_RECORDER, --test-recorder TEST_RECORDER
                        测试记录器。示例：-r path.to.module.callable，其中callable为返回TestRecorder对象的可调用对象。
  -rn TEST_RUNNER, --test-runner TEST_RUNNER
                        测试执行器。示例：-rn path.to.module.callable，其中callable为返回TestRunner对象的可调用对象。
  -s STOP_STRATEGY, --stop-strategy STOP_STRATEGY
                        终止策略。参数取值：0-全部完成（默认）/1-第一个未执行成功/2-第一个P0测试用例未执行成功
  -rt RETRY_STRATEGY, --retry-strategy RETRY_STRATEGY
                        重试策略。参数取值：0-不重试（默认）/1-立即重新执行测试用例/2-最后重新执行测试用例
  -to TIMEOUT, --timeout TIMEOUT
                        超时时间（单位秒）。参数取值：正整数
  -p PARALLEL, --parallel PARALLEL
                        并行执行数量。参数取值：正整数以上帮助信息已经把使用方法说明得很清楚了，以下演示如何使用命令行执行测试任务，新增测试任务test_task_04：deftest_task_04():test_task=DefaultTestTask()test_task.add_test_cases(TestCase01(),TestCase02())returntest_task注意test_task_04要定义为可调用对象，这里定义为了一个函数。执行以下命令可运行test_task_04中的测试用例：python -m testauto -t testauto_test.test_task.test_task_04另外，IDE和命令行均支持直接传入测试模块，但此时若同时传入了测试任务，testauto会忽略测试任务，而使用传入的测试模块自动创建测试任务。多线程测试testauto支持多线程测试，使用方法很简单，通过main()方法传入parallel参数或命令行传入-p/--parallel参数即可。为了演示多线程测试带来的效率上优势，我们首先在case_for_doc.py中新增以下两个测试用例：classTestCase07(TestCase):deftest_case(self):sleep(5)classTestCase08(TestCase):deftest_case(self):sleep(5)然后在task_for_doc.py中新增test_task_05：test_task_05=DefaultTestTask()test_task_05.add_test_cases(TestCase07(),TestCase08())if__name__=='__main__':main(test_task=test_task_05)如果直接执行test_task_05，那么测试耗时是10秒，这时我们加入parallel参数，并将参数值设置为2：if__name__=='__main__':main(test_task=test_task_05,parallel=2)重新执行test_task_05，可以看到耗时为5秒。需要注意的是，多线程执行测试用例时，需考虑线程安全性，如果多个测试用例同时对一个资源进行修改，会造成意想不到的结果。参数化测试testauto使用@parameterized装饰器提供对参数化的支持。首先在case_for_doc.py中新增以下测试用例：@parameterized(('username','password'),[('zhangsan','zhangsan123456'),('lisi','lisi123456')])classTestCase09(TestCase):deftest_case(self):username=self.get_param_value('username')password=self.get_param_value('password')print(f'我的用户名是：{username}，我的密码是：{password}！')@parameterized装饰器的第一个参数是一个字符串类型的元组，每个字符串代表一个参数，可传递多个参数；第二个参数是一个元组组成的列表，每个元组代表一组参数，元组中参数的个数必须与参数数量一致。然后在测试用例中通过get_param_value()
方法来获取参数。在test_task.py中新增test_task_06：test_task_06=DefaultTestTask()test_task_06.add_test_cases_by_classes('testauto_test.case_for_doc.TestCase09')if__name__=='__main__':main(test_task=test_task_06)注意test_task_06添加测试用例的方式不是直接传递测试用例对象，因为参数化测试时，需要根据参数的数量来动态创建测试用例对象，这个过程是testauto自动完成的。执行结果如下：我的用户名是：zhangsan，我的密码是：zhangsan123456！
我的用户名是：lisi，我的密码是：lisi123456！测试报告testauto有5种测试结果：通过：未引发任何异常。失败：引发AssertionError异常。超时：引发TimeoutError异常。阻塞：引发其它异常（非AssertionError和TimeoutError异常）。未执行：未执行。testauto内置的测试记录器DefaultTestRecorder会生成HTML测试报告。为了查看不同测试结果在测试报告中的显示效果，在case_for_doc.py中新增以下3个测试用例：classTestCase010(TestCase):module='TestCase010模块'title='TestCase010标题'deftest_case(self):sleep(1)classTestCase11(TestCase):module='TestCase11模块'title='TestCase11标题'deftest_case(self):sleep(2)assertFalseclassTestCase12(TestCase):module='TestCase12模块'title='TestCase12标题'deftest_case(self):sleep(3)raiseRuntimeError('我是TestCase12，这是我抛的异常！')然后直接执行test_task_03，执行后会生成test-report.html文件，该文件即HTML测试报告。效果如下所示：未执行成功的测试用例，可点击查看详情，效果如下所示：不同的测试结果在HTML测试报告中显示是不同的：通过：显示为绿色，不能点击详情查看。失败：显示为红色，能点击详情查看。阻塞：显示为黄色，能点击详情查看。超时：显示为灰色，能点击详情查看。未执行：显示为白色，不能点击详情查看。其它终止策略testauto支持3种终止策略：ALL_COMPLETED：全部完成，默认。FIRST_NOT_PASS：第一个未执行成功。FIRST_P0_NOT_PASS：第一个P0测试用例未执行成功。终止策略使用StopStrategy枚举来设置：if__name__=='__main__':main(stop_strategy=StopStrategy.FIRST_NOT_PASS)重试策略testauto支持3种重试策略：NOT_RERUN：不重试，默认。RERUN_NOW：立即重新执行测试用例，即：对当前未执行成功的测试用例，立即重新执行一次。RERUN_LAST：最后重新执行测试用例，即：对全部未执行成功的测试用例，最后批量重新执行一次。重试策略使用RetryStrategy枚举来设置：if__name__=='__main__':main(retry_strategy=RetryStrategy.RERUN_NOW)注意终止策略的优先级是大于重试策略的，比如同时设置了FIRST_NOT_PASS和RERUN_NOW，当测试用例执行失败时，testauto会立即终止后续测试用例的执行，而不会对当前测试用例进行重新执行。超时时间使用timeout参数可对单个测试用例设置超时时间：if__name__=='__main__':main(timeout=60)以上代码将单个测试用例的执行超时时间设置为了60秒，默认为1小时（3600秒）。断言作为自动化测试框架，断言功能当然是不能少的，但testauto没有重复造轮子，而是直接使用Python自带的assert关键字来实现断言。比如TestCase11测试用例中断言的写法如下：classTestCase11(TestCase):module='TestCase11模块'title='TestCase11标题'deftest_case(self):sleep(2)assertFalse以上代码直接使用了assert关键字来断言。但testauto也新增了2个断言函数作为补充：assert_raise()：断言抛出指定异常。assert_not_raise()：断言不抛出指定异常。以下为演示代码，可参考这几个测试用例的写法来使用以上断言函数：classTestCase13(TestCase):title='抛出异常成功'deftest_case(self):assert_raise(self._callable_target,RuntimeError)def_callable_target(self):raiseRuntimeError('TestCase13的异常')classTestCase14(TestCase):title='不抛出异常成功'deftest_case(self):assert_not_raise(self._callable_target,ValueError)def_callable_target(self):raiseRuntimeError('TestCase14的异常')classTestCase15(TestCase):title='抛出异常失败'deftest_case(self):assert_raise(self._callable_target,ValueError)def_callable_target(self):raiseRuntimeError('TestCase15的异常')classTestCase16(TestCase):title='不抛出异常失败'deftest_case(self):assert_not_raise(self._callable_target,RuntimeError)def_callable_target(self):raiseRuntimeError('TestCase16的异常')