部分内容来自:https://www.cnblogs.com/klb561/p/8858122.html

一、基础介绍

核心概念:test case, testsuite, TestLoder,TextTestRunner,TextTestResult, test fixture

TestCase(测试用例): 所有测试用例的基类,它是软件 测试中最基本的组成单元。

一个test case就是一个测试用例,是一个完整的测试流程,包括测试前环境的搭建setUp,执行测试代码(run),以及测试后环境的还原(tearDown)。测试用例是一个完整的测试单元,可以对某一问题进行验证。

TestSuite(测试套件):多个测试用例test case集合就是TestSuite,TestSuite可以嵌套TestSuite

TestLoder:是用来加载 TestCase到TestSuite中,其中有几个loadTestsFrom_()方法,就是从各个地方寻找TestCase,创建他们的实例,然后add到TestSuite中,再返回一个TestSuite实例

TextTestRunner:是来执行测试用例的,其中的run(test)会执行TestSuite/TestCase中的run(result)方法。

 TextTestResult:测试结果会保存到TextTestResult实例中,包括运行了多少用例,成功与失败多少等信息

TestFixture:又叫测试脚手,测试代码的运行环境,指测试准备前和执行后要做的工作,包括setUp和tearDown方法

二、测试流程

1)unittest是Python自带的单元测试框架,我们可以用其来作为我们自动化测试框架的用例组织执行框架。

2)unittest的流程:写好TestCase,然后由TestLoader加载TestCase到TestSuite,然后由 TextTestRunner来运行TestSuite,运行的结果保存在TextTestResult中,我们通过命令行或者unittest.main()执行时,main会调用TextTestRunner中的run来执行,或者我们可以直接通过 TextTestRunner来执行用例。

3)一个class继承unittest.TestCase即是一个TestCase,其中以 test 开头的方法在load时被加载为一个真正的TestCase。

4)verbosity参数可以控制执行结果的输出,0 是简单报告、1 是一般报告、2 是详细报告。

5)可以通过addTest和addTests向suite中添加case或suite,可以用TestLoader的loadTestsFrom__()方法。

6)用 setUp()tearDown()setUpClass()以及 tearDownClass()可以在用例执行前布置环境,以及在用例执行后清理环境

7)我们可以通过skip,skipIf,skipUnless装饰器跳过某个case,或者用TestCase.skipTest方法。

8)参数中加stream,可以将报告输出到文件:可以用TextTestRunner输出txt报告,以及可以用HTMLTestRunner输出html报告。

三、unittest模块的各个属性说明

1、unittest的属性如下:

