安庆大理运城常德铜陵江西
投稿投诉
江西南阳
嘉兴昆明
铜陵滨州
广东西昌
常德梅州
兰州阳江
运城金华
广西萍乡
大理重庆
诸暨泉州
安庆南充
武汉辽宁

自动化测试unittest框架,理论和实操双管齐下

7月15日 辞凤阙投稿
  unittest
  1、什么是Unittest框架?
  python自带一种单元测试框架
  2、为什么使用UnitTest框架?
  批量执行用例
  提供丰富的断言知识
  可以生成报告
  3、核心要素:
  1)。TestCase(测试用例)
  2)。TestSuite(测试套件)
  3)。TestRunner(测试执行,执行TestUite测试套件的)
  4)。TestLoader(批量执行测试用例搜索指定文件夹内指定字母开头的模块)【推荐】
  5)。Fixture(固定装置(两个固定的函数,一个初始化时使用,一个结束时使用))
  接下来会展开核心要素来认识unittest框架:
  首先介绍下unittest的用例规则:
  1、测试文件必须导包:importunittest
  2、测试类必须继承unittest。TestCase
  3、测试方法必须以test开头
  一、TestCase(测试用例)
  1、是一个代码文件,在代码文件中来书写真正的用例代码(里面的print均是模拟测试用例)1、导包2、自定义测试类3、在测试类中书写测试方法采用print简单书写测试方法4、执行用例importunittest2、自定义测试类,需要继承unittest模块中的TestCase类即可classTestDemo(unittest。TestCase):书写测试方法,测试用例代码,书写要求,测试方法必须test开头deftestmethod1(self):print(测试方法11)deftestmethod2(self):print(测试方法12)4、执行测试用例4。1光标放在类后面执行所有的测试用例4。2光标放在方法后面执行当前的方法测试用例
  说明:def定义的test是测试用例,只有执行ifnamemian的时候会执行测试用例,其他普通函数则不执行,通过self来调用执行。
  二、TestSuite(测试套件)和TestRunner(测试执行)
  1、TestSuite(测试套件):用来组装,打包,管理多个TestCase(测试用例)文件的
  2、TestRunner(测试执行):用来执行TestSuite(测试套件的)
  代码:首先要准备多个测试用例的文件才可以实现TestSuite和TestRunner,以下代码是已经准备了unittestDemo2和unittestDemo1两个测试用例文件1、导包2、实例化(创建对象)套件对象3、使用套件对象添加用例方法4、实例化对象运行5、使用运行对象去执行套件对象importunittestfromunittestDemo2importTestDemofromunittestDemo1importDemosuiteunittest。TestSuite()将个测试类中的所有法进添加套件对象。addTest(unittest。makeSuite(测试类名))suite。addTest(unittest。makeSuite(TestDemo))suite。addTest(unittest。makeSuite(Demo))4、实例化运行对象runnerunittest。TextTestRunner();5、使用运行对象去执行套件对象运对象。run(套件对象)runner。run(suite)
  三、TestLoader(测试加载)
  说明:
  将符合条件的测试方法添加到测试套件中
  2。搜索指定目录文件下指定字母开头的模块文件下test开始的方法,并将这些方法添加到测试套件中,最后返回测试套件
  3。与Testsuite功能一样,对他功能的补充,用来组装测试用例
  一般测试用例是写在Case这个文件夹里面,当测试用例超多的时候就可以考虑TestLoader写法:1。suiteunittest。TestLoader()。discover(指定搜索的目录文件,指定字母开头模块文件)2。suiteunittest。defaultTestLoader。discover(指定搜索的目录文件,指定字母开头模块文件)【推荐】注意:如果使用写法1,TestLoader()必须有括号。1。导包2。实例化测试加载对象并添加用例得到的是suite对象3。实例化运行对象4。运行对象执行套件对象importunittest实例化测试加载对象并添加用例得到的是suite对象unittest。defaultTestLoader。discover(用例所在的路径,用例的代码文件名)测试路径:相对路径测试文件名:可以使用通配符,可以重复使用suiteunittest。defaultTestLoader。discover(。Case,cs。py)runnerunittest。TextTestRunner()runner。run(suite)TestSuite与TestLoader区别:共同点:都是测试套件不同点:实现方式不同TestSuite:要么添加指定的测试类中所有test开头的方法,要么添加指定测试类中指定某个test开头的方法TestLoader:搜索指定目录下指定字母开头的模块文件中以test字母开头的方法并将这些方法添加到测试套件中,最后返回测试套件
  四、Fixture(测试夹具)
  是一种代码结构,在某些特定情况下,会自动执行。
  4。1方法级别
  在每个测试方法(用例代码)执行前后都会自动调用的结构
  defsetUp(),每个测试方法执行之前都会执行(初始化)
  deftearDown(),每个测试方法执行之后都会执行(释放)
  特性:几个测试函数,执行几次。每个测试函数执行之前都会执行setUp,执行之后都会执行tearDwon初始化defsetUp(self):每个测试方法执行之前执行的函数pass释放deftearDown(self):每个测试方法执行之后执行的函数pass场景:当你要登录自己的用户名账户的时候,都会输入网址,当你准备不用这个页面了,都会关闭当前页面;1、输入网址(方法级别)2、关闭当前页面(方法级别)
  4。2类级别
  在每个测试类中所有方法执行前后都会自动调用的结构(在整个类中执行之前执行之后各一次)
  defsetUpClass(),类中所有方法之前
  deftearDownClass(),类中所有方法之后
  特性:测试类运行之前运行一次setUpClass,类运行之后运行一次tearDownClass
  注意:类方法必须使用classmethod修饰classmethoddefsetUpClass(cls):print(1。打开浏览器)classmethoddeftearDownClass(cls):print(5、关闭浏览器)场景:你上网的整个过程都首先需要打开浏览器,关闭浏览器,而他们整个过程都需要执行一次,那么就可以用类级别。
  案列模板:结合了类级别和方法级别实现的
  〔外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(imgGBxQV2uP1647245316010)(C:Users15277AppDataRoamingTyporatyporauserimagesimage20220303153824329。png)〕提示:无论使用函数级别还是类级别,最后常用场景为:初始化:1。获取浏览器实例化对象2。最大化浏览器3。隐式等待结束:关闭浏览器驱动对象
  五、断言
  1、什么是断言:
  让程序代替人工自动的判断预期结果和实际结果是否相符
  断言的结果:
  1)、True,用例通过
  2)、False,代码抛出异常,用例不通过
  3)、在unittest中使用断言,需要通过self。断言方法
  2、为什么要断言:
  自动化脚本执行时都是无人值守,需要通过断言来判断自动化脚本的执行是否通过
  注:自动化脚本不写断言,相当于没有执行测试一个效果。
  3、常用的断言:self。assertEqual(ex1,ex2)判断ex1是否和ex2相等self。assertIn(ex1,ex2)ex2是否包含ex1注意:所谓的包含不能跳字符self。assertTrue(ex)判断ex是否为True重点讲前两个assertEqual和assertIn方法:assertEqual:self。assertEqual(预期结果,实际结果)判断的是预期是否相等实际assertIn:self。assertIn(预期结果,实际结果)判断的是预期是否包含实际中assertIn(admin,admin)包含assertIn(admin,adminnnnnnnn)包含assertIn(admin,aaaaaadmin)包含assertIn(admin,aaaaaadminnnnnnn)包含assertIn(admin,addddddmin)不是包含Login函数我已经封装好了,这里直接导包调用就可以了。importunittestfromloginimportLoginclassTestLogin(unittest。TestCase):正确的用户名和密码:admin,123456,登录成功deftestsuccess(self):self。assertEqual(登录成功,Login(admin,123456))deftestusernameerror(self):错误的用户名:root,123456,登录失败self。assertEqual(登录失败,Login(root,123456))deftestpassworderror(self):错误的密码:admin,123123,登录失败self。assertEqual(登录失败,Login(admin,123123))deftesterror(self):错误的用户名和错误的密码:aaa,123123,登录失败self。assertEqual(登录失败,Login(登陆失败,123123))self。assertIn(失败,Login(登录失败,123123))六、跳过
  对于一些未完成的或者不满足测试条件的测试函数和测试类,不想执行,可以使用跳过使用方法,装饰器完成代码书写在TestCase文件直接将测试函数标记成跳过unittest。skip(跳过条件)根据条件判断测试函数是否跳过,判断条件成立,跳过unittest。skipIf(判断条件,跳过原因)importunittestversion20classTestDemo1(unittest。TestCase):unittest。skip(直接跳过)deftestmethod1(self):print(测试用例11)unittest。skipIf(version19,版本大于19,测试跳过)deftestmethod2(self):print(测试用例12)
  结果
  七、数据驱动(unittestddt)
  ddt:datadrivertests
  数据驱动:是以数据来驱动整个测试用例的执行,也就是测试数据决定测试结果
  数据驱动解决的问题是:
  1)、代码和数据分离,避免代码冗余
  2)、不写重复的代码逻辑;
  在python解释器中需要安装ddt这个包才能用:
  要检查是否安装上,在cmd当中输入piplist命名,有ddt说明安装成功
  语法:
  1、使用数据驱动,要在class前加上修饰器ddt
  说明:方法里面使用print,为了方便,模拟测试用例,主要是为了学习数据驱动,实际中方法里面写的是测试用例的代码
  importunittestfromddtimportddt,dataddtclassTestDemo(unittest。TestCase):单一参数data(17611110000,17611112222)deftest1(self,phone):print(测试一电话号码:,phone)ifnamemain:unittest。main()else:pass
  1)、结合selenium使用ddtunittestseleniumimportunittestfromtimeimportsleepfromddtimportddt,datafromseleniumimportwebdriverddtclassTestBaidu(unittest。TestCase):defsetUp(self)None:self。driverwebdriver。Chrome()self。driver。get(https:www。sogou。com)deftearDown(self)None:sleep(3)self。driver。quit()单一参数data(易烊千玺,王嘉尔)deftest01(self,name):self。driver。findelementbyid(query)。sendkeys(name)self。driver。findelementbyid(stb)。click()ifnamemain:unittest。main()
  self:相当于java中的this,当前对象的引用,self。driver定义了driver这个变量。
  2、在实际中不可能是单一参数进行传参,将会使用多个参数进行传参:注意事项:1)、多个数据传参的时候data里面是要用列表形式2)、会用到unpack装饰器进行拆包,把对应的内容传入对应的参数;importunittestfromddtimportddt,data,unpackddtclassTestDemo(unittest。TestCase):多参数数据驱动data(〔admin,123456〕)unpack是进行拆包,不然会把列表里面的数据全部传到username这个一个参数,我们要实现列表中的两个数据分别传入对应的变量中unpackdeftest2(self,username,password):print(测试二:,username,password)ifnamemain:unittest。main()else:pass
  但是以上步骤都是数据在代码当中的,假如要测试n个手机号这样的数据,全部写在data装饰器里面就很麻烦,这就引出了数据驱动里面的代码和数据的分离。
  3、将数据放入一个文本文件中,从文件读取数据,如JSON、excel、xml、txt等格式文件,这里演示的是json文件类型。
  json文件处理,这个链接介绍了json文件和Python文件基本操作
  (1)、在json文件驱动〔{username:admin,password:123456},{username:normal,password:45678}〕
  (2)、在测试代码中读取json文件importjsonimportunittestfromddtimportddt,data,unpack用json多个参数读取defreadsphone():withopen(user。json,encodingutf8)asf:resultjson。load(f)列表returnresultddtclassTestDemo(unittest。TestCase):多参数数据驱动data(readsphone())unpack是进行拆包,不然会把列表里面的数据全部传到username这个一个参数,我们要实现列表中的两个数据分别传入对应的变量中unpackdeftest2(self,username,password):print(测试二:,username,password)ifnamemain:unittest。main()else:pass注意事项:1、withopen里面默认是r2、data里面的含义是实现每个json对象单个传入方法执行,不然会吧json文件里面所用数据全部传入是元祖;是字典;3、参数不能传错,要对应
  执行结果:
  (3)、txt文件驱动
  一行表示一组:admin,123456normal,456789importunittestdefread():lis〔〕withopen(readtext。txt,r,encodingutf8)asf:forlineinf。readlines():lis。append(line)〔admin,123456,normal,456789〕lis。append(line。strip())〔admin,123456,normal,456789〕两个字符串lis。append(line。strip()。split(,))〔〔admin,123456〕,〔normal,456789〕〕returnlisclassTestDome(unittest。TestCase):deftest01(self):liread()print(li)ifnamemain:unittest。main()split():一个字符串里面用某个字符分割,返回列表strip():去掉两边的字符或者字符串,默认删除空白符(包括,r,,)(3)、csv文件驱动供应商名称,联系人,移动电话英业达,张三,13261231234阿里巴巴,李四,13261231231日立公司,王五,13261231233
  写法一:编写csvv。py脚本读取csv中的测试数据importcsvclassReadCsv():defreadcsv(self):lis〔〕用csv的API的reader方法!!!!datacsv。reader(open(testdata。csv,r))!!!!next(data,None)forlineindata:lis。append(line)lis。append(line〔0〕)二维数组可以省略行,列不可以省略lis。append(line〔1〕)returnlis实例化类readCsvReadCsv()打印类中的方法print(readCsv。readcsv())
  写法二:推荐defcsvTest():li〔〕withopen(user。csv,r,encodingutf8)asf:filenamecsv。reader(f)next(filename,None)forrinfilename:li。append(r)returnli(4)、yaml文件驱动username:admin9password:123456username:normalpassword:789456
  对应的json文件〔{username:admin9,password:123456},{username:normal,password:7894}〕
  写法:使用yaml数据驱动importunittestfromtimeimportsleepfromseleniumimportwebdriverfromddtimportddt,data,unpack,filedataddtclassYamlTest(unittest。TestCase):defsetUp(self)None:self。driverwebdriver。Chrome()self。driver。get(file:D:E6A18CE99DA2pageE6B3A8E5868CA。html)self。driver。maximizewindow()deftearDown(self)None:driverself。driversleep(3)driver。quit()filedata传入多个参数的时候,unpack的解包不起作用unittest。skipfiledata(。。user。yaml)unpackdeftestyaml01(self,username,password):driverself。driverdriver。findelementbyid(userA)。sendkeys(username)driver。findelementbyid(passwordA)。sendkeys(password)注意:传的参数名称要与yaml文件对应在yaml数据中文件中采用对象(键值对)的方式来定义数据内容filedata(。。user1。yaml)deftestyaml02(self,username,password):driverself。driverdriver。findelementbyid(userA)。sendkeys(username)driver。findelementbyid(passwordA)。sendkeys(password)ifnamemain:unittest。main()
  注意:filedate装饰器,可以直接读取yaml和json文件(4)、Excel文件驱动
  建立excel表的时候需要退出pychram在根目录下创建excel表保存,否则会报错defreadexcel():xlsxopenpyxl。loadworkbook(。。excel。xlsx)sheet1xlsx〔Sheet1〕print(sheet1。maxrow)行print(sheet1。maxcolumn)列print()allList〔〕forrowinrange(2,sheet1。maxrow1):rowlist〔〕forcolumninrange(1,sheet1。maxcolumn1):rowlist。append(sheet1。cell(row,column)。value)allList。append(rowlist)returnallList
  用excel登录csdn操作测试excel数据驱动importunittestfromtimeimportsleepimportopenpyxlasopenpyxlfromddtimportddt,data,unpackfromseleniumimportwebdriver读取excel表中的数据,使用xlrd,openpyxldefreadexcel():xlsxopenpyxl。loadworkbook(。。excel。xlsx)sheet1xlsx〔Sheet1〕print(sheet1。maxrow)行print(sheet1。maxcolumn)列print()allList〔〕forrowinrange(2,sheet1。maxrow1):rowlist〔〕forcolumninrange(1,sheet1。maxcolumn1):rowlist。append(sheet1。cell(row,column)。value)allList。append(rowlist)returnallListddtclassExcelText(unittest。TestCase):defsetUp(self)None:self。driverwebdriver。Chrome()self。driver。get(https:passport。csdn。netlogin?codeapplets)self。driver。maximizewindow()deftearDown(self)None:driverself。driversleep(3)driver。quit()data(readexcel())unpackdeftestexcel01(self,flag,username,password):print(flag,username,password)driverself。driversleep(2)driver。findelementbyxpath(htmlbodyp〔2〕pp〔2〕p〔2〕p〔1〕pp〔1〕span〔4〕)。click()driver。findelementbyxpath(htmlbodyp〔2〕pp〔2〕p〔2〕p〔1〕pp〔2〕pp〔1〕pinput)。sendkeys(username)driver。findelementbyxpath(htmlbodyp〔2〕pp〔2〕p〔2〕p〔1〕pp〔2〕pp〔2〕pinput)。sendkeys(password)driver。findelementbyxpath(htmlbodyp〔2〕pp〔2〕p〔2〕p〔1〕pp〔2〕pp〔4〕button)。click()ifnamemain:unittest。main()十、截图操作
  用例不可能每一次运行都成功,肯定运行时候有不成功的时候。如果可以捕捉到错误,并且把错误截图保存,这将
  是一个非常棒的功能,也会给我们错误定位带来方便
  截图方法:driver。getscreenshotasfile捕捉异常截图测试importos。pathimporttimeimportunittestfromtimeimportsleepfromseleniumimportwebdriverclassScreeshotTest(unittest。TestCase):defsetUp(self)None:self。driverwebdriver。Chrome()self。driver。get(https:www。sogou。com)self。driver。maximizewindow()deftearDown(self)None:sleep(3)driverself。driverdriver。quit()deftest01(self):driverself。driverdriver。findelementbyid(query)。sendkeys(易烊千玺)driver。findelementbyid(stb)。click()sleep(3)print(driver。title)try:self。assertEqual(driver。title,u搜狗一下你就知道,msg不相等)except:self。saveScreenShot(driver,shot。png)sleep(5)defsaveScreenShot(self,driver,filename):ifnotos。path。exists(。imge):os。makedirs(。imge)格式十分重要,小写大写敏感YmdHMSnowtime。strftime(YmdHMS,time。localtime(time。time()))driver。getscreenshotasfile(。imgenowfilename)sleep(3)ifnamemain:unittest。main()
  十一、测试报告
  有两种测试报告:1、自带的测试报告
  2、生成第三方测试报告9。1自带测试报告
  只有单独运行TestCase的代码,才会生成测试报告
  10。2生成第三方测试报告
  这里需要第三方的测试运行类模块,然后放在代码的目录中
  就像这两个模块一样放进代码目录中步骤:1。获取第三方的测试运行类模块,将其放在代码的目录中2。导包unittest3。使用套件对象,加载对象去添加用例方法4。实例化第三方的运行对象并运行套件对象HTMLTestRunner()
  写法一:importunittestfromHTMLTestRunnerimportHTMLTestRunnersuiteunittest。defaultTestLoader。discover(。,Uni。py)filereport1。htmlwithopen(file,wb)asf:runnerHTMLTestRunner(f,2,测试报告,python3。10)运行对象运行对象执行套件,要写在with的缩进中runner。run(suite)
  写法二:生成测试报告importos。pathimportsysimporttimeimportunittestfromtimeimportsleepfromHTMLTestRunnerimportHTMLTestRunnerdefcreatesuite():discoversunittest。defaultTestLoader。discover(。cases,patterncs。py)print(discovers)returndiscoversifnamemain:当前路径sys。path是一个路径的集合curpathsys。path〔0〕print(sys。path)print(sys。path〔0〕)当前路径文件resultreport不存在时,就创建一个ifnotos。path。exists(curpathresultreport):os。makedirs(curpathresultreport)2、解决重名问题nowtime。strftime(YmdHMS,time。localtime(time。time()))print(time。time())print(time。localtime(time。time()))文件名是路径加上文件的名称filenamecurpathresultreportnowresultreport。html打开文件html,是用wb以写的方式打开withopen(filename,wb)asf:runnerHTMLTestRunner(f,2,u测试报告,u测试用例情况)suitecreatesuite()runner。run(suite)
  这里面的当前路径也可以用。来表示!!!生成测试报告importos。pathimportsysimporttimeimportunittestfromtimeimportsleepfromHTMLTestRunnerimportHTMLTestRunnerdefcreatesuite():discoversunittest。defaultTestLoader。discover(。cases,patterncs。py)print(discovers)returndiscoversifnamemain:当前路径文件resultreport不存在时,就创建一个ifnotos。path。exists(。resultreport):os。makedirs(。resultreport)2、解决重名问题格式十分重要YmdHMSnowtime。strftime(YmdHMS,time。localtime(time。time()))print(time。time())print(time。localtime(time。time()))文件名是路径加上文件的名称filename。resultreportnowresultreport。html打开文件html,是用wb以写的方式打开withopen(filename,wb)asf:runnerHTMLTestRunner(f,2,u测试报告,u测试用例情况)suitecreatesuite()runner。run(suite)
  注意:
  实例化第三方的运行对象,HTMLTestRunner()的初始化有多种可以自定义设置
  HTMLTestRunner()1、streamsys。stdout,必填,测试报告的文件对象(open),注意点,要使用wb打开2、verbosity1,可选,报告的详细程度,默认1简略,2详细3、titleNone,可选,测试报告的标题4、descriptionNone可选,描述信息,Python的版本,pycharm版本
  最后生成结果
  unittest框架就本上就是这些知识了,里面记得东西很多,多敲代码,形成记忆。。。
  希望本文对你有所帮助如果对软件测试、接口测试、自动化测试、面试经验交流感兴趣可以私聊我或关注公众号特斯汀软件测试。免费领取最新软件测试大厂面试资料和Python自动化、接口、框架搭建学习资料!技术大牛解惑答疑,同行一起交流。
投诉 评论 转载

荒泷极意堂堂斗虫大试合活动完成斗虫挑战得原石活动时间2023021610:002023022703:59参与条件冒险等阶30级且完成魔神任务离岛逃离计划完成魔神任务危途疑踪后体验更佳。……入冬之后忌讳多,建议中老年人勤喝2汤少饮2酒,早知早受益春种夏长,秋收冬藏,这是老祖宗总结的养生规律,也是大自然运行的自然规律。想要身体好,就要遵循规律,顺应季节吃喝,因时而养生,这样身体才会好,尤其是上了年纪的中老年人,身体……自动化测试unittest框架,理论和实操双管齐下unittest1、什么是Unittest框架?python自带一种单元测试框架2、为什么使用UnitTest框架?批量执行用例提供丰富的断言知识……比steam史低还低价位的游戏!Switch每周打折推荐!春节倒计时,打折出手要及时,本周Switch平台选出了一批难得价位低于Steam平台的不错游戏,当然PSN就不用比较了,想必懂的都懂,另外由《人类一败涂地》发行商CurveGa……新世纪游乐无动力游乐设备有哪几类?不同类型有什么特点?关于无动力游乐设备,很多人还停留在不带电动、液动或气动等任何动力装置的,由攀爬、滑行、钻筒、走梯、荡秋千等功能部件和结构、扣件及连接部件组成的游乐设施的基础概念上,对于无动力游……亭亭玉立!姚明一家亮相,女儿又瘦又飒,名模胚子,身高媲美叶莉不久前,中国篮球协会进行了换届会议,最终姚明毫无疑问地继续担任篮协的领头人,此外郭振明、王芳、徐济成、宫鲁鸣将是姚明的左膀右臂,不得不说这几个人在中国篮球界都是举足轻重的人物,……一加11完整规格以及包装内含物曝光IT之家12月30日消息,一加11已经定档1月4日发布,爆料人士EvanBlass在最新推文中分享了关于该机的完整规格参数,以及包装内含物。EvanBlass透露一加11……曾经销量扛把子,全新蔚来ES8能东山再起吗?蔚来ES8作为蔚来的第一款车,为蔚来的发展奠定了基础和立下了汗马功劳。可如今的蔚来ES8销量在蔚来家庭里占比并不高,已开启预售52。863。8万元的2023款蔚来ES8,相对在……趋势股的卖点趋势股的卖跟情绪股不一样。情绪股只要是看情绪状态还有没有,如果没有了,就要卖了。但,趋势股一旦确定趋势,通常没有疯掉之前,不构成卖点。或者说,趋势股疯的时候,……1月5日玉兔瑞盈发布会倒计时!努力积累巽值,赢取发布会门票!Hi,新年快乐!我是小巽。巽风数字世界已于1月1日上线,在此,感谢大家的支持与喜爱。在今后的日子里,让小巽陪您走进巽风数字世界,发掘其中的奥秘吧!截至1月5日12时,巽值……汽车机器人带来的行业变化及投资机会氢媒体深度出品氢媒体作者Felix头图氢媒体不知道你有没有发现,路面上已经有越来越多的绿牌新能源车在飞驰。身边也有很多的朋友考虑趁着还有新能源车购车补贴的政策背景下,在……YouTube和谷歌Gmail账号注册!关于YouTube和1、谷歌Gmail账号注册(YouTube注册)2、关于YouTube和视频营销基础1、谷歌Gmail账号注册(YouTube注册)2、关于YouTube和视频营销……
DNF天风之子裔!逐风者背景故事分析小米11系列售后新政策保修三年丨音质党狂喜,TWS耳机音质升会展元宇宙促进五大融合倒数第四发!阿丽亚娜5将欧洲史上最高的卫星送入极致椭圆轨道华为,想要超越苹果,越来越难了来自一个新手宝爸的劝告保存1500多年的南朝青釉瓷唾壶折射出古代福州人的文明生活滕哈格告诉曼联高层,在自己确定谁有赚钱资格前不要续约球员别总内切!滕哈赫谈安东尼可以更多尝试走外线,要内外结合人还年轻,但胃已经老了,4种食物令胃黏膜受损,少吃一口是一口家有一个犟脾气的宝宝,父母应该怎么办?郭晶晶和婆婆同穿旗袍,婆媳差距一目了然,谁丑谁尴尬

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找七猫云易事利