十三.自动化测试

完整的测试步骤:

初始化 ——测试步骤——测试断言——测试清理

比如百度:打开浏览器——输入框关键字点击搜索——验证搜索是否正确——关闭浏览器

测试用例就是测试点,测试固件是初始化和清理

测试用例:就是测试类里面编写的测试方法,它的英文单词是TestCase 测试固件:初始化和清理,使用到的方法分别是setUp()和tearDown() 测试套件:TestSuite,就是测试用例的集合,在一个测试套件可以有很多的测试用例 测试执行:TestRunner,执行测试套件或者测试用例 测试报告:TestReport,就是执行所有测试用例后的结果信息

代码编写测试步骤:

注意事项: 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():是类的方法,不管测试类里面有多少测试用例,它只会执行一次,这样也会方便很多,但是也会存在一个弊端,它可以在单页面里更好的运行,而在一些跳转的页面里,它就无法去执行,除非代码里提前设置好跳转的处理操作。

test_sina

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():比较的是两个对象的==关系

assertIn():比较的是两个对象的包含关系

assertIs():比较两个字符串的内存地址

bool判断:assertTrue()、assertFalse()

test_baidu

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()

unittest是单元测试框架,使用它的注意事项: a、测试类建议以Test开头,如第7行 b、每个测试类必须要继承unittest模块中的TestCase类,这样就可以直接调用里面的方法,如第7行

知识点回顾:如果不想继承该类,而又想调用该类的方法,我们应该:进行类的对象实例化即可。 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()

运行合集,生成报告

UnitTest生成测试报告需要借助第三方的库HtmlTestRunner.py的文件

我们在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“,打开内容如下:

 运行完成且都成功的话如图: