第九课 Python自动化之selenium 自动化unittest框架(9.3)

自动化框架

一、介绍框架

1、unittest 框架是python中自带的框架

2、作用:管理和组织测试用例

当我们写的用例越来越多,我们就要考虑用例的编写的规范和组织,以便于后期的维护

3、常见的自动化框架:po框架、pytest 框架、unittest框架(我们讲解)

4、unitest 框架自带标准的库:有如下

a、TestCase类 (测试用例)
b、TestSuite类 (测试套件)
c、TestLoader类 (测试路径)
d、TextTestRunner类 (测试运行)
e、TextTestResult类 (测试结果)
f、TestFixture类 (测试前后准备)
解释下:
TestCase:
一个Testcase的实例就是一个测试用例,测试用例就是一个完整的测试流程,包括初始化setUp、运行run、测试后的还原tearDown
TestSuite:
对一个功能的测试往往需有多个测试用例,可以把多的测试用例集合在一起执行,这就是TestSuite的概念。常用addTest()方法将一个测试用例添加到测试套件中
TextTestRunner:
是用来执行测试用例的,其中的run(test)用来执行TestSuite/TestCase。测试的结果会保存在TextTestResult实例中
TestFixture:
测试准备前要做的工作和测试执行完后要做的工作.包括setUp()和tearDown()。通过覆盖TestCase的setUp和tearDown来实现。
TestLoader:
是用来搜索所有以test开头的测试用例,然后将其加入到testsuite中去执行

5、unittest的框架的结构:

import  unittest # 导入unittest框架
class   Cms_Test(unittest.TestCase): # 创建一个类,一个testcase就是一个用例  ,继承unittest.testcase
    # 类方法
    @classmethod  #定义一个类方法
    def  setUpClass(cls) -> None:  #类的开始,在整个框架中只执行一次
          print("类开始")
    @classmethod  #定义一个类方法
    def  tearDownClass(cls) -> None:   #类的结束  ,在整个框架中只执行一次
        print("类的结束")
    def setUp(self) -> None:  #方法的开始 ,每一条用例执行,他们都去执行
        print("方法的开始")
    def tearDown(self):  #方法结束 ,每条用例都会去执行
        print("方法结束")
    def  test1(self): #用例1    tset 以test开头
        print("1111") #用例内容 (写在函数内,也可以模块在群用,等)
    def   test3(self):#
        print("3333")
    def   test2(self):
        print("2222")
    def   testa(self):
        print("aaaa")
    def   testA(self):
       print("AAAA")
    def  dcs(self): #  没有以test开头的用例 ,不被运行
        print("dcs独有")
if __name__ == '__main__':
     unittest.main() #第一种执行方法,执行全部的用例

结果:
类开始类的结束

方法的开始
1111
方法结束
方法的开始
2222
方法结束
方法的开始
3333
方法结束
方法的开始
AAAA
方法结束
方法的开始
aaaa
方法结束

备注:

1、类的开始,类的结束,方法开始,方法结束都可以不写

2、用例要以test开头,如果没有以test开头就不运行

3、test开头的用例运行顺序: 按ascllma标准:0-9 A-Z a-z

4、类的开始,类的结束在整个框架中就运行一次

5、方法开始和方法结束,每一条用例都执行

第二种运行方式(执行单个用例或指定的用例)

import  unittest # 导入unittest框架
class   Cms_Test(unittest.TestCase): # 创建一个类,一个testcase就是一个用例
    # 类方法
    @classmethod
    def  setUpClass(cls) -> None:
          print("类开始")
    @classmethod
    def  tearDownClass(cls) -> None:
        print("类的结束")
    def setUp(self) -> None:
        print("方法的开始")
    def tearDown(self):
        print("方法结束")
    def  test1(self):
        print("1111")
    def   test3(self):
        print("3333")
    def   test2(self):
        print("2222")
    def   testa(self):
        print("aaaa")
    def   testA(self):
       print("AAAA")
    def  dcs(self): #  没有以test开头的用例
        print("dcs独有")
if __name__ == '__main__':
     # unittest.main() #第一种执行方法,执行所有的用例
     tj=unittest.TestSuite()  # 创建一个套件
     # tj.addTest(Cms_Test('test2')) #通过addtest添加用例到套件中
     tj.addTests([Cms_Test('test2'),Cms_Test('test3')])
     unittest.TextTestRunner().run(tj) #通过TextTestRunner去运行套件中的用例

解决环境运行问题:只要运行单个用例,解决运行整个框架的用例

运行的环境

右键:复制path C:\Users\Administrator.USER-20231114RR\PycharmProjects\untitled4\ui\ui4.py

编辑环境变量

在填写环境地址和相对路径

第三种运行方法:运行一个路径下所有的用例

