selenium unittest框架
###################################
unitTest框架需要掌握
什么是框架就是解决一类事情的功能集合
提供了3个重要内容
1,我写了很多的自动化测试用例,怎么组织多个用例都执行,这是框架提供的,
2,测试结果需要出报告,框架会自动出报告,
3,断言,判断结果和预期,这是看框架提供的,而且还提供了丰富的日志
这几条就是为什么使用这个框架
登陆是一条用例,这里面包含了登陆成功, 用户名错误,密码错误,等等情况,
#################################
unitTest核心要素
1,testcase, 测试用例
2,testsuite 测试套件,可以添加多个测试用例
3,texttestRunner testsuite组装了多个用例,通过texttestRunner执行
4,fixture 这是一个概念,两个函数,放在任何地方先执行,最后执行,所以打开浏览器输入url,隐式等待都可以放入先执行的,关闭浏览器都放在最后执行的部分,
###############################
testcase
1,导包,import unittest
2,继承 unittest.testcase
新建测试类,继承了这个类,只要继承了就是一个testcase了,
注意:
文件名必须是test开头的,
测试方法必须是test开头的,
在自动化测试中,一个测试用例是一个完整的流程有打开,有关闭,
测试方法命名必须都是test开头,因为testcase运行的之后会去搜索test开头的方法, 不以test开头,搜不到,运行不了
运行的时候,放到类名上右键运行就是里面的方法全部运行,
放到方法名上右键运行就是只运行这个方法,
#################################
import unittest class Test01(unittest.TestCase): def test_001(self): print('test01执行') def test_002(self): print('test02执行') if __name__ == '__main__': unittest.main()
##############################
testsuite测试套件
1,可以把测试用例组织起来,
首先实例化,
suite = unittest.Testsuite()
添加用例,有三种方法
1,suite.addTest(classname("methodname"))
但是suite是组织多个测试用例,而一个测试用例就是一个py文件,所以这种写法不好,
2,第二种方法:
suite = unittest.TestLoader().loadTestsFromTestCase(Test01)
3,第三种方式,这是重点,我们只会使用这种方式,
suite = unittest.defaultTestLoader.discover("./",pattern="test*.py") # 第一参数是指定文件夹,第二个参数是指定的py文件
###############################
from test_01 import Test01 import unittest if __name__ == '__main__': suite = unittest.TestSuite() suite.addTest(Test01("test_001")) suite.addTest(Test01("test_002")) runner = unittest.TextTestRunner() runner.run(suite)
#############################
from test_01 import Test01 import unittest if __name__ == '__main__': # suite = unittest.TestLoader().loadTestsFromTestCase(Test01) # 这一句就是下面两句 suite = unittest.TestSuite() suite.addTest(unittest.TestLoader().loadTestsFromTestCase(Test01)) runner = unittest.TextTestRunner() runner.run(suite)
#################################
测试执行:texttestrunner() runner = unittest.TextTestRunner() runner.run(suite)
##################################
fixture 两个函数 def setUp(self): def tearDown(self): 如果一个测试类有多个test开头的方法,比如5个,那么每一个方法执行之前都会执行setUp,结束都会执行tearDown,就会执行5次,
#######################################
import unittest class Test01(unittest.TestCase): def test_001(self): print('test01执行') def test_002(self): print('test02执行') def setUp(self): print('setUp方法') def tearDown(self): print('tearDown方法') if __name__ == '__main__': unittest.main() """ setUp方法 test01执行 tearDown方法 setUp方法 test02执行 tearDown方法 """
################################
'''
完整的登陆测试 cnblog的登录测试,分下面几种情况: (1)用户名、密码正确 (2)用户名正确、密码不正确 (3)用户名正确、密码为空 (4)用户名错误、密码正确 (5)用户名为空、密码正确(还有用户名和密码均为空时与此情况是一样的,这里就不单独测试了) ''' import unittest from selenium import webdriver from time import sleep class LoginCase(unittest.TestCase): def setUp(self): self.dr = webdriver.Chrome() self.dr.maximize_window() #定义登录方法 def login(self, username, password): self.dr.get('https://passport.cnblogs.com/user/signin') #cnblog登录页面 self.dr.find_element_by_id('input1').send_keys(username) self.dr.find_element_by_id('input2').send_keys(password) self.dr.find_element_by_id('signin').click() def test_login_success(self): '''用户名、密码正确''' self.login('kemi_xxx', 'kemi_xxxx') #正确用户名和密码 sleep(3) link = self.dr.find_element_by_id('lnk_current_user') self.assertTrue('菜鸟可米' in link.text) #用assertTrue(x)方法来断言 bool(x) is True 登录成功后用户昵称在lnk_current_user里 self.dr.get_screenshot_as_file("D:\cnblogtest\\login_success.jpg") #截图 可自定义截图后的保存位置和图片命名 def test_login_pwd_error(self): '''用户名正确、密码不正确''' self.login('kemi_xxx', 'kemi') #正确用户名,错误密码 sleep(2) error_message = self.dr.find_element_by_id('tip_btn').text self.assertIn('用户名或密码错误', error_message) #用assertIn(a,b)方法来断言 a in b '用户名或密码错误'在error_message里 self.dr.get_screenshot_as_file("D:\cnblogtest\\login_pwd_error.jpg") def test_login_pwd_null(self): '''用户名正确、密码为空''' self.login('kemi_xxx', '') #密码为空 error_message = self.dr.find_element_by_id('tip_input2').text self.assertEqual(error_message,'请输入密码') #用assertEqual(a,b)方法来断言 a == b 请输入密码等于error_message self.dr.get_screenshot_as_file("D:\cnblogtest\\login_pwd_null.jpg") def test_login_user_error(self): '''用户名错误、密码正确''' self.login('kemixing', 'kemi_xxx') #密码正确,用户名错误 sleep(2) error_message = self.dr.find_element_by_id('tip_btn').text self.assertIn('该用户不存在', error_message) #用assertIn(a,b)方法来断言 a in b self.dr.get_screenshot_as_file("D:\cnblogtest\\login_user_error.jpg") def test_login_user_null(self): '''用户名为空、密码正确''' self.login('', 'kemi_xxx') #用户名为空,密码正确 error_message = self.dr.find_element_by_id('tip_input1').text self.assertEqual(error_message,'请输入登录用户名') #用assertEqual(a,b)方法来断言 a == b self.dr.get_screenshot_as_file("D:\cnblogtest\\login_user_null.jpg") def tearDown(self): sleep(2) print('自动测试完毕!') self.dr.quit() if __name__ == '__main__': unittest.main()
#########################################
第三种套件组织的方法,很重要,以后都是这种
1,可以加载指定目录下, 指定开头为py的文件,所以你把用例都放到一个文件,用这个方法就可以都执行了,使用addTest一个一个加太麻烦了,
2,defaultTestLOader这是一个类,里面有一个方法discover,
########################################
import unittest if __name__ == '__main__': suite = unittest.defaultTestLoader.discover("./",pattern="test*.py") # 第一参数是指定文件夹,第二个参数是指定的py文件 runner = unittest.TextTestRunner() runner.run(suite)
###################################
断言的使用
1,就是让程序去判断结合预期是否一致,
2,为什么使用断言 ,因为测试的要点就是符合预期,没有哦判断你就不知道是否符合我们想要的结果,
unittest支持的断言
1,布尔断言
2,比较断言
3,复杂断言,
里面有很多,掌握常用的就可以
1,assertEqual(arg1,arg2) 如果arg1=arg2 就是成功了 这个常用,
2,assertIn(arg1,arg2) arg1是arg2的子串 就通过了,
3,assertTrue('xx' in msg) # 这种也可以,
断言失败之后需要截屏,
def test_xxx(self):
...
try:
self.assertIn("admin" ,text)
except AssertionError:
nowtime = time.strftime("%Y_%m_%d %H_%M_%s")
driver.get_screenshot_as_file("D:\cnblogtest\\%s.jpg"%nowtime)
# 抛出异常
raise AssertionError
...
####################################
测试报告的生成
1,就是html格式的
2,内容就是哪一条通过,哪一条没有通过,
3,HTMLTestRunner() 使用这种替代TextTestRunner()
###################################
from test_01 import Test01 import time import unittest from HTMLTestRunner import HTMLTestRunner if __name__ == '__main__': suite = unittest.defaultTestLoader.discover("./",pattern="test*.py") # 第一参数是指定文件夹,第二个参数是指定的py文件 # 定义个报告存放的路径,支持相对路径 file_path = "./report/" nowtime = time.strftime("%Y_%m_%d %H_%M_%S") file_name = file_path+nowtime+"report.html" # 写入数据 with open(file_name, 'wb') as f : # 定义测试报告 runner = HTMLTestRunner(stream=f, title=u"百度搜索测试报告", description=u"用例执行情况") runner.run(suite)
###################################
技术改变命运