1. 认识unittest(续)

关于unittest单元测试框架,还有一些问题值得进一步探讨。你可能在前一章的学习过程中产生了一些疑问,也许你会在本节中找到答案。

1.1 用例执行的顺序

用例的执行顺序涉及多个层级,在多个测试目录的情况下,先执行哪个目录?在多个测试文件的情况下,先执行哪个文件?在多个测试类的情况下,先执行哪个测试类?在多个测试方法(用例)的情况下,先执行哪个测试方法?

我们先来运行一个例子,再来解释unittest的执行策略。

import unittest

class TestBdd(unittest.TestCase):

    def setUp(self):
print("test TestBdd:") def test_ccc(self):
print("test ccc") def test_aaa(self):
print("test aaa") def tearDown(self):
pass class TestAdd(unittest.TestCase): def setUp(self):
print("test TestAdd:") def test_bbb(self):
print("test bbb") def tearDown(self):
pass if __name__ == '__main__':
unittest.main()

运行结果:

无论执行多少次,结果都是一样的,通过上面的结果,相信你已经找到了unittest执行测试用例的规律。

unittest框架默认根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。所以,TestAdd类会优先于TestBdd类被执行,test_aaa()方法会有限与test_ccc()被执行,因而它并没有按照用例从上到下的顺序执行。

对于测试目录与测试文件来说,unittest框架同样是按照这个规则来加载测试用例的。

那么可不可以让test_ccc()先执行呢?答案是肯定的,只是不能使用默认的main()方法了,而是需要通过TestSuite类的addTest()按照一定的顺序来加载。

import unittest

class TestBdd(unittest.TestCase):

    def setUp(self):
print("test TestBdd:") def test_ccc(self):
print("test ccc") def test_aaa(self):
print("test aaa") def tearDown(self):
pass class TestAdd(unittest.TestCase): def setUp(self):
print("test TestAdd:") def test_bbb(self):
print("test bbb") def tearDown(self):
pass if __name__ == '__main__':
#构造测试集
suite = unittest.TestSuite()
suite.addTest(TestBdd("test_ccc"))
suite.addTest(TestAdd("test_bbb"))
suite.addTest(TestBdd("test_aaa")) #执行测试
runner = unittest.TextTestRunner()
runner.run(suite)

运行结果:

现在的执行顺序就是addTest()方法所加载的顺序。discover()的加载测试用例的规则与main()方法相同。所以,我们只能通过测试用例的命名来提高被执行的优先级。例如,将希望先被执行的测试用例命名为“test_a”,将希望最后执行的测试用例命名为“test_z”。

1.2 执行多级目录的用例

我们要控制Web用例的数量,但是当测试用例达到一定量级时,就要考虑划分目录。

test_project/test_case/

  test_bbb/

    test_ccc/

      test_c.py

    test_b.py

  test_ddd/

    test_d.py

  test_a.py

对于上面的目录结构,如果将discover()方法中的start_dir参数定义为“./test_case/”目录,那么只能加载test_a.py文件中的测试用例。怎样让unittest框架查找到test_case/的子目录中高端测试文件呢?方法很简单,在每个子目录下放一个__init__.py文件(在文件夹中包含一个__init__.py,Python就会把文件夹当作一个package,里面的py文件就能够在外面被import)。

1.3 跳过测试和预期失败

在运行测试时,有时需要直接跳过某些测试用例,或者当用例符合某个条件时跳过测试,又或者直接将测试用例设置为失败。unittest提供了实现这些需求的装饰器。

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

unittest.skipIf(condition,reason):跳过修饰的测试,如果条件为真时。

unittest.skipUnless(condition,reason):跳过修饰的测试,除非条件为真。

unittest.expectedFailure():测试标记为失败。不管执行结果是否失败,统一标记为失败。

import unittest

class MyTest(unittest.TestCase):

    def setUp(self):
