十三.自动化测试
完整的测试步骤:
比如百度:打开浏览器——输入框关键字点击搜索——验证搜索是否正确——关闭浏览器
测试用例就是测试点,测试固件是初始化和清理
测试用例:就是测试类里面编写的测试方法,它的英文单词是TestCase 测试固件:初始化和清理,使用到的方法分别是setUp()和tearDown()
代码编写测试步骤:
注意事项: 1.测试用例名必须是以test开头的 比如测试新浪邮箱登录用户名为空的用例名称,必须先有test:test_sina_uername def test_sina_uername(self): 2.每个测试点都需要有标题 3.每个测试点都需要有断言 4.测试点的名称不嫩一致 执行顺序: 1.先执行setUp 2.执行测试点的代码 3.最后执行tearDown
测试固件
测试固件的主体结构1如下:
import unittest class TestBaidu(unittest.TestCase): def setUp(self) -> None: passs def tearDown(self) -> None: passs
其中:setUp() and tearDown():在一个测试类里面,有多少个测试用例,它就会被执行多少次,这样不仅会对我们的浏览器增加许多负载,而且也很麻烦,对此,我们可以使用类的方法:setUpClass() and tearDownClass()
测试固件的主体结构2如下:
import unittest @classmethod def setUpClass(cls) -> None: cls.driver=webdriver.Chrome() cls.driver.maximize_window() cls.driver.get('http://www.baidu.com') cls.driver.implicitly_wait(30) @classmethod def tearDownClass(cls) -> None: cls.driver.quit()
其中:setUpClass() and tearDownClass():是类的方法,不管测试类里面有多少测试用例,它只会执行一次,这样也会方便很多,但是也会存在一个弊端,它可以在单页面里更好的运行,而在一些跳转的页面里,它就无法去执行,除非代码里提前设置好跳转的处理操作。
import unittest from selenium import webdriver from selenium.webdriver.common.by import By import time #初始化,打开需要测试的网址,此种方式会多次执行初始化和清理 # class Testsina(unittest.TestCase): # def setUp(self) -> None: # self.driver=webdriver.Chrome() # self.driver.maximize_window() # self.driver.get('https://mail.sina.com.cn/') # self.driver.implicitly_wait(30) #类测试固件,初始化和清理,打开和关闭网址只要一次。但是不能多窗口切换,需要重新设置 class Testsina(unittest.TestCase): @classmethod def setUp(cls) -> None: cls.driver=webdriver.Chrome() cls.driver.maximize_window() cls.driver.get('https://mail.sina.com.cn/') cls.driver.implicitly_wait(30) def test_sina_uername(self): #验证用户名为空的错误提示消息 self.driver.find_element(By.CLASS_NAME,'loginBtn').click() time.sleep(1) divTest=self.driver.find_element(By.XPATH,'/html/body/div[1]/div/div[2]/div/div/div[4]/div[1]/div[1]/div[1]/span[1]').text #==:比较两个对象的值 # self.assertEqual(divTest,'请输入邮箱名') #在。。。范围内,in的字符串比较 self.assertIn(divTest,'请输入邮箱名') #针对是否的断言,比如是否自动登录是否勾选,勾选了 def test_isAuto_login(self): islogin=self.driver.find_element(By.ID,'store1') self.assertTure(islogin.is_selected()) # 针对是否的断言,比如是否自动登录是否勾选,没有勾选 def test_isNotAuto_login(self): islogin = self.driver.find_element(By.ID, 'store1') islogin.click() self.assertFalse(islogin.is_selected()) #清理,关闭测试网址 # def tearDown(self) -> None: # self.driver.close() @classmethod def tearDown(cls) -> None: cls.driver.close() #主函数 if __name__=='main': unittest.main()
上述代码里使用到了断言:(之所以使用断言是因为,它可以让测试人员更加明确的知道,实际与期望的结果之间的问题。)
assertEqual():比较的是两个对象的==关系
assertIs():比较两个字符串的内存地址
bool判断:assertTrue()、assertFalse()
import unittest from selenium import webdriver from selenium.webdriver.common.by import By import time class Testbaidu(unittest.TestCase): def setUp(self) -> None: self.driver=webdriver.Chrome() self.driver.maximize_window() self.driver.get('https://www.baidu.com/') self.driver.implicitly_wait(30) def tearDown(self) -> None: self.driver.close() def test_find_value(self): '''验证输入框里边的文字信息''' find=self.driver.find_element(By.ID,'kw') find.send_keys('为什么每天都很困') time.sleep(2) self.assertEqual(find.get_attribute('value'),'为什么每天都很困') time.sleep(1) def test_baidu_title(self): '''验证百度的title''' self.assertEqual(self.driver.title,'百度一下,你就知道') time.sleep(1) def test_baidu_url(self): '''验证当前的地址''' self.assertTrue(self.driver.current_url.endswith('baidu.com/')) time.sleep(1) if __name__ =='main': unittest.main()
知识点回顾:如果不想继承该类,而又想调用该类的方法,我们应该:进行类的对象实例化即可。 c、在测试类里面编写的方法叫测试方法,测试方法必须是以test开头的,如第10行
测试套件:顾名思义,就是有许多测试用例的集合体。
test_qq
import unittest from selenium import webdriver from selenium.webdriver.common.by import By import time class Testqq(unittest.TestCase): def setUp(self) -> None: self.driver=webdriver.Chrome() self.driver.maximize_window() self.driver.get('https://file.qq.com/') self.driver.implicitly_wait(30) def tearDown(self) -> None: self.driver.close() def test_qq_username(self): '''验证用户名错误提示信息''' self.driver.switch_to.frame(0) self.driver.switch_to.frame(0) self.driver.find_element(By.ID,'switcher_plogin').click() time.sleep(1) self.driver.find_element(By.ID,'u').send_keys('234') time.sleep(1) self.driver.find_element(By.ID,'login_button').click() time.sleep(1) divTest=self.driver.find_element(By.XPATH,'//*[@id="err_m"]').text self.assertEqual(divTest,'请输入正确的帐号!') def test_qq_allchick(self): '''验证全选按钮勾选''' self.driver.switch_to.frame(0) ischick=self.driver.find_element(By.XPATH,'//*[@id="accredit_info"]/ul/li[1]/label') self.assertFalse(ischick.is_selected()) def test_qqagree_ischeck(self): '''切换到注册页面,验证勾选''' self.driver.switch_to.frame(0) self.driver.switch_to.frame(0) nowHandler = self.driver.current_window_handle self.driver.find_element(By.LINK_TEXT, '注册帐号').click() time.sleep(2) # 获取所有的窗口 allHandlers = self.driver.window_handles # 对所有的窗口循环 for handler in allHandlers: if handler != nowHandler: self.driver.switch_to.window(handler) time.sleep(2) '''验证服务协议和隐私已经勾选''' self.driver.find_element(By.ID,'get_acc').click() ischeck=self.driver.find_element(By.XPATH,'/html/body/div[3]/div[2]/div[1]/form/div[6]/div/div').text self.assertEqual(ischeck,'请先同意服务条款和隐私政策') if __name__ =='main': unittest.main()
运行合集,生成报告
我们在test的模块下,编写了很多的测试用例,但是实际的工作环境中,我们总不能按测试模块来执行,我们都是加载所有的测试模块来执行并且最终生成基于HTML的测试报告,测试报告会使用到第三方的库HTMLTestRunner。下载的地址为:https://github.com/tungwaiyip/HTMLTestRunne
导入插件 import HTMLTestRunner
将插件下载保存到python3的lib目录下之后,导入此插件
创建report文件目录,必须和tests目录在一个层级。以上的所有类比的test都是在tests目录下的。在该文件夹里新建一个存放我们测试报告的html报告,假设取名为”report.html“。
import unittest import os import HTMLTestRunner def base_dir(): return os.path.dirname(os.path.dirname(__file__)) def allTests(): suite=unittest.TestLoader().discover(start_dir=os.path.dirname(__file__), pattern='test_*.py') return suite def run(): filename=os.path.join(base_dir(),'report','report.html') fp=open(filename,'wb') runner=HTMLTestRunner.HTMLTestRunner(stream=fp,title='自动化测试报告',description='UI自动化测试报告') runner.run(allTests()) if __name__ == '__main__': run()
运行完成后,我们用浏览器的方式打开”report.html“,打开内容如下:
运行完成且都成功的话如图: