一、引入unittest单元测试框架的好处有:
- 提供用例组织与执行
- 提供丰富的断言方法
- 提供丰富的日志和报告(HTML格式的更好一些)
路径问题
在unittest中./表示首目录位置
- TestCase:在unittest中的一个TestCase的实例就是一个测试用例,就是一个完整的测试流程,包括测试前资源初始化(setUp),执行测试代码(test),测试后环境的还原tearDown)。
- TestSuite:测试套件,可以理解为:多个独立的测试用例(test case)可以构成一个测试套件,然后传递给TestRunner进行测试执行。
- TestLoader:通过unittest.TestLoader类的loadTestsFromTestCase、loadTestsFromModule、LoadTestsFromName、discover方法,可以将测试用例添加一个测试套件中。
- TestRunner :可以理解为测试集的运行器,可以在其基础上扩展子类
- TextTestRunner或者HTMLTestRunner,只不过生成的测试报告样式不同。
- TestResult:测试结果类,用来处理测试用例或测试集执行过程中的所有信息并最终输出,比如代码错误、异常、断言失败、skip等等。
二、Unittest.TestCase框架基本使用
- setUp():主要是进行测试用例的资源初始化,测试用例的前提条件写在这
- test_xxx():测试用例,要把测试用例的步骤写在这个方法中
- tearDown():主要是进行测试用例的资源释放的
注册模块自动测试框架
testc.py文件代码
#导包
import unittest
from selenium import webdriver
from time import sleep
import random
class zhucetest(unittest.TestCase):
def setUp(self):#初始化资源
self.driver =webdriver.Chrome()#谷歌浏览器打开
self.driver.maximize_window()#最大化窗口
self.driver.implicitly_wait(10)#智能等待时间
self.driver.get("http://localhost:8088/verydows/index.php?c=user&a=register")#注册页面链接
def testzhuce1(self):#test主体部分
randN = str(random.randint(100,100000))#random随机变量的引入
us = "cbt_"+randN
use =randN+"@163.com"
self.driver.find_element_by_id("username").send_keys(us)
self.driver.find_element_by_id("email").send_keys(use)
self.driver.find_element_by_id("password").send_keys("123456")
self.driver.find_element_by_id("repassword").send_keys("123456")
self.driver.find_element_by_id("captcha").send_keys("aaaa")
self.driver.find_element_by_link_text("立即注册").click()
sleep(5)
actualValue=self.driver.find_element_by_xpath('//*[@id="top-userbar"]/a').text
expectValue=us
self.assertEqual(actualValue,expectValue,"设计用例失败")
def testzhuce2(self):#下面插入列表
list1=[
['12345',"30215110100@qq.com",'123456','123456','用户名不符合格式要求'],
['a123',"3021511200@qq.com",'123456','123456','用户名不符合格式要求'],
['a113344556677838999',"302152100@qq.com",'123456','123456','用户名不符合格式要求'],
['_abcda',"3021504200@qq.com",'123456','123456','用户名不符合格式要求'],
['',"3021501500@qq.com",'123456','123456','请设置用户名']
]
for i in list1:
self.driver.find_element_by_id("username").clear()
self.driver.find_element_by_id("username").send_keys(i[0])
self.driver.find_element_by_id("email").clear()
self.driver.find_element_by_id("email").send_keys(i[1])
self.driver.find_element_by_id("password").clear()
self.driver.find_element_by_id("password").send_keys(i[2])
self.driver.find_element_by_id("repassword").clear()
self.driver.find_element_by_id("repassword").send_keys(i[3])
self.driver.find_element_by_id("captcha").clear()
self.driver.find_element_by_id("captcha").send_keys("aaaa")
self.driver.find_element_by_link_text("立即注册").click()
sleep(2)
actualValue=self.driver.find_element_by_xpath('//*[@id="register-form"]/div/dl[1]/dd/span/font').text
expectValue=i[4]
self.assertEqual(actualValue,expectValue,"用例设计失败")
#或者用csv文件导入方式
#需要把文件中的数据读入到脚本中来
#with open(r"e:\verydows_Reg_false.csv","r",encoding="utf-8") as f:
# data = csv.reader(f)
# 遍历data出来的数据就是一个个的列表
for i in csv.reader(f):
# 1、打开电商首页
#driver.get("http://localhost:8088/verydows")nb
# 2、点击免费注册
driver.find_element_by_link_text("免费注册").click()
# 3、输入合法的用户名
#driver.find_element_by_id("username").send_keys(i[0])
# 4、输入合法的邮箱
#driver.find_element_by_id("email").send_keys(i[1])
# 5、输入合法的密码
#driver.find_element_by_id("password").send_keys(i[2])
# 6、输入一致的确认密码
3driver.find_element_by_id("repassword").send_keys(i[3])
#driver.find_element_by_id("captcha").send_keys("aaaa")
# 7、购选同意
# 8、点击注册
#driver.find_element_by_link_text("立即注册").click()
#time.sleep(5)
def testzhuce3(self):
list2=[
['te4st123945','@qq.com','123456','123456','无效的邮箱地址'],
['terst4127345','302650102qq.com','123456','123456','无效的邮箱地址'],
['tesrt1326345','302650100@.com','123456','123456','无效的邮箱地址'],
['tesrt1822345','302650100@qq','123456','123456','无效的邮箱地址'],
['testr1923145','','123456','123456','请设置邮箱']
]
for i in list2:
self.driver.find_element_by_id("username").clear()
self.driver.find_element_by_id("username").send_keys(i[0])
self.driver.find_element_by_id("email").clear()
self.driver.find_element_by_id("email").send_keys(i[1])
self.driver.find_element_by_id("password").clear()
self.driver.find_element_by_id("password").send_keys(i[2])
self.driver.find_element_by_id("repassword").clear()
self.driver.find_element_by_id("repassword").send_keys(i[3])
self.driver.find_element_by_id("captcha").clear()
self.driver.find_element_by_id("captcha").send_keys("aaaa")
self.driver.find_element_by_link_text("立即注册").click()
sleep(2)
actualValue=self.driver.find_element_by_xpath('//*[@id="register-form"]/div/dl[2]/dd/span/font').text
expectValue=i[4]
self.assertEqual(actualValue,expectValue,"用例设计失败")
def testzhuce4(self):
list3=[
['testaqb1233','3022650140@qq.com','12345','12345','密码不符合格式要求'],
['testabg1223','3026501240@qq.com','1233333333333312341233333333333121223333333333333331232132322131231233','1233333333333312341233333333333121223333333333333331232132322131231233','密码不符合格式要求'],
['testfab1213','3021650140@qq.com','','','请设置密码']
]
for i in list3:
self.driver.find_element_by_id("username").clear()
self.driver.find_element_by_id("username").send_keys(i[0])
self.driver.find_element_by_id("email").clear()
self.driver.find_element_by_id("email").send_keys(i[1])
self.driver.find_element_by_id("password").clear()
self.driver.find_element_by_id("password").send_keys(i[2])
self.driver.find_element_by_id("repassword").clear()
self.driver.find_element_by_id("repassword").send_keys(i[3])
self.driver.find_element_by_id("captcha").clear()
self.driver.find_element_by_id("captcha").send_keys("aaaa")
self.driver.find_element_by_link_text("立即注册").click()
sleep(2)
actualValue=self.driver.find_element_by_xpath('//*[@id="register-form"]/div/dl[3]/dd/span/font').text
expectValue=i[4]
self.assertEqual(actualValue,expectValue,"用例设计失败")
def testzhuce5(self):
list4=[
['teat123aa','3026520100@qq.com','123456','123457','两次密码不一致'],
['teba123453','302650100@qq.com','123456','','两次密码不一致']
]
for i in list4:
self.driver.find_element_by_id("username").clear()
self.driver.find_element_by_id("username").send_keys(i[0])
self.driver.find_element_by_id("email").clear()
self.driver.find_element_by_id("email").send_keys(i[1])
self.driver.find_element_by_id("password").clear()
self.driver.find_element_by_id("password").send_keys(i[2])
self.driver.find_element_by_id("repassword").clear()
self.driver.find_element_by_id("repassword").send_keys(i[3])
self.driver.find_element_by_id("captcha").clear()
self.driver.find_element_by_id("captcha").send_keys("aaaa")
self.driver.find_element_by_link_text("立即注册").click()
sleep(2)
actualValue=self.driver.find_element_by_xpath('//*[@id="register-form"]/div/dl[4]/dd/span/font').text#实际值
expectValue=i[4]#预期值
self.assertEqual(actualValue,expectValue,"用例设计失败")#做断言
def tearDown(self):#资源释放
self.driver.quit()
if __name__ == "__main__":
unittest.main()#执行文件
通过addTest和addTests增加测试用例
if __name__=='__main__':
suitt = unittest.TestSuite()
#测试集合对象中有一个方法,addtest-->追加单个测试用例到测试集合
#格式:类名(用例名)
suitt.addTest(unitMymath("test_chengfa_2"))
suitt.addTest(unitMymath("test_add_2"))
suitt.addTest(unitMymath("test_add_1"))
# 测试集合对象还有一个方法,addtests-->追加多个测试用例到测试集合
suitt.addTests(map(unitMymath,["test_add_2","test_add_1"]))
三、TestRunner
- TextTestRunner 语法:TextTestRunner(stream, descriptions=None, verbosity=0)
- Stream:运行测试用例之后的结果要保存的文本文件流对象
- Descriptions:对生成报告的描述性文字
- Verbosity:日志显示等级
- verbosity =< 0时—静默模式,输出结果中不提示执行成功的用例数
- verbosity = 1 时—默认模式,输出结果中仅仅以(.)的形式表示执行成功的用例数,成功几个就是几个点
- verbosity >= 2 时—详细模式,可以输出每个用例执行的详细信息,特别是在用例较多的情况下,此设置会比较有用
import unittest#导包
from HTMLTestRunner import HTMLTestRunner
discover=unittest.defaultTestLoader.discover(r"./SELENIUMTEST",pattern="testc*.py") #导入方法的路径和文件pattern=后跟要导入方法的模块,集合在一起
with open(r"./SELENIUMTEST/zhuce.html","wb")as f:#路径和生成新的.html文件
runner=HTMLTestRunner(stream=f,verbosity=1,title="注册",description="测试")
runner.run(discover)#运行导入用例生成报告文件
一个自动化测试用例,测试步骤、测试的断言缺一不可,unittest中提供的断言方法有:
- assertEqual(a,b,msg=""):就是判断a和b是否相等,如果相等,则断言成功,如果不相等,会断言失败,并且输出msg消息
- assertNotEqual(a,b,msg=""):就是判断a和b是否不相等
- assertTrue(a):就是判断a是否为True这个bool值
- assertFalse(a):就是判断a是否为False这个bool值
- assertIs(a,b,msg=""):判断a和b的内存地址是否相等,如果相等则身份一致
- assertIsNot(a,b,msg):判断a和b的内存地址是否不相等,如果相等,断言失败
- assertIsNone(a):判断对象a是不是空指针(没有指向堆内存中空间),如果是则断言成功
- assertIsNotNone(a):判断对象a是不是空指针,如果是,则断言失败
- assertIn(a,b):判断a是不是b的成员,如果是则断言成功
- assertNotIn((a,b):判断a是不是b的成员,如果不是则断言成功
- assertIsInstance(a,b):判断a是b的一个实例对象
- assertIsNotInstance(a,b):判断a不是b的一个实例对象