['BaseTestSuite', 'FunctionTestCase', 'SkipTest', 'TestCase', 'TestLoader', 'TestProgram', 'TestResult', 'TestSuite', 'TextTestResult', 'TextTestRunner', '_TextTestResult', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', '__unittest', 'case', 'defaultTestLoader', 'expectedFailure', 'findTestCases', 'getTestCaseNames', 'installHandler', 'loader', 'main', 'makeSuite', 'registerResult', 'removeHandler', 'removeResult', 'result', 'runner', 'signals', 'skip', 'skipIf', 'skipUnless', 'suite', 'util']

说明:

unittest.TestCase:TestCase类,所有测试用例类继承的基本类。

class BaiduTest(unittest.TestCase):

unittest.main():使用她可以方便的将一个单元测试模块变为可直接运行的测试脚本,main() 方法使用TestLoader类来搜索所有包含在该模块中以“test”命名开头的测试方法,并自动执行他们。执行方法的默认顺序是:根据ASCII码的 顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。所以以A开头的测试用例方法会优先执行,以a开头会后执行。

unittest.TestSuite():unittest框架的TestSuite()类是用来创建测试套件的。

unittest.TextTextRunner():unittest框架的TextTextRunner()类,通过该类下面的run()方法来运行suite所组装的测试用例,入参为suite测试套件。

unittest.defaultTestLoader(): defaultTestLoader()类,通 过该类下面的discover()方法可自动更具测试目录start_dir匹配查找测试用例文件(test*.py),并将查找到的测试用例组装到测试 套件,因此可以直接通过run()方法执行discover。用法如下:

discover=unittest.defaultTestLoader.discover(test_dir, pattern='test_*.py')

unittest.skip():装饰器,当运行用例时,有些用例可能不想执行等,可用装饰器暂时屏蔽该条测试用例。一种常见的用法就是比如说想调试某一个测试用例,想先屏蔽其他用例就可以用装饰器屏蔽。

@unittest.skip(reason): skip(reason)装饰器:无条件跳过装饰的测试,并说明跳过测试的原因。

@unittest.skipIf(reason): skipIf(condition,reason)装饰器:条件为真时,跳过装饰的测试,并说明跳过测试的原因。

@unittest.skipUnless(reason): skipUnless(condition,reason)装饰器:条件为假时,跳过装饰的测试,并说明跳过测试的原因。

@unittest.expectedFailure(): expectedFailure()测试标记为失败。

2、TestCase类的属性如下:

['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_addSkip', '_baseAssertEqual', '_classSetupFailed', '_deprecate', '_diffThreshold', '_formatMessage', '_getAssertEqualityFunc', '_truncateMessage', 'addCleanup', 'addTypeEqualityFunc', 'assertAlmostEqual', 'assertAlmostEquals', 'assertDictContainsSubset', 'assertDictEqual', 'assertEqual', 'assertEquals', 'assertFalse', 'assertGreater', 'assertGreaterEqual', 'assertIn', 'assertIs', 'assertIsInstance', 'assertIsNone', 'assertIsNot', 'assertIsNotNone', 'assertItemsEqual', 'assertLess', 'assertLessEqual', 'assertListEqual', 'assertMultiLineEqual', 'assertNotAlmostEqual', 'assertNotAlmostEquals', 'assertNotEqual', 'assertNotEquals', 'assertNotIn', 'assertNotIsInstance', 'assertNotRegexpMatches', 'assertRaises', 'assertRaisesRegexp', 'assertRegexpMatches', 'assertSequenceEqual', 'assertSetEqual', 'assertTrue', 'assertTupleEqual', 'assert_', 'countTestCases', 'debug', 'defaultTestResult', 'doCleanups', 'fail', 'failIf', 'failIfAlmostEqual', 'failIfEqual', 'failUnless', 'failUnlessAlmostEqual', 'failUnlessEqual', 'failUnlessRaises', 'failureException', 'id', 'longMessage', 'maxDiff', 'run', 'setUp', 'setUpClass', 'shortDescription', 'skipTest', 'tearDown', 'tearDownClass']

说明:

setUp():setUp()方法用于测试用例执行前的初始化工作。如测试用例中需要访问数据库,可以在setUp中建立数据库连接并进行初始化。如测试用例需要登录web,可以先实例化浏览器。

tearDown():tearDown()方法用于测试用例执行之后的善后工作。如关闭数据库连接。关闭浏览器。

assert*():一些断言方法:在执行测试用例的过程中,最终用例是否执行通过,是通过判断测试得到的实际结果和预期结果是否相等决定的。

assertEqual(a,b,[msg='测试失败时打印的信息']):断言a和b是否相等,相等则测试用例通过。

assertNotEqual(a,b,[msg='测试失败时打印的信息']):断言a和b是否相等,不相等则测试用例通过。

assertTrue(x,[msg='测试失败时打印的信息']):断言x是否True,是True则测试用例通过。

assertFalse(x,[msg='测试失败时打印的信息']):断言x是否False,是False则测试用例通过。

assertIs(a,b,[msg='测试失败时打印的信息']):断言a是否是b,是则测试用例通过。

assertNotIs(a,b,[msg='测试失败时打印的信息']):断言a是否是b,不是则测试用例通过。

assertIsNone(x,[msg='测试失败时打印的信息']):断言x是否None,是None则测试用例通过。

assertIsNotNone(x,[msg='测试失败时打印的信息']):断言x是否None,不是None则测试用例通过。

assertIn(a,b,[msg='测试失败时打印的信息']):断言a是否在b中,在b中则测试用例通过。

assertNotIn(a,b,[msg='测试失败时打印的信息']):断言a是否在b中,不在b中则测试用例通过。

assertIsInstance(a,b,[msg='测试失败时打印的信息']):断言a是是b的一个实例,是则测试用例通过。

assertNotIsInstance(a,b,[msg='测试失败时打印的信息']):断言a是是b的一个实例,不是则测试用例通过。

3、TestSuite类的属性如下:(组织用例时需要用到)

['__call__', '__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__iter__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_addClassOrModuleLevelException', '_get_previous_module', '_handleClassSetUp', '_handleModuleFixture', '_handleModuleTearDown', '_tearDownPreviousClass', '_tests', 'addTest', 'addTests', 'countTestCases', 'debug', 'run']

说明:

addTest(): addTest()方法是将测试用例添加到测试套件中,如下方,是将test_baidu模块下的BaiduTest类下的test_baidu测试用例添加到测试套件。

suite = unittest.TestSuite()
suite.addTest(test_baidu.BaiduTest('test_baidu'))
 

4、TextTextRunner的属性如下:(组织用例时需要用到)

['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_makeResult', 'buffer', 'descriptions', 'failfast', 'resultclass', 'run', 'stream', 'verbosity']

说明:

run(): run()方法是运行测试套件的测试用例,入参为suite测试套件。

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

四、使用unittest框架编写测试用例思路

设计基本思路如下,新建一个test.py文件(名称自定义),代码如下

 import unittest

 class Test(unittest.TestCase):
# 定义测试类,父类为unittest.TestCase
# 定义setUp()方法用于测试用例执行前的初始化工作。
def setUp(self):
# 注意,所有类中方法的入参为self,定义方法的变量也要“self.变量”
self.number = input('Enter a number:')
self.number = int(self.number) # 注意,输入的值为字符型的需要转为int型 # 定义测试用例,以“test_”开头命名的方法,方法的入参为self
# 可定义多个测试用例
# 最重要的就是该部分
def test_case1(self):
self.assertEqual(self.number, 10, msg = 'Your input is not 10') def test_case2(self):
print(self.number)
self.assertEqual(self.number, 20, msg = 'Your input is not 20') @unittest.skip('暂时跳过用例3的测试')
def test_case3(self):
print(self.number)
self.assertEqual(self.number, 30, msg = 'Your input is not 30') # 定义tearDown()方法用于测试用例执行之后的善后工作。
# 注意,方法的入参为self
def tearDown(self):
print('Test over') # 执行测试用例方案一如下:
# unittest.main()方法会搜索该模块下所有以test开头的测试用例方法,并自动执行它们。
# 执行顺序是命名顺序:先执行test_case1,再执行test_case2
if __name__ == '__main__':
unittest.main() # 执行测试用例方案二如下(以下整段代码块替换方案一的代码块):
# 1.先构造测试集2.实例化测试套件
if __name__ == '__main__':
suite = unittest.TestSuite()
# 将测试用例加载到测试套件中。
# 执行顺序是安装加载顺序:先执行test_case2,再执行test_case1
suite.addTest(Test('test_case2'))
suite.addTest(Test('test_case1'))
# 执行测试用例,实例化TextTestRunner类,verbosity参数可以控制执行结果的输出,0 是简单报告、1 是一般报告、2 是详细报告
runner = unittest.TextTestRunner(verbosity = 2)
# 使用run()方法运行测试套件(即运行测试套件中的所有用例)
runner.run(suite) # 执行测试用例方案三如下(以下整段代码块替换方案一的代码块):
# 构造测试集(简化了方案二中先要创建测试套件然后再依次加载测试用例)
# 执行顺序同方案一:执行顺序是命名顺序:先执行test_case1,再执行test_case2
if __name__ == '__main__':
test_dir = './'
# 通过该类下面的discover()方法可自动加载测试目录test_dir匹配查找测试用例文件(test_*.py),并将查找到的测试用例组装到测试套件discover中
discover = unittest.defaultTestLoader.discover(test_dir, pattern = 'test_*.py')
runner = unittest.TextTestRunner()
runner.run(discover)

执行py文件:python test.py

结果:

方案一:因为先执行test_case1,再执行test_case2,所以第一次输入10时,执行通过,返回. 第二次输入10时,执行不通过,返回F,最终一个用例通过,一个用例失败,还有一个用例是直接跳过的(装饰器)

方案二:因为先执行test_case2,再执行test_case1,所以第一次输入10时,执行不通过,返回F , 第二次输入10时,执行通过,返回. ,最终一个用例通过,一个用例失败。

方案三:因为先执行test_case1,再执行test_case2,所以第一次输入10时,执行通过,返回. 第二次输入10时,执行不通过,返回F,最终一个用例通过,一个用例失败,还有一个用例是直接跳过的(装饰器)。

五、测试报告输出:

1. 那如何生成一个测试报告呢,需要加入另外一个模块了,HTMLTestRunner,这个模块需要自己安装,使用执行测试用例就会生成一个html的测试报告

HTMLTestRunner地址:http://tungwaiyip.info/software/HTMLTestRunner.html

注意区分python的版本:2.x与3.x

下载完成后,放到C:\python35\Lib路径里面,然后修改test.py文件

import HTMLTestRunner #导入报告模块

#在if __name__ == '__main__'代码块中,用下面代码块替换runner = unittest.TextTestRunner()
with open('HTMLReport.html', 'w') as f:
runner = HTMLTestRunner(stream=f,
title='MathFunc Test Report',
description='generated by HTMLTestRunner.',
verbosity=2
)
runner.run(suite)

再执行test.py文件后,后在test.py所在目录中生成HTMLReport.html;这个路径可以自行指定

六、测试日志输出:

1. 可以在运行的时候输出日志文件,这个不是那么必要

修改test.py

 import unittest
import time,os,sys,logging sys.path.append(os.path.dirname(os.path.abspath(__file__)) + r'\..') # 返回脚本的路径
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='log_test.log',
filemode='w')
logger = logging.getLogger()
class Test(unittest.TestCase):
#代码略

执行test.py文件后,后在test.py所在目录中生产log_test.log

在上面代码块中的第5行:

INFO:处理请求或者状态变化等日常事务(一般详细)
DEBUG:调试过程中使用DEBUG等级,如算法中每个循环的中间状态(较详细)

七、总代码示例:

1. Tset.py文件

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

import unittest
import time,os,sys,logging
import HTMLTestRunner sys.path.append(os.path.dirname(os.path.abspath(__file__)) + r'\..') # 返回脚本的路径
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s',
datefmt='%a, %d %b %Y %H:%M:%S',
filename='log_test.log',
filemode='w')
logger = logging.getLogger()
class MyTest(unittest.TestCase): # 继承unittest.TestCase def setUp(self):
# 每个测试用例执行之前做操作
print('执行用例开始') def tearDown(self):
# 每个测试用例执行之后做操作
print('执行用例结束') @classmethod
def tearDownClass(self):
# 必须使用 @ classmethod装饰器, 所有test运行完后运行一次
print('--------测试执行结束--------') @classmethod
def setUpClass(self):
# 必须使用@classmethod 装饰器,所有test运行前运行一次
print('--------测试执行开始--------') def test_1_add(self):
"""添加类别信息"""
logger.info("Now: %r", '执行添加')
self.assertEqual(1, 1) def test_2_que(self):
"""查询类别信息"""
logger.info("Now: %r", '执行查询')
self.assertEqual(2, 2) if __name__ == '__main__':
current_time = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime(time.time()))
test_suite = unittest.TestSuite() # 创建一个测试集合
test_suite.addTest(MyTest('test_1_add'))
test_suite.addTest(MyTest('test_2_que'))# 测试套件中添加测试用例
# test_suite.addTest(unittest.makeSuite(MyTest))#使用makeSuite方法添加所有的测试方法
report_path = current_time + '.html' # 生成测试报告的路径
fp = open(report_path, "wb")
runner = HTMLTestRunner.HTMLTestRunner(stream = fp,
title = '自动化测试报告',
description = '用例执行情况:',
verbosity = 2)
runner.run(test_suite)
fp.close()

selenium自动化测试、Python单元测试unittest框架以及测试报告和日志输出的更多相关文章

  1. Selenium with Python 010 - unittest 框架(又称PyUnit 框架)

    unittest进行python代码单元测试 calculator.py--被测试类 #!/usr/bin/env python # -*- coding: utf-8 -*- # 将要被测试的类 c ...

  2. python单元测试unittest框架

    环境:PyCharm 2016.2 + python 3.5 待测试的类:(Widget.py) 测试类:(Auto.py) 测试结果: 总结:1.第一步:先写好测试类2.第二步:导入unittest ...

  3. python之unittest框架实现接口测试实例

    python之unittest框架实现接口测试实例 接口测试的方法有很多种,具体到工具有postman,jmeter,fiddler等,但是工具的局限性是测试数据的组织较差,接口的返回工具的判断有限, ...

  4. 《手把手教你》系列基础篇(八十六)-java+ selenium自动化测试-框架设计基础-Log4j实现日志输出(详解教程)

    1.简介 自动化测试中如何输出日志文件.任何软件,都会涉及到日志输出.所以,在测试人员报bug,特别是崩溃的bug,一般都要提供软件产品的日志文件.开发通过看日志文件,知道这个崩溃产生的原因,至少知道 ...

  5. 《手把手教你》系列基础篇(九十一)-java+ selenium自动化测试-框架设计基础-Logback实现日志输出-下篇(详解教程)

    1.简介 为了方便查看和归档:(1)不同包的日志可能要放到不同的文件中,如service层和dao层的日志:(2)不同日志级别:调试.信息.警告和错误等也要分文件输出.所以宏哥今天主要介绍和分享的是: ...

  6. Python单元测试unittest - 单元测试框架

    一.unittest简介 unitest单元测试框架最初是有JUnit的启发,它支持测试自动化,共享测试的设置和关闭代码,将测试聚合到集合中,以及测试与报告框架的独立性. 二.unittest相关概念 ...

  7. Selenium自动化测试Python二:WebDriver基础

    WebDriver基础 欢迎阅读WebDriver基础讲义.本篇讲义将会重点介绍Selenium WebDriver的环境搭建和基本使用方法. WebDriver环境搭建 Selenium WebDr ...

  8. Selenium自动化测试Python六:持续集成

    持续集成 欢迎阅读WebDriver持续集成讲义.本篇讲义将会重点介绍Selenium WebDriver API的在持续集成中的使用方法,以及使用Jenkins持续集成工具进行自动化测试的设计. 持 ...

  9. Selenium自动化测试Python五:WebDriver设计模式

    WebDriver 设计模式 欢迎阅读WebDriver进阶讲义.本篇讲义将会重点介绍Selenium WebDriver 自动化框架的设计,着重使用Page Object设计模式,以及使用HTML测 ...

随机推荐

  1. xj监控端口,模拟登陆脚本

    #!/bin/bash date=`date +%Y%m%d-%H%M` count=0 ip1=124.117.246.195 ip2=124.117.246.194 port1=(443 80 6 ...

  2. PyCharm 2017.2.2+PyQt5+Python3.6.0

    PyCharm注册地址 http://idea.imsxm.com/ 安装的是miniconda激活虚拟环境执行pip install PyQt5pip install PyQt5-tools 从官网 ...

  3. MySQL 数据库备份种类以及常用备份工具汇总

    1,数据库备份种类 按照数据库大小备份,有四种类型,分别应用于不同场合,下面简要介绍一下: 1.1完全备份 这是大多数人常用的方式,它可以备份整个数据库,包含用户表.系统表.索引.视图和存储过程等所有 ...

  4. 自己写的highcharts级联(点击事件)

    $.fn.extend({ Zhu: function (option) { var id = $(this).attr("id"); $('#' + id).highcharts ...

  5. (转)c# Linq及Lamda表达式应用经验之 GroupBy 分组

    本文转载自:http://www.cnblogs.com/han1982/p/4138163.html 示例1: GroupBy 分组在List<>泛型中的应用 原表: 按姓名Nam 分组 ...

  6. appium运行时启动失败

    1.检查服务是否开启 2.简单Android设备是否连接成功 3.检查4723端口是否被占用: netstat -ano|findstr '4723' 查到被占用后,找到pid,进入任务管理器查看该p ...

  7. Solaris11.1网络配置(Fixed Network)

    Solaris11的网络配置与Solaris10有很大不同,Solaris11通过network configuration profiles(NCP)来管理网络配置. Solaris11网络配置分为 ...

  8. Delphi 转圈 原型进度条 AniIndicator 及线程配合使用

    Delphi FMX 转圈 原型进度条 progress AniIndicator TAniIndicator TFloatAnimation VCL下也有转圈菊花进度条 TActivityIndic ...

  9. import requests

  10. jQuery获取多种值的方法

    **jQuery 1.3.2版本下的 jquery radio取值,checkbox取值,select取值,radio选中,checkbox选中,select选中,及其相关设置** 1.判断是否已经打 ...