pass def tearDown(self):
pass @unittest.skip("直接跳过测试")
def test_skip(self):
print('test aaa') @unittest.skipIf(3>2,"当条件为True时跳过测试")
def test_skip_if(self):
print('test bbb') @unittest.skipUnless(3 > 2, "当条件为True时执行测试")
def test_skip_unless(self):
print('test ccc') @unittest.expectedFailure
def test_expected_failure(self):
assertEqual(2,3) if __name__ == '__main__':
unittest.main()

运行结果:

上例中共创建了4条测试用例。第一条测试用例通过@unittest.skip()修饰,直接跳过不执行。第二条用例通过@unittest.skipIf()修饰,当条件为真时不执行,3>2条件为真(True),通过不执行。第三条用例通过@unittest.skipUnless装饰,当条件为真时执行,判断3>2条件为真(True),第三条用例执行。第四条用例通过@unittest.expectedFailure装饰,不管执行结果是否失败,统一标记为失败,但不会抛出错误信息。

当然,这些方法同样可以作用于测试类,只需将它们定义在测试类上面即可。

import unittest

@unittest.skip("直接跳过测试该测试类")
class MyTest(unittest.TestCase):

1.4 fixtures

fixtures的概念前面已经有过简单的介绍,可以形象的把它看作是夹心饼干外层的两片饼干,这两片饼干就是setUp/tearDown,中间的心就是测试用例。除此之外,unittest还提供了更大范围的fixtures,例如对于测试类和模块的fixtures。

import unittest

def setUpModule():
print("test module start >>>>>>>>>>>>>>>>") def tearDownModule():
print("test module end >>>>>>>>>>>>>>>>") class Test(unittest.TestCase): @classmethod
def setUpClass(cls):
print("test class start ==============>") @classmethod
def setDownClass(cls):
print("test class end ==============>") def setUp(self):
print("test case start -->") def tearDown(self):
print("test case end -->") def test_case(self):
print("test case1") def test_case2(self):
print("test case2") if __name__ == '__main__':
unittest.main()

运行结果:

setUpModule/tearDownModule:在整个模块的开始与结束时被执行。

setUpClass/tearDownClass:在测试类的开始与结束时被执行。

setUp/tearDown:在测试用例的开始与结束时被执行。

需要注意的是, setUpClass/tearDownClass的写法稍微有些不同。首先,需要通过@classmethon进行修饰,其次方法的参数为cls。其实,cls与self并没有什么特别之处,都只表示类方法的第一个参数,只是大家约定俗成,习惯于这样来命名,当然也可以用abc来代替。

Selenium(十六):unittest单元测试框架(二) 初识unittest(续)的更多相关文章

  1. Selenium(十五):unittest单元测试框架(一) 初识unittest

    1. 认识unittest 什么是单元测试?单元测试负责对最小的软件设计单元(模块)进行验证,它使用软件设计文档中对模块的描述作为指南,对重要的程序分支进行测试以发现模块中的错误.在python语言下 ...

  2. python六十六课——单元测试(二)

    ''' 封装Person类 ''' class Person: def __init__(self,name,age): self.name=name self.age=age def getAge( ...

  3. Selenium基于Python web自动化基础二 -- 免登录、等待及unittest单元测试框架

    一.免登录在进行测试的过程中难免会遇到登录的情况,给测试工作添加了工作量,本文仅提供一些思路供参考解决方式:手动请求中添加cookies.火狐的profile文件记录信息实现.人工介入.万能验证码.去 ...

  4. Selenium+Python ---- 免登录、等待、unittest单元测试框架、PO模型

    1.免登录在进行测试的过程中难免会遇到登录的情况,给测试工作添加了工作量,本文仅提供一些思路供参考解决方式:手动请求中添加cookies.火狐的profile文件记录信息实现.人工介入.万能验证码.去 ...

  5. Python+selenium之简单介绍unittest单元测试框架

    Python+selenium之简单介绍unittest单元测试框架 一.unittest简单介绍 unittest支持测试自动化,共享测试用例中的初始化和关闭退出代码,在unittest中最小单元是 ...

  6. Selenium(十八):unittest单元测试框架(四) HTML测试报告

    1. HTML测试报告 对测试人员来而言,测试的产出很难衡量.换句话说,测试人员的价值比较难以量化和评估,相信这一点对软件测试人员来说深有体会.我们花费了很多时间与精力所做的自动化测试也是如此.所以, ...

  7. Python+Selenium框架设计篇之-简单介绍unittest单元测试框架

    前面文章已经简单介绍了一些关于自动化测试框架的介绍,知道了什么是自动化测试框架,主要有哪些特点,基本组成部分等.在继续介绍框架设计之前,我们先来学习一个工具,叫unittest.       unit ...

  8. Python+Selenium ----unittest单元测试框架

    unittest是一个单元测试框架,是Python编程的单元测试框架.有时候,也做叫做“PyUnit”,是Junit的Python语言版本.这里了解下,Junit是Java语言的单元测试框架,Java ...

  9. Selenium(十七):unittest单元测试框架(三) 脚本分析、编写Web用例

    1. 带unittest的脚本分析 也许你现在心里还有疑问,unittest框架与我们前面所编写的Web自动化测试之间有什么必然联系吗?当然有,既然unittest可以组织.运行测试用例,那么为什么不 ...

随机推荐

  1. tomcat启动内存溢出三种解决方案:java.lang.OutOfMemoryError:PermGen space解决办法

    问题: 严重: Error waiting for multi-thread deployment of WAR files to completejava.util.concurrent.Execu ...

  2. k8s~k8s里的服务Service

    k8s用命名空间namespace把资源进行隔离,默认情况下,相同的命名空间里的服务可以相互通讯,反之进行隔离. 服务Service 1.1 Service Kubernetes中一个应用服务会有一个 ...

  3. Cesium专栏-地形开挖2-任意多边形开挖(附源码下载)

    “任意多边形地形开挖” 是“地形开挖”的补充篇,在这节里,我们介绍关于如何使用任意多边形对地形进行开挖,同时,由于有不少小伙伴也咨询了关于“地形开挖”篇后序内容中的填充地形的效果,之前没放出来,是想让 ...

  4. Linux 桥接网络不自动分配IP的问题

    之前遇到过好多次,知道什么原因就是忘了命令怎么敲,还要去搜索,写一遍加强下记忆,并总结下. 情况一 :网卡冲突问题 1 , 网卡问题 有安装过oracle VM VirtualBox 的,会和VMwa ...

  5. Pikachu-Sql Inject

    Pikachu-Sql Inject 在owasp发布的top10排行榜里,注入漏洞一直是危害排名第一的漏洞,其中注入漏洞里面首当其冲的就是数据库注入漏洞. 一个严重的SQL注入漏洞,可能会直接导致一 ...

  6. Maven项目使用mybatis报错 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found):

    maven项目使用mybatis时,找不到mapper文件(.xml) 错误信息提示: 项目可以正常运行,但是在有请求到达服务器时(有访问数据库的请求),会出现报错!! 错误原因: mybatis没有 ...

  7. 实战Netty集群

    疯狂创客圈 Java 分布式聊天室[ 亿级流量]实战系列之 -25[ 博客园 总入口 ] 1.写在前面 1.1 实战Netty集群的理由 Java基础练习中,一个重要的实战练习是: java的聊天程序 ...

  8. 第421期 Python 周刊

    新闻 感谢 Guido 链接: https://blog.dropbox.com/topics/company/thank-you--guido Python之父 Guido van Rossum 即 ...

  9. 检测一个App是不是有UWP血统

    Win + Shift + Enter   

  10. Dubbo学习系列之十四(Seata分布式事务方案AT模式)

    一直说写有关最新技术的文章,但前面似乎都有点偏了,只能说算主流技术,今天这个主题,我觉得应该名副其实.分布式微服务的深水区并不是单个微服务的设计,而是服务间的数据一致性问题!解决了这个问题,才算是把分 ...