1.导包:import unittest
2.定义测试类:新建测试类必须继承unittest.TestCase
3.定义测试方法:测试方法名称命名必须以test开头
1.类后 unittest 运行,类后 unittest 运行
2.运行所有的方法运行所有的方法
3.命令行运行,测试用例增加 main 方法
调用 unittest.main() 来运行
import unittest
def add(x,y):
num = x + y
return num
# 类继承 unittest.TestCase
class TestADD01(unittest.TestCase):
def test_add0101(self):
number = add(2, 3)
print('number1的值:', number)
def test_add0102(self):
number = add(2,2)
print('number2的值是:', number)
if __name__ == '__main__':
unittest.main()
import unittest
def add(x,y):
num = x + y
return num
# 类继承 unittest.TestCase
class TestADD02(unittest.TestCase):
def test_add0201(self):
number = add(1,1)
print('number1的值是:', number)
def test_add0202(self):
number = add(2,2)
print('number2的值是:', number)
if __name__ == '__main__':
unittest.main()
说明:(翻译:测试套件)多条测试用例集合在一起,就是一个TestSuite
使用:
1. 实例化: suite = unittset.TestSuite()
(suite:为TestSuite实例化的名称)
2. 添加用例:
方法一:suite.addTest(ClassName("MethodName"))
(ClassName:为类名;MethodName:为方法名)
方法二:suite.addTest(unittest.makeSuite(ClassName))
(搜索指定ClassName类名内test开头的方法并添加到测试套件中)
提示:TestSuite需要配合TestRunner才能被执行
import unittest
from hm01_test_add import TestADD01
from hm02_test_add import TestADD02
# 组装测试用例
# 1.实例化一个suite对象
suite = unittest.TestSuite()
# 2.增加测试用例
# 方式一: suite.addTest(ClassName("MethodName"))
suite.addTest(TestADD01("test_add0101"))
suite.addTest(TestADD01("test_add0102"))
# 3.增加测试用例 方式二: suite.addTest(unittest.makeSuite(ClassName))
suite.addTest(unittest.makeSuite(TestADD02))
# 4.实例化一个runner
runner = unittest.TextTestRunner()
# 5.调用run(suite)
runner.run(suite)
说明:TextTestRunner是用来执行测试用例和测试套件的
使用:
1. 实例化:runner = unittest.TextTestRunner()
2. 执行: runner.run(suite) # suite:为测试套件名称
说明:
1.用来加载TestCase到TestSuite中,即加载满足条件的测试用例,并把测试用例封装成测试套件。
2.使用unittest.TestLoader,通过该类下面的discover()方法自动搜索指定目录下指定开头的.py文件,并将查找到的测试用例组装到测试套件。
用法:
suite = unittest.TestLoader().discover('文件夹路径', pattern="*.py")
解释:
自动搜索指定目录下指定开头的.py文件,并将查找到的测试用例组装到测试套件
pattern:为查找的.py文件的格式,默认为'test*.py'
也可以使用unittest.defaultTestLoader 代替 unittest.TestLoader()
运行:
runner = unittest.TextTestRunner()
runner.run(suite)
# 运行10个py文件
# 导包
import unittest
# 调用discover() 方法 找文件 文件路径 寻找规则
loader = unittest.TestLoader().discover("./cases", pattern="*.py")
# 运行组装好的测试用例
runner = unittest.TextTestRunner()
runner.run(loader)
1. TestSuite需要手动添加测试用例,可以添加测试类(makeSuite(类名)),也可以添加测试类中某个测试方法(类名+方法名),更加灵活;
2. TestLoader搜索指定目录下指定开头.py文件,并添加测试类中的所有的测试方法,不能指定添加测试方法,多个文件要运行时,更加简单方便;
说明:Fixture是一个概述,对一个测试用例环境的初始化和销毁就是一个Fixture
定义: 测试用例包含 数据准备, 用例功能, 数据恢复 结构内容
Fixture控制级别:
1. 方法级别
2. 类级别
3. 模块级别
# 完成两个方法,实现打印每个方法的消耗时间
import unittest
import time
class TestTime(unittest.TestCase):
def tBegin(self):
print("开始的时间:", int(time.time()))
def tEnd(self):
print("结束的时间:", int(time.time()))
def test_t01(self):
self.tBegin()
print('*' * 20)
time.sleep(2)
self.tEnd()
def test_t02(self):
self.tBegin()
print('=' * 20)
time.sleep(2)
self.tEnd()
代码实现步骤:
方法级别:
1. 初始化(前置处理):
def setUp(self) --> 每个方法执行前, 自动执行
2. 销毁(后置处理):
def tearDown(self) --> 每个方法结束后, 自动执行
3. 运行于测试方法的始末,即:运行一次测试方法就会运行一次setUp和tearDown
代码演示2
import unittest
class TestFixture(unittest.TestCase):
def setUp(self):
print('setUp每个方法执行前,执行 --001')
def tearDown(self):
print('tearDown每个方法执行后,执行 --001')
def test_f01(self):
print('我是方法1)
def test_f02(self):
print('我是方法2')
类级别:
1. 初始化(前置处理):
@classmethod
def setUpClass(cls): --> 类开始前自动执行
2. 销毁(后置处理):
@classmethod
def tearDownClass(cls): --> 类结束后自动执行
3. 运行于测试类的始末,即:每个测试类只会运行一次setUpClass和tearDownClass
代码演示3
import unittest
class TestFixture(unittest.TestCase):
@classmethod
def setUpClass(cls):
print('类开始前,执行———————————————————————002')
@classmethod
def tearDownClass(cls):
print('类结束后,执行———————————————————————002')
def setUp(self):
print('setUp每个方法执行前,执行 --001')
def tearDown(self):
print('tearDown每个方法执行后,执行 --001')
def test_f01(self):
print('我是方法1')
def test_f02(self):
print('我是方法2')
模块级别:
1. 初始化(前置处理):
def setUpModule() --> 模块执行前自动执行
2. 销毁(后置处理):
def tearDownModule() --> 模块执行后自动执行
3. 运行于整个模块的始末,即:整个模块只会运行一次setUpModule和tearDownModule
代码演示4
import unittest
def setUpModule():
print('模块开始前:****************************003')
def tearDownModule():
print('模块结束后:****************************003')
class TestFixture(unittest.TestCase):
@classmethod
def setUpClass(cls):
print('类开始前,执行———————————————————————002')
@classmethod
def tearDownClass(cls):
print('类结束后,执行———————————————————————002')
def setUp(self):
print('setUp每个方法执行前,执行 --001')
def tearDown(self):
print('tearDown每个方法执行后,执行 --001')
def test_f01(self):
print('我是方法1')
def test_f02(self):
print('我是方法2')
# 需求:使用UnitTest框架对tpshop项目测试
# 1). 点击登录,进入登录页面
# 2). 输入用户名和密码,不输入验证码,直接点击登录按钮
# 3). 获取错误提示信息
import unittest
from selenium import webdriver
from time import sleep
class TestLogin(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.get('http://127.0.0.1/')
self.driver.implicitly_wait(10)
self.driver.maximize_window()
def tearDown(self):
sleep(2)
self.driver.quit()
def testlogin(self):
# 1).点击登录,进入登录页面
self.driver.find_element_by_link_text('登录').click()
# 2). 输入用户名和密码,不输入验证码,直接点击登录按钮
sleep(2)
self.driver.find_element_by_id('username').send_keys('admin')
sleep(2)
self.driver.find_element_by_id('password').send_keys('xxxxxx')
sleep(2)
self.driver.find_element_by_class_name('J-login-submit').click()
# 3).获取错误提示信息
sleep(2)
msg = self.driver.find_element_by_class_name('layui-layer-content')
text = msg.text
print("提示信息:", text)
断言概念:
让程序代替人为判断测试程序执行结果是否符合预期结果的过程
为什么学习断言?
自动化脚本在执行的时候一般都是无人值守状态,我们不知道执行结果是否符合预期结果,所以我们需要让程序代替人为检测程序执行的结果是否符合预期结果,这就需要使用断言。
断言的方法:
1.assertEqual(预期结果, 实际结果)
2.assertTrue(预期结果==实际结果)
3.assertIn(预期结果, 实际结果) --> 实际结果包含预期结果
异常类:AssertionError
代码演示1
import unittest
def add(x, y):
num = x + y
return num
class TestAdd(unittest.TestCase):
def test_add01(self):
result1 = add(2, 3)
print(result1)
self.assertEqual(5, result1)
def test_add02(self):
result2 = add(3, 5)
print(result2)
is_equal = result2==8
self.assertTrue(is_equal)
代码演示2
# 需求:使用UnitTest框架对tpshop项目测试
# 1). 点击登录,进入登录页面
# 2). 输入用户名和密码,不输入验证码,直接点击登录按钮
# 3). 获取错误提示信息
# 4). 断言错误提示信息是否为“验证码不能为空!”,如果断言失败则保存截图
import unittest
from selenium import webdriver
from time import sleep
import time
import sys
class TestLogin(unittest.TestCase):
def setUp(self):
self.driver = webdriver.Firefox()
self.driver.get('http://127.0.0.1/')
self.driver.implicitly_wait(10)
self.driver.maximize_window()
def tearDown(self):
sleep(2)
self.driver.quit()
def testlogin(self):
# 1).点击登录,进入登录页面
self.driver.find_element_by_link_text('登录').click()
# 2). 输入用户名和密码,不输入验证码,直接点击登录按钮
sleep(2)
self.driver.find_element_by_id('username').send_keys('admin')
sleep(2)
self.driver.find_element_by_id('password').send_keys('xxxxxx')
sleep(2)
self.driver.find_element_by_class_name('J-login-submit').click()
# 3).获取错误提示信息
sleep(2)
msg = self.driver.find_element_by_class_name('layui-layer-content')
text = msg.text
print("提示信息:", text)
# 断言
# assertEqual('验证码不能为空!', text)
try:
self.assertEqual('这是怎么了', text)
except Exception as e:
ee = sys.exc_info()
print('异常的详细信息:',ee)
print('异常的详细信息:',ee[1])
# self.driver.get_screenshot_as_file('./123.png')
# 获取当前时间戳 年月日 时分秒
now_f = time.strftime('%Y%m%d_%H%M%S')
self.driver.get_screenshot_as_file('./screenshot%s.png' % now_f)
print('错误信息', e)
# 抛出异常
raise e