import  unittest # 导入unittest框架
class   Cms_Test(unittest.TestCase): # 创建一个类,一个testcase就是一个用例
    # 类方法
    @classmethod
    def  setUpClass(cls) -> None:
          print("类开始")
    @classmethod
    def  tearDownClass(cls) -> None:
        print("类的结束")
    def setUp(self) -> None:
        print("方法的开始")
    def tearDown(self):
        print("方法结束")
    def  test1(self):
        print("1111")
    def   test3(self):
        print("3333")
    def   test2(self):
        print("2222")
    def   testa(self):
        print("aaaa")
    def   testA(self):
       print("AAAA")
    def  dcs(self): #  没有以test开头的用例
        print("dcs独有")
if __name__ == '__main__':
     # unittest.main() #第一种执行方法,执行所有的用例
     # tj=unittest.TestSuite()  # 创建一个套件
     # # tj.addTest(Cms_Test('test2')) #通过addtest添加用例到套件中
     # tj.addTests([Cms_Test('test2'),Cms_Test('test3')])
     # unittest.TextTestRunner().run(tj) #通过TextTestRunner去运行套件中的用例
     path=r"C:\Users\Administrator.USER-20231114RR\PycharmProjects\untitled4\ui" #运行文件的相对路径
     d=unittest.TestLoader().discover(start_dir=path,pattern="ui4*.py")  #测试路径:路径和匹配的文件   一般接*结尾  
     unittest.TextTestRunner().run(d) #运行路径下的用例

第四种方法:运行一个测试报告

import  unittest # 导入unittest框架
from  time import  * #导入时间模块
from ui.HTMLTestRunner3_New import HTMLTestRunner #导入报告模板
class   Cms_Test(unittest.TestCase): # 创建一个类,一个testcase就是一个用例
    # 类方法
    @classmethod
    def  setUpClass(cls) -> None:
          print("类开始")
    @classmethod
    def  tearDownClass(cls) -> None:
        print("类的结束")
    def setUp(self) -> None:
        print("方法的开始")
    def tearDown(self):
        print("方法结束")
    def  test1(self):
        print("1111")
    def   test3(self):
        print("3333")
    def   test2(self):
        print("2222")
    def   testa(self):
        print("aaaa")
    def   testA(self):
       print("AAAA")
    def  dcs(self): #  没有以test开头的用例
        print("dcs独有")
if __name__ == '__main__':
     # unittest.main() #第一种执行方法,执行所有的用例
     # tj=unittest.TestSuite()  # 创建一个套件
     # # tj.addTest(Cms_Test('test2')) #通过addtest添加用例到套件中
     # tj.addTests([Cms_Test('test2'),Cms_Test('test3')])
     # unittest.TextTestRunner().run(tj) #通过TextTestRunner去运行套件中的用例
     # path=r"C:\Users\Administrator.USER-20231114RR\PycharmProjects\untitled4\ui" #运行文件的相对路径
     # d=unittest.TestLoader().discover(start_dir=path,pattern="ui4*.py")
     # unittest.TextTestRunner().run(d)
     path = r"C:\Users\Administrator.USER-20231114RR\PycharmProjects\untitled4\ui" #运行文件的相对路径
     d=unittest.TestLoader().discover(start_dir=path,pattern="ui4*.py") #匹配用例文件
     bglj=r"C:\Users\Administrator.USER-20231114RR\PycharmProjects\untitled4\ui" #运行文件的相对路径
     new=strftime("%y-%m-%d-%H-%M-%S") # 时间戳
     file=bglj+'/'+str(new)+"ui_.html" #file的路径和时间+生成报告的后缀
     f=open(file,"bw")  #open打开文件,b表示而二进制的方式写入(w)到文件中
     r=HTMLTestRunner(
         stream=f,title="ui自动化测试报告",description="用例执行情况",
         tester="dcs"
     )
     r.run(d)  # run执行 匹配到的用例

以上讲解结构,接下来我们就针对项目来进行编写内容
案例:

import   unittest
from   time  import   *
from   selenium import   webdriver
class  Cms_Test(unittest.TestCase):
    @classmethod
    def  setUpClass(cls) -> None:
        pass
    @classmethod
    def  tearDownClass(cls) -> None:
        pass
    def  setUp(self) -> None: #运行前用例的操作
        self.dx = webdriver.Chrome()
        self.dx.get("http://cms.duoceshi.cn/manage/login.do")
        self.dx.find_element_by_name("userAccount").send_keys("admin")
        self.dx.find_element_by_name("loginPwd").send_keys("123456")
    def   tearDown(self) -> None: #运行完一个用例后操作
         sleep(5)
         self.dx.close()  #
    def  test1_tc(self):
        self.dx.find_element_by_xpath("html/body/div/div/form/div[3]/label/input").click()
        sleep(2)
        self.dx.find_element_by_xpath("html/body/div/div/form/div[4]/input[1]").click()
        self.dx.maximize_window()
        sleep(2)
        self.dx.find_element_by_link_text("退出").click()
    def  test2_xtgl(self):
        self.dx.find_element_by_xpath("html/body/div/div/form/div[3]/label/input").click()
        sleep(2)
        self.dx.find_element_by_xpath("html/body/div/div/form/div[4]/input[1]").click()
        self.dx.maximize_window()
        sleep(2)
        self.dx.find_element_by_xpath('//*[@id="menu-system"]/dt').click()
        sleep(3)
        self.dx.find_element_by_link_text("退出").click()
if __name__ == '__main__':
    unittest.main()

自动化用例编写注意点:
1、一个自动化脚本就是一个完整的场景:从开始—执行过程—结束(退出)
2、一个自动化脚本只验证一个功能点,不要试图把所有功能都写在一个用例中
3、编写自动化用例尽量是正常场景,避免异常场景(用名不填验证登录)
4、自动动化用例直接尽量保证独立性,不要造成一个用例与多个用例产出数据上或业务上的关联,这会给后期带来用例维护上的不便
5、自动化用例的断言,只针对需要断言的地方进行断言(重要环节),没必要在每个环境进行断言验证

总结unittest讲解稿:
参考

讲解1:
流程:

我们要建立这个框架,首先需要导入unittest这个模块,我们做自动化的话还需要导入selenium这个模块,以及一些相关的,比方说time模块,OS模块,HTMLTestRunner模块。把我们需要的模块都导入,在unittest里我们需要去定义一个类,定义类名,继承testcase,一个testcase的实例就是一个用例,类里需要有类的开始:setupclass,以及类的结束:teardownclass,然后我们需要去定义我们的用例,test1,test2,注意一定要以test开头,因为TestLoader只搜索所有以test开头的测试用例。

写完用例以后,我们需要去调用它,我们以main作为unittest的入口,执行自动化我们主要有4种调用的方式

第一种用unittest.main()去运行所有用例

第二种是创建一个套件TestSuite(),然后用addtest去添加你要执行的用例,这种方法可以执行部分测试用例,不会全部执行

第三种就是搜索绝对路径去执行自动化,调用unittest.testloader.discover方法执行用例

第四种是生成测试报告,搜索绝对路径去执行自动化,调用unittest.testloader.discover方法执行用例,然后把执行结果写入我们导入的模板文件,执行之后就能看到我们路径下所有用例的执行结果。

以上就是unittest框架的整个基本流程

讲解2:

建立unittest框架流程:
第一步先导入unittest模块:import unittest;然后导入selenium模块:from selenium import webdriver、时间模块:from time import*等。第二步定义一个类,给这个类取一个类名,继承unittest.testcase,一个testcase就是一个用例,之后定义一个类方法,类方法要有类的开始(setUpClass)和类的结束(tearDownClass)。第三步进行方法的开始(setUp),每一条用例执行,他们都去执行,之后是方法的结束(tearDown)。第四步写用例,用例一定要用test开头=》test1、test2,没有以test开头的用例 ,不被运行。第五步调用函数,使用main方法(if name=='main':)进行主函数调用。第六步执行用例,第一种可以用unittest.main()运行所有用例;第二种可以创建一个套件TestSuite(),然后用addtest去添加你要执行的用例,这种方法可以执行部分测试用例,不会全部执行;第三种搜索绝对路径去执行自动化,调用unittest.testloader.discover方法执行用例;第四种生成测试报告,搜索绝对路径去执行自动化,调用unittest.testloader.discover方法执行用例,然后把执行结果写入我们导入的模板文件,执行之后就能看到我们路径下所有用例的执行结果。

讲解3:

下面我介绍一下自动化框架的基本流程:自动化框架是用来管理和组织测试用例的,首先我们先导入unittest框架,再导入本次测试应用到的一些模块,比如time模块(进行计时)等等。接下来我们进行类的定义,创建一个类,一个testcase就是一个用例,继承unittest.testcase,定义类需要类的开始setUpClass()和类的结束tearDownClass() ,在整个框架中只运行一次。为了减少代码的冗余,我们需要进行方法的定义,调用的时候直接使用这个方法名就可以了,方法的开始和结束每一条用例都会执行。然后我们进行用例定义,用例要以test开头,如果没有以test开头就不能运行,运行顺序按ascllma标准排序:0-9 A-Z a-z。
用例编写完成之后,我们进行用例的调用,这里我们有四种方法:
1.unittest.main() #第一种执行方法,执行所有的用例
2.创建一个套件TestSuite(),通过addtest添加用例到套件中,通过TextTestRunner去运行套件中的用例
3.根据运行文件的相对路径执行自动化测试,通过unittest.TestLoader().discover匹配测试路径和文件, unittest.TextTestRunner().run(d) 运行路径d下的用例
4.根据运行文件的相对路径执行自动化测试,通过unittest.TestLoader().discover匹配测试路径和文件,接下来把执行结果写入我们导入的模板文件,执行之后就能看到我们路径下所有用例的执行结果。

posted @ 2024-11-18 14:25  影清风  阅读(7)  评论(0编辑  收藏  举报