- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章Python unittest单元测试框架的使用由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
1、测试模型 。
下面这部分来自于某书籍资料,拿过来,按需参考一下:
测试模型 。
(1)线性测试 。
1、概念:
通过录制或编写对应应用程序的操作步骤产生的线性脚本。单纯的来模拟用户完整的操作场景。(操作,重复操作,数据)都混合在一起.
2、优点:每个脚本相对独立,且不产生其他依赖和调用。任何一个测试用例脚本拿出来都可以单独执行.
3、缺点:开发成本高,用例之间存在重复的操作。比如重复的用户登录和退出.
维护成本高,由于重复的操作,当重复的操作发生改变时,则需要逐一进行脚本的修改.
4.线性测试实例:用户登录 。
(2)模块化驱动测试 。
1、概念:
将重复的操作独立成功共模块,当用例执行过程中需要用到这一模块操作时则被调用。 操作+(重复操作,数据)混合在一起。例如,自动化测试的执行需要保持测试用例的独立性和完整性,所以每一条用例在执行时都需要登录和退出操作,so可以把登录和退出的操作封装为公共函数.
2、优点:由于最大限度消除了重复,从而提高了开发效率和提高测试用例的可维护性.
3、缺点:虽然模块化的步骤相同,但是测试数据不同。比如说重复的登录模块,如果登录用户不同,依旧要重复编写登录脚本.
4.实例:对公共模块,例如登陆和退出进行模块化封装 。
(3)数据驱动测试 。
1、概念:它将测试中的测试数据和操作分离,数据存放在另外一个文件中单独维护.
通过数据的改变从而驱动自动化测试的执行,最终引起测试结果的改变.
操作+重复操作+数据分开.
2、优点:
通过这种方式,将数据和重复操作分开,可以快速增加相似测试,完成不同数据情况下的测试.
3、实例从excel表格读取用户名密码,登录邮箱.
2、unittest框架 。
用Python搭建自动化测试框架,需要组织用例以及测试执行,大部分推荐的是unittest。现在用的也是这个,随着了解,也有其他的框架,有时间再多去学习,保持持续学习哦~ 。
附上官方文档地址:链接描述https://docs.python.org/2.7/library/unittest.html# 。
unittest是Python自带的单元测试框,可以用来作自动化测试框架的用例组织执行框架。优点:提供用例组织与执行方法;提供比较方法;提供丰富的日志、清晰的报告。 大致流程:
通过命令行或者unittest.main()执行时,main会调用TextTestRunner中的run()来执行,或者可以直接通过TextTestRunner来执行用例.
在Runner执行时,默认将执行结果输出到控制台,我们可以设置其输出到文件,在文件中查看结果.
unittest中最核心的部分是:TestFixture、TestCase、TestSuite、TestRunner.
1、Test fixture 。
用于一个测试环境的准备和销毁还原.
当测试用例每次执行之前需要准备测试环境,每次测试完成后还原测试环境,比如执行前连接数据库、打开浏览器等,执行完成后需要还原数据库、关闭浏览器等操作。这时候就可以启用testfixture.
例如:
1
2
3
4
5
|
# 重写TestCase的setUp() tearDown()方法:在每个测试方法执行前以及执行后各执行一次
def
setUp(
self
):
# 钩子方法
print
(
"do something before test : prepare environment"
)
def
tearDown(
self
):
# 钩子方法
print
(
"do something after test : clean up "
)
|
2、TestCase 。
类,unittest.TestCase 。
一个类class继承 unittest.TestCase,就是一个测试用例。一个TestCase的实例就是一个测试用例,就是一个完整的测试流程.
包括测试前环境准备setUp()|setUpClass()、执行代码run()、测试环境后的还原tearDown()|tearDownClass()。 继承自unittest.TestCase的类中,测试方法的名称要以test开头。且只会执行以test开头定义的方法(测试用例).
例如:【先准备待测试的方法function.py】 。
1
2
3
4
5
6
7
8
9
10
|
#!/usr/bin/python3
# -*- coding:utf-8 -*-
def
add(a,b):
return
a
+
b
def
minus(a,b):
return
a
-
b
def
multi(a,b):
return
a
*
b
def
divide(a,b):
return
a
/
b
|
【测试脚本】:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
|
import
unittest
from
A_UnitTest_basicDemo_ok.function
import
*
class
TestFunc(unittest.TestCase):
# 继承自unittest.TestCase
# 重写TestCase的setUp()、tearDown()方法:在每个测试方法执行前以及执行后各执行一次
def
setUp(
self
):
print
(
"do something before test : prepare environment"
)
def
tearDown(
self
):
print
(
"do something after test : clean up "
)
# 测试方法均已test开头,否则是不被unittest识别的
def
test_add(
self
):
print
(
"add:"
)
self
.assertEqual(
3
,add(
1
,
2
))
def
test_minus(
self
):
print
(
"minus"
)
self
.assertEqual(
3
,minus(
5
,
2
))
def
test_multi(
self
):
print
(
"multi"
)
self
.assertEqual(
6
,multi(
2
,
3
))
def
test_divide(
self
):
print
(
"divide"
)
self
.assertEqual(
2
,divide(
4
,
2
))
if
__name__
=
=
"__main__"
:
# 在main()中加verbosity参数,可以控制输出的错误报告的详细程度
# verbosity=*:默认是1;设为0,则不输出每一个用例的执行结果;2-输出详细的执行结果
unittest.main(verbosity
=
2
)
|
或者也可以使用setUpClass() & tearDownClass()方法:
1
2
3
4
5
6
7
|
# 如果想在所有case执行之前准备一次测试环境,并在所有case执行结束后再清理环境
@classmethod
def
setUpClass(
cls
):
print
(
"this setupclass() method only called once"
)
@classmethod
def
tearDownClass(
cls
):
print
(
"this teardownclass() method only called once too"
)
|
【verbosity】 。
在测试用例文件的末尾加上如下代码:
1
2
|
if
__name__
=
=
"__main__"
:
unittest.main(verbosity
=
2
)
# 输出详细的错误报告
|
在unittest.main()中加参数verbosity可以控制错误报告的详细程度:默认为1。0,表示不输出每一个用例的执行结果;2表示详细的执行报告结果.
【执行结果】:输出到控制台 。
this setupclass() method only called once test_add (__main__.TestFunc) ... ok add: test_divide (__main__.TestFunc) ... ok divide test_minus (__main__.TestFunc) ... ok minus test_multi (__main__.TestFunc) ... ok multi 。
this teardownclass() method only called once too ---------------------------------------------------------------------- Ran 4 tests in 0.000s 。
OK 。
3、TestSuite 。
上述简单的测试会产生两个问题,可不可以控制test测试用例的执行顺序?若不想执行某个测试用例,有没有办法可以跳过? 对于执行顺序,默认按照test的 A-Z、a-z的方法执行。若要按自己编写的用例的先后关系执行,需要用到testSuite。 把多个测试用例集合起来,一起执行,就是testSuite。testsuite还可以包含testsuite.
一般通过addTest()或者addTests()向suite中添加。case的执行顺序与添加到Suite中的顺序是一致的.
例如:run_main.py 。
1
2
3
4
5
6
7
|
if
__name__
=
=
"__main__"
:
suite
=
unittest.TestSuite()
# 定义list,按照list里的顺序执行测试用例
tests
=
[TestFunc(
"test_add"
),TestFunc(
"test_minus"
),TestFunc(
"test_multi"
),TestFunc(
"test_divide"
)]
suite.addTests(tests)
runner
=
unittest.TextTestRunner(verbosity
=
2
)
runner.run(suite)
|
TestSuite可以再包含testsuite,示例如下:
1
2
3
|
suite1
=
module.TheTestSuite()
suite2
=
module.TheTestSuite()
alltests
=
unittest.TestSuite([suite1],[suite2])
|
跳过某个case:skip装饰器 。
若想让某个测试用例不执行,有没有办法呢?当然是有的,可以使用skip装饰器.
例如:
1
2
3
4
|
@unittest
.skip(
"i don't want to run this case -> test_minus() ... "
)
def
test_minus(
self
):
print
(
"minus"
)
self
.assertEqual(
3
,minus(
5
,
2
))
|
加上“@unittest.skip()”后,执行看看,对比控制台的输出结果就可以明显看出区别了.
Skip装饰器有如下几种情况:
(1)skip():无条件跳过 。
1
|
@unittest
.skip(
"i don't want to run this case. "
)
|
(2)skipIf(condition,reason):如果condition为true,则 skip 。
1
|
@unittest
.skipIf(condition,reason)
|
(3)skipUnless(condition,reason):如果condition为False,则skip 。
1
|
@unittest
.skipUnless(condition,reason)
|
(4)还可以使用TestCase.skipTest(reason)。例如:
1
2
3
4
|
def
test_divide(
self
):
self
.skipTest(
'do not run test_divide()'
)
print
(
"divide"
)
self
.assertEqual(
2
,divide(
4
,
2
))
|
控制台输出(部分):test_divide (__main__.TestFunc) ... skipped 'do not run test_divide()' 。
4、TestLoader 。
TestLoadder用来加载TestCase到TestSuite中.
loadTestsFrom*()方法从各个地方寻找testcase,创建实例,然后addTestSuite,再返回一个TestSuite实例.
该类提供以下方法:
1
2
3
4
5
6
|
unittest.TestLoader().loadTestsFromTestCase(testCaseClass)
unittest.TestLoader().loadTestsFromModule(module)
unittest.TestLoader().loadTestsFromName(name,module
=
None
)
unittest.TestLoader().loadTestsFromNames(names,module
=
None
)
unittest.TestLoader().getTestCaseNames(testCaseclass)
unittest.TestLoader().discover()
|
TestLoader 之discover:
用discover()来加载测试多个测试用例,再用TextRunner类的run()方法去一次执行多个脚本的用例,达到批量执行的效果.
discover方法里面有三个参数:
TextTestRunner():执行测试用例。runner.run(test)会执行TestSuite、TestCase中的run(result)方法.
如下:run_main.py示例 。
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import
unittest
import
os
# 用例的路径
case_path
=
os.path.join(os.getcwd(),
"case"
)
# 报告存放的路径
report_path
=
os.path.join(os.getcwd(),
"report"
)
def
all_cases():
discover
=
unittest.defaultTestLoader.discover(case_path,pattern
=
"test*.py"
,top_level_dir
=
None
)
print
(discover)
return
discover
if
__name__
=
=
"__main__"
:
runner
=
unittest.TextTestRunner(verbosity
=
2
)
runner.run(all_cases())
|
5、生成测试报告 。
生成TXT测试报告 。
代码示例:
1
2
3
4
5
6
7
|
if
__name__
=
=
"__main__"
:
suite
=
unittest.TestSuite()
# 生成.txt的测试报告(控制台的输出写入到文件中)
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestFunc))
with
open
(
'UnittestTextReport.txt'
,
'a'
) as f:
runner
=
unittest.TextTestRunner(stream
=
f,verbosity
=
2
)
runner.run(suite)
|
可以看到在目录下,生成了UnittestTextReport.txt文件.
但是txt格式的文件太过于简陋。我们可以借助与第三方提供的库来输出更加形象的html报告,也可以自定义输出自己想要格式的html格式的报告.
HTMLTestRunner()方法有三个参数:
代码示例:
1
2
3
4
5
6
7
|
if
__name__
=
=
"__main__"
:
suite
=
unittest.TestSuite()
# 生成HTML格式的具体测试报告
with
open
(
'HtmlReport.html'
,
'wb'
) as f:
# 在python3,要写成'wb' or 'wr'
runner
=
HTMLTestRunner(stream
=
f,title
=
'function test
report
',description='
generated by HTMLTestRunner',verbosity
=
2
)
runner.run(suite)
|
3、代码示例 。
function.py 。
1
2
3
4
5
6
7
8
9
10
|
#!/usr/bin/python3
# -*- coding:utf-8 -*-
def
add(a,b):
return
a
+
b
def
minus(a,b):
return
a
-
b
def
multi(a,b):
return
a
*
b
def
divide(a,b):
return
a
/
b
|
Test_function.py 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
|
#!/usr/bin/python3
# -*- coding:utf-8 -*-
import
unittest
from
UnitTest_1.function
import
*
# from..import ... :要指定文件的路径
class
TestFunc(unittest.TestCase):
# unittest.TestCase
# 如果想在所有case执行之前准备一次测试环境,并在所有case执行结束后再清理环境
@classmethod
def
setUpClass(
cls
):
print
(
"this setupclass() method only called once"
)
@classmethod
def
tearDownClass(
cls
):
print
(
"this teardownclass() method only called once too"
)
# 测试方法均已test开头,否则是不被unittest识别的
def
test_add(
self
):
print
(
"add:"
)
self
.assertEqual(
3
,add(
1
,
2
))
def
test_minus(
self
):
print
(
"minus"
)
self
.assertEqual(
3
,minus(
5
,
2
))
# 如果想临时跳过某个case:skip装饰器
@unittest
.skip(
"i don't want to run this case. "
)
def
test_multi(
self
):
print
(
"multi"
)
self
.assertEqual(
6
,multi(
2
,
3
))
def
test_divide(
self
):
print
(
"divide"
)
self
.assertEqual(
2
,divide(
5
,
2
))
if
__name__
=
=
"__main__"
:
# 在main()中加verbosity参数,可以控制输出的错误报告的详细程度
# verbosity=*:默认是1;设为0,则不输出每一个用例的执行结果;2-输出详细的执行结果
unittest.main(verbosity
=
2
)
|
Test_suite.py 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
#!/usr/bin/python3
# -*- coding:utf-8 -*-
import
unittest
from
UnitTest_1.test_function
import
TestFunc
from
HTMLTestRunner
import
HTMLTestRunner
# 在Python3中已经没有 StringIO,所以引用的时候要注意
from
io
import
StringIO
if
__name__
=
=
"__main__"
:
suite
=
unittest.TestSuite()
# 定义list,按照list里的顺序执行测试用例
tests
=
[TestFunc(
"test_add"
),TestFunc(
"test_minus"
),TestFunc(
"test_multi"
),TestFunc(
"test_divide"
)]
suite.addTests(tests)
'''
runner = unittest.TextTestRunner(verbosity=2)
runner.run(suite)
'''
# 生成.txt的测试报告(控制台的输出写入到文件中)
'''
suite.addTests(unittest.TestLoader().loadTestsFromTestCase(TestFunc))
with open('UnittestTextReport.txt','a') as f:
runner = unittest.TextTestRunner(stream=f,verbosity=2)
runner.run(suite)
'''
# 生成HTML格式的具体测试报告
with
open
(
'HtmlReport.html'
,
'wb'
) as f:
# 在python3,要写成'wb' or 'wr'
runner
=
HTMLTestRunner(stream
=
f,title
=
'function test report'
,description
=
'generated by
HTMLTestRunner',verbosity
=
2
)
runner.run(suite)
|
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://segmentfault.com/a/1190000016315201 。
最后此篇关于Python unittest单元测试框架的使用的文章就讲到这里了,如果你想了解更多关于Python unittest单元测试框架的使用的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我试图要求 test/unit 的新版本(即不是与 ruby 捆绑的版本) .根据 instructions我用 gem i test-unit 安装它.但是现在当我需要 test/unit我似乎
简短版本是: 我有一个 systemd 单元,我想在调用时检查脚本的返回代码: systemctl status service.service 长版本:我有一个 lsb init 脚本正是这样做的,
我正在使用反射动态创建一个类的实例,这工作正常,除非尝试通过单元测试执行此操作 - 我使用的是 MS 测试框架。 我收到熟悉的错误:“无法加载文件或程序集‘Assy’或其依赖项之一。系统找不到指定的文
我想知道测试网站“界面功能”的最佳实践是什么。 我对哪些方法可用于测试界面和动态生成的内容感兴趣。特别是,我很难弄清楚是否可以为需要用户交互的操作创建自动化测试,或者这是否只是浪费时间,我应该让一些
我有一个简单的 Python 服务,其中有一个无限执行某些操作的循环。在各种信号上,sys.exit(0) 被调用,这导致 SystemExit 被引发,然后如果可以的话应该进行一些清理。 在测试中,
我正在使用 OpenCV 2.4.2 这是 OpenCV 文档中的引文 C++: void HoughLinesP(InputArray image, OutputArray lines, doubl
忙于 C# 中的自动化测试用例,我们需要在每次测试后恢复数据库快照。问题是,当运行多个测试时它会失败,因为“其他用户正在使用数据库时无法更改数据库状态。” 我们使用 SqlConnection.Cle
我阅读了 C# 规范并用谷歌搜索了它,但一无所获。 我 99% 肯定 C# 中没有像单元命名空间指令这样的功能,但问题是:为什么?是否有惯用或技术原因? 这很方便,尤其是当我们的大部分文件都由单个命名
我目前正在尝试向我的应用程序(一个非常老的项目......评论说 iOS 2.0)添加单元测试(精确的应用程序测试)并且总是偶然发现 undefined symbols for architectur
我正在使用Delphi 7,并且有一个新单元要在我的项目中使用。我已经编译了新的。当我尝试通过将其添加到uses子句在项目中使用此单元时,出现错误,提示未找到.dcu文件。我还尝试将文件的完整路径放在
场景:我需要编写一个复杂的nHibernate查询,该查询将返回预计的DTO,但是我想使用TDD方法。该方法如下所示: public PrintDTO GetUsersForPrinting(int
您可以通过运行以下命令在事件 html 设置中显示 Jupyter 笔记本: $ jupyter nbconvert untitled.ipynb --to slides --post serve 有
如何在一个网站上拥有多个 AdSense 单元? Google 提供的唯一代码是按单位计算的。 (adsbygoogle = window.adsbygoogle || []).push({})
我刚刚开始为大量代码编写测试。有很多类依赖于文件系统,即读取 CSV 文件、读/写配置文件等。 当前测试文件存储在项目(这是一个 Maven2 项目)的 test 目录中,但由于多种原因该目录并不总是
我对 TDD 还很陌生,在单元测试方面也不是很老练,所以才有这个问题。我有这个用 PHP 编写的遗留函数 function foo(){ x = bar(); y = baz();
我创建了一个程序,在 Swing 窗口的一侧显示结果过滤选项,但默认情况下它们水平相邻显示,这浪费了我在 BorderLayout 的西侧分配的空间。我可以在构造函数或添加语句中传递任何内容来将它们堆
标题不好的借口:如果有人能更好地描述它,请做。 我有一个 WeakList类,它“基本上”是一个 List> (虽然不是字面意义上的派生自列表,但它应该对用户完全透明)。 现在的基本思想是“如果引用的
我正在尝试在 UITableView 上添加两个原型(prototype)单元。但是,我不知道如何验证是否能够为每个原型(prototype)“返回”正确的单元格。你们能帮我一下吗? func ta
我正在使用 CloudKit 作为数据库创建一个简单的待办事项列表应用程序。目前我可以添加和删除对象,但对编辑对象感到困惑。 编辑项目 Controller protocol EditItemCont
我正在针对以下任务训练 RNN:给定一个包含 30 个单词的序列,然后将该序列分类为二进制类。 在我的网络中拥有超过 30 个单元(LSTM、GRU 或普通 RNN)有好处吗?我在网上看到过很多例子,
我是一名优秀的程序员,十分优秀!