目录
Unittest
简单使用示例
重要概念
断言方法
深入
高级应用
认识Page Object
资料获取方法
Unittest是python的一个单元测试框架,但是它不仅适用于单元测试,还适用自动化测试用例的开发与执行。我们可以很方便的使用它组织执行测试用例,使用它提供的丰富的断言方法进行测试结果比对,并最终结合HTMLTestRunner生成测试报告完成整个自动化测试流程。
class count:
def _init_(self,a,b)
self.a = int(a)
self.b = int(b)
#计算加法
def add(self):
return self.a + self.b
from calculator import count
import unitest
class TestCount(unitest.TestCase):
def setUp(self):
print("test start")
def test_add(self):
j = count(2,3)
self.assertEqual(j.add(),5)
def tearDown(self):
print("test end")
if _name_ == '_main_':
unittest.main()
说明:
from calculator import count
import unitest
class TestCount(unitest.TestCase):
def setUp(self):
print("test start")
def test_add(self):
j = count(2,3)
self.assertEqual(j.add(),5)
def test_add2(self):
j = count(7,8)
self.assertEqual(j.add(),15)
def tearDown(self):
print("test end")
if _name_ == '_main_':
unittest.main()
#构建测试集
suite = unittest.TestSuite()
suite.addTest(TestCount("test_add2"))
#执行测试
runner = unittest.TextTestRunner()
runner.run(suite)
本例只执行第二个测试用例,
unittest框架的TestCase类提供的断言方法用于测试结果的判断
-assertEqual(first,second,msg=None)
# 如果不相等则测试失败,msg为可选参数,用于定义测试失败时打印的信息。
self.assertEqual(j.add(),15,msg="测试结果不等于15")
格式:-assertNotEqual(first,second,msg=None)则与之相反
-assertTrue(expr,msg=None)
-assertFalse(expr,msg=None)
创建count.py用于判断质数的
def is_prime(n):
if n<=1:
return False
for i in range(2,n):
if n % i = = 0:
return False
retun True
测试用例:调用is_prime()函数和unittest
self.assertTrue(is_prime(7),msg="is not prime")
-assertIn(first,second,msg=None)
-assertNotIn(first,second,msg=None)
测试用例(部分):
def test_case(self):
a = "hello"
b = "hello world"
self.assertIn(a,b,msg="a is not in b")
-assertIs(first,second,msg=None)
-assertIsNot(first,second,msg=None)
-assertIsNone(expr,msg=None)
-assertIsNotNone(expr,msg=None)
-assertIsInstance(obj,cls,msg=None)
-assertNotIsInstance(obj,cls,msg=None)
- 方法1.setUp()和setDown方法分别作用于每个测试用例的开始和结束
- 方法2.如果每个类中的setUp()和setDown方法所做的事情是一样的,那么可以封装成一个自己的测试类
如果单元测试用例达到成百上千个,可以将这些用例按照所测试的功能进行拆分,分散到不同的测试文件中
最后再创建用于执行所有测试用例的runtest.py文件。
- discover(start_dir,pattern='test*.py',top_level_dir=None)
- start_dir:要测试的模块名或测试用例的目录
- pattern='test.py':表示用例文件名的匹配原则,此处文件名以“test”开头的“.py”类型的文件,“”表示任意多个字符。
- top_level_dir=None:测试模块的顶层目录,如果没有顶层目录,默认为None.
unittest框架默认根据ASCII码的顺序加载测试用例,数字与字母的顺序为:0-9,A-Z,a-z。所以TestAdd会优于TestBdd类被执行,test_aaa()方法会优于test_ccc被执行,因而它并没有按照用例从上到下的顺序执行。
对于测试目录和测试文件来说,unittest框架同样是按照这个规则来加载测试用例的。
如果按照指定的顺序执行,可以通过TestSuite类的addTest()方法按照一定的顺序加载。不能默认main()方法了。需要构造测试集,然后通过run()方法执行测试。
注意:discover()的加载测试用例的规则与main()方法相同,所以只能通过测试用例的命名来提高被执行的优先级。
discover()方法中的start_dir只能加载当前目录下的.py文件,如果加载子目录下的.py文件,需在每个子目录下放一个_init_.py文件。
unittest提供了实现某些需求的装饰器,在执行测试用例时每个装饰前面加@符号。
fixtures可以形象的把他看作是夹心饼干外层的两片饼干,这两片饼干就是setUp/tearDown,中间的心就是测试用例,除此以外,unittest还提供了更大范围的fixtures,例如对于测试类和模块的fixtures。
HTMLTestRunner是python标准库unittest单元测试框架的一个拓展,它生成易于使用的HTML测试报告。
HTMLTestRunner下载地址:HTMLTestRunner - tungwaiyip's software
这个拓展只有一个HTMLTestRunner.py文件,选中后单击鼠标右键,在弹出的快捷菜单中选择目标另存为,将它保存到本地。安装方法是将其复制到python安装目录下即可。
- windows:将下载的文件保存到...\python35\Lib目录下
- Ubuntu:以root身份将HTMLTestRunner.py文件复制到/usr/local/python3.4/dist-packages/目录下。
HTMLTestRunner.py文件是基于python2开发的,若要支持python3环境需要对其中的部分内容进行修改。
方法:加注释并用一种方法读取
在类和方法的下方,通过三引号(""" """或''' ''')来添加docstring类型的注释,这类注释在平时调用的时候
不显示,可以通过help()方法来查看类或方法的这种注释。
HTMLTestRunner可以读取docstring类型的注释,所以只需给测试类或方法添加这种类型的注释即可。
在每次运行测试之前,都要手动修改报告的名称,如果忘记修改,就会把之前的报告覆盖,为了使每次生成的报告名称都不重复并且有意义,最好的方法是在报告名称中加入当前时间,这样生成的报告既不会重叠,又能更清晰的知道报告的生成时间。
- time.time():获取当前时间戳 比如:1445694559.2290168
- time.ctime():当前时间的字符串形式 比如:'sat oct 24 21:49:29 2015'
- time.localtime():当前时间的struct_time形式 比如:tm_year=2015,tm_mon=10,tm_mday=24,..........等等。
- time.strftime("%Y_%m_%d %H:%M:%s"):用来获得当前时间,可以将时间格式化为字符串。比如:'2015_10_24 21:50:15'
方法:通过时间操作的方法以指定的格式获取当前时间,将当前时间的字符串赋值给now变量,将now通过加号(+)拼接到生成的测试报告的文件名中,再次运行测试用例,生成测试报告文件名。
目前HTMLTestRunner只是针对单个测试文件生成测试报告,若要使其作用于整个测试项目,
要将它集成到runtest.py文件中,对其文件进行修改。
为web页面编写测试时,需要操作该web页面上的元素,如果在测试代码中直接操作HTML元素,那么你的代码是极其脆弱的,因为UI经常变动。我们可以将一个page对象封装成一个HTML页面,然后通过提供的应用程序特定的API来操作页面元素,而不是在HTML中四处搜寻。
page对象应当将在GUI控件上所有查询和操作数据的行为封装为方法,即使改变具体的控件,page对象的接口也不应当发生变化。
“页面”对象不仅是针对每个页面建立一个这样的对象,对由重要意义的元素也可以独立为一个page对象。
【留言777】
各位想获取源码等教程资料的朋友请点赞 + 评论 + 收藏,三连!
三连之后我会在评论区挨个私信发给你们~