当前位置: 首页 > news >正文

上海专业网站建设市场成都房价

上海专业网站建设市场,成都房价,怎么在手机上做企业网站,仿站网站建设文章目录 1.unittest框架解析2.批量执行脚本2.1构建测试套件2.2用例的执行顺序2.3忽略用例执行 3.unittest断言4.HTML报告生成5.异常捕捉与错误截图6.数据驱动 大家好#xff0c;我是晓星航。今天为大家带来的是 自动化测试selenium第三节 相关的讲解#xff01;#x1f600… 文章目录 1.unittest框架解析2.批量执行脚本2.1构建测试套件2.2用例的执行顺序2.3忽略用例执行 3.unittest断言4.HTML报告生成5.异常捕捉与错误截图6.数据驱动 大家好我是晓星航。今天为大家带来的是 自动化测试selenium第三节 相关的讲解 1.unittest框架解析 unittest 是python 的单元测试框架它主要有以下作用 **提供用例组织与执行**当你的测试用例只有几条时可以不必考虑用例的组织但是当测试用例达到 成百上千条时大量的测试用例堆砌在一起就产生了扩展性与维护性等问题此时需要考虑用例的规 范与组织问题了。单元测试框架就是来解决这个问题的。 **提供丰富的比较方法**在用例执行完之后都需要将实际结果与预期结果进行比较断言从而断定用 例是否可以顺利通过。单元测试一般会提供丰富的断言方法。例如判断相等/不相等、包含/不包含、 True/False等断言方法。 **提供丰富的日志**当测试用例执行失败时能抛出清晰的失败原因当所有用例执行完成后能提供丰富的 执行结果。例如总的执行时间失败用例数成功用例数等。 unittest里面有四个很重要的概念test fixturetest casetest suitetest runner。 Test Fixture 对一个测试用例环境的搭建和销毁就是一个fixture通过覆盖setUp()和tearDown()方法来实 现。 setUp()方法可以进行测试环境的搭建比如获取待测试浏览器的驱动或者如果测试中需要访问 数据库那么可以在setUp()中通过建立数据库连接来进行初始化。 tearDown()方法进行环境的销毁可以进行关闭浏览器关闭数据库连接清除数据库中产生的 数据等操作 Test Case 一个TestCase的实例就是一个测试用例。测试用例就是一个完整的测试流程包括测试前准备环 境的搭建setUp、实现测试过程的代码以及测试后环境的还原tearDown。单元测试 unit test的本质就在这里一个测试用例就是一个完整的测试单元可以对某一个功能进行验 证。 Test Suite 一个功能的验证往往需要多个测试用例可以把多个测试用例集合在一起执行这个就产生了测试 套件TestSuite的概念。Test Suit用来将多个测试用例组装在一起 Test Runner 测试的执行也是非常重要的一个概念在unittest框架中通过TextTestRunner类提供的run()方 法来执行test suite/test case。 下面为一个使用了unittest框架的脚本 from selenium import webdriver import unittest import time import os from selenium.common.exceptions import NoAlertPresentException from selenium.common.exceptions import NoSuchElementException class Baidu1(unittest.TestCase): def setUp(self): print(-----setUp-----) self.driver webdriver.Chrome() self.url https://www.baidu.com/ self.driver.maximize_window() time.sleep(3) def tearDown(self): print(-----tearDown-----) self.driver.quit() def test_hao(self): driver self.driver url self.url driver.get(url) driver.find_element_by_link_text(hao123).click() time.sleep(6) def test_hbaidu(self): driver self.driver url self.url driver.get(url) driver.find_element_by_id(kw).send_keys(突如其来的假期) driver.find_element_by_id(su).submit() time.sleep(5) print(driver.title) # self.assertNotEqual(driver.title, 百度一下_百度搜索, msg不相等) # self.assertTrue(beautifulbeauty, msgNot Equal!) time.sleep(6) def saveScreenAsPhoto(self, driver, file_name): if not os.path.exists(./image): os.makedirs(./image) now time.strftime(%Y%m%d-%H%M%S, time.localtime(time.time())) driver.get_screenshot_as_file(./image/ now - file_name) time.sleep(3) if __name__ __main__: unittest.main()这个脚本中的类 Baidu1 继承了unittest.TestCase类所以它使用了unittest框架来组织测试用例 TestCase。 setUp() 和 setDown() 是unittest框架中的测试固件 以**test_**开头命名的方法是测试方法在运行整个类的时候会默认执行。 unittest提供了全局的main()方法使用它可以方便地将一个单元测试模块变成可以直接运行的测试脚 本。main()方法搜索所有包含在该模块中以”test命名的测试方法并自动执行他们。 2.批量执行脚本 2.1构建测试套件 当我们增加了被测试功能和相应的测试用例之后我们就需要把多个测试用例组织在一起执行那 unittest框架是如何扩展和组织新增的测试用例的呢它使用的就是上文中提到的测试套件Test Suite 假设我们已经编写了testbaidu1.pytestbaidu2.py两个文件那么我们怎么同时执行这两个文件呢 testbaidu1.py from selenium import webdriver import unittest import time import os from selenium.common.exceptions import NoAlertPresentException from selenium.common.exceptions import NoSuchElementException class Baidu1(unittest.TestCase): def setUp(self): self.driver webdriver.Chrome() self.url https://www.baidu.com/ self.driver.maximize_window() time.sleep(3) def tearDown(self): self.driver.quit() def test_hao(self): driver self.driver url self.url driver.get(url) driver.find_element_by_link_text(hao123).click() time.sleep(6) def test_hbaidu(self): driver self.driver url self.url driver.get(url) driver.find_element_by_id(kw).send_keys(突如其来的假期) driver.find_element_by_id(su).submit() time.sleep(5) print(driver.title) time.sleep(6) def saveScreenAsPhoto(self, driver, file_name): if not os.path.exists(./image): os.makedirs(./image) now time.strftime(%Y%m%d-%H%M%S, time.localtime(time.time())) driver.get_screenshot_as_file(./image/ now - file_name) time.sleep(3) if __name__ __main__: unittest.main()testbaidu2.py # -*- coding: utf-8 -*- from selenium import webdriver import unittest import time from selenium.common.exceptions import NoAlertPresentException from selenium.common.exceptions import NoSuchElementException class Baidu2 (unittest.TestCase) : def setUp(self): self.driver webdriver.Chrome() self.driver.implicitly_wait(30) self.base_url http://www.baidu.com/ self.driver.maximize_window() self.verificationErrors[] self.accept_next_alert True def tearDown(self): self.driver.quit() self.assertEqual([], self.verificationErrors) def test_hao(self): driver self.driver driver.get(self.base_url) driver.find_element_by_link_text(新闻).click() time.sleep(6) self.assertTrue(123 1234, msgnot true) time.sleep(3) def test_baidusearch(self): driver self.driver driver.get(self.base_url) driver.find_element_by_id(kw).clear() driver.find_element_by_id(kw).send_keys(u庆余年) driver.find_element_by_id(su).click() time.sleep(6) def is_element_present(self, how, what): try: self.driver.find_element(byhow, valuewhat) except NoSuchElementException as e: return False return True def is_alert_present(self): try: self.driver.switch_to.alert except NoAlertPresentException as e: return False return True def close_alert_and_get_its_text(self): try: alert self.driver.switch_to.alert alert_text alert.text if self.accept_next_alert: alert.accept() else: alert.dismiss() return alert_text finally: self.accept_next_alert True if __name__ __main__: unittest.main(verbosity2)addTest() TestSuite类的addTest()方法可以把不同的测试类中的测试方法组装到测试套件中但是addTest()一次 只能把一个类里面的一个测试方法组装到测试套件中。方式如下 将testbaidu1.py、testbaidu2.py中的测试方法放到一个测试套件中在testsuite.py中实现。 testsuite.py import unittest from src0716 import testbaidu1 from src0716 import testbaidu2 def createsuite(): #addTest suite unittest.TestSuite() suite.addTest(testbaidu1.Baidu1(test_hao)) suite.addTest(testbaidu1.Baidu1(test_hbaidu)) suite.addTest(testbaidu2.Baidu2(test_hao)) suite.addTest(testbaidu2.Baidu2(test_baidusearch)) return suite if __name____main__: suite createsuite() runner unittest.TextTestRunner(verbosity2) runner.run(suite)但是上述做法有两个不方便的地方阻碍脚本的快速执行必须每次修改testsuite.py 1需要导入所有的相关的py文件比如 import testbaidu1每新增一个脚本就需要导入一个 2addTest一次只能增加一个测试方法如果一个py文件中有10个测试方式如果都要组装到测试套 件中就需要增加10次 makeSuite和TestLoader()的应用 在unittest 框架中提供了makeSuite() 的方法makeSuite可以实现把测试用例类内所有的测试case组 成的测试套件TestSuite unittest 调用makeSuite的时候只需要把测试类名称传入即可。 TestLoader 用于创建类和模块的测试套件一般的情况下使TestLoader().loadTestsFromTestCase(TestClass) 来加载测试类。 runall.py # -*- coding: utf-8 -*- import unittest,csv import os,sys import time import testbaidu1 import testbaidu2 #手工添加案例到套件 def createsuite(): suite unittest.TestSuite() #将测试用例加入到测试容器套件中 suite.addTest(unittest.makeSuite(testbaidu1.Baidu1)) suite.addTest(unittest.makeSuite(testbaidu2.Baidu2)) return suitesuite1 unittest.TestLoader().loadTestsFromTestCase(testbaidu1.Baidu1) suite2 unittest.TestLoader().loadTestsFromTestCase(testbaidu2.Baidu2) suite unittest.TestSuite([suite1, suite2]) return suiteif __name____main__: suitecreatesuite() runner unittest.TextTestRunner(verbosity2) runner.run(suite)经过makeSuite和TestLoader的引入我们不用一个py文件测试类只需要导入一次即可。 那么能不能测试类也不用每次添加指定呢 discover的应用 discover 是通过递归的方式到其子目录中从指定的目录开始 找到所有测试模块并返回一个包含它们 对象的TestSuite 然后进行加载与模式匹配唯一的测试文件discover 参数分别为 discover(dir,pattern,top_level_dirNone) runall.py—注意路径 # -*- coding: utf-8 -*- import unittest,csv import os,sys import time #手工添加案例到套件 def createsuite(): discoverunittest.defaultTestLoader.discover(../test,patterntest*.py,top_le vel_dirNone) print discover return discover if __name____main__: suitecreatesuite() runner unittest.TextTestRunner(verbosity2) runner.run(suite)2.2用例的执行顺序 unittest 框架默认加载测试用例的顺序是根据ASCII 码的顺序数字与字母的顺序为 09,AZ,a~z 。 所以 TestAdd 类会优先于TestBdd 类被发现 test_aaa() 方法会优先于test_ccc() 被执行。对于测试 目录与测试文件来说 unittest 框架同样是按照这个规则来加载测试用例。 addTest方法按照增加顺序来执行。 2.3忽略用例执行 unittest.skip(uThe function was canceled, neglects to perform thecase)# -*- coding: utf-8 -*- from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import Select from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import NoAlertPresentException import unittest, time, re class Baidu1(unittest.TestCase): #test fixture初始化环境 def setUp(self): self.driver webdriver.Firefox() self.driver.implicitly_wait(30) self.base_url http://www.baidu.com/ self.verificationErrors [] self.accept_next_alert True unittest.skip(skipping) def test_baidusearch(self): driver self.driver driver.get(self.base_url /) driver.find_element_by_id(kw).click() driver.find_element_by_id(kw).clear() driver.find_element_by_id(kw).send_keys(u测试) driver.find_element_by_id(su).click() driver.find_element_by_id(su).click() def test_hao(self): driver self.driver driver.get(self.base_url /) driver.find_element_by_link_text(hao123).click() self.assertEqual(uhao123_上网从这里开始, driver.title) #判断element是否存在可删除 def is_element_present(self, how, what): try: self.driver.find_element(byhow, valuewhat) except NoSuchElementException as e: return False return True #判断alert是否存在可删除 def is_alert_present(self): try: self.driver.switch_to_alert() except NoAlertPresentException as e: return False return True #关闭alert可删除 def close_alert_and_get_its_text(self): try: alert self.driver.switch_to_alert() alert_text alert.text if self.accept_next_alert: alert.accept() else: alert.dismiss() return alert_text finally: self.accept_next_alert True #test fixture清除环境 def tearDown(self): self.driver.quit() self.assertEqual([], self.verificationErrors) if __name__ __main__: #执行用例 unittest.main()3.unittest断言 自动化的测试中 对于每个单独的case来说一个case的执行结果中 必然会有期望结果与实际结 果 来判断该case是通过还是失败 在unittest 的库中提供了大量的实用方法来检查预期值与实际 值 来验证case的结果 一般来说 检查条件大体分为等价性 逻辑比较以及其他 如果给定的断 言通过 测试会继续执行到下一行的代码 如果断言失败 对应的case测试会立即停止或者生成错误 信息( 一般打印错误信息即可) 但是不要影响其他的case执行。 unittest 的单元测试库提供了标准的xUnit 断言方法。下面是一些常用的断言 举例 self.assertEqual(“admin”, driver.find_element_by_link_text(“admin”).text) 4.HTML报告生成 脚本执行完毕之后还需要看到HTML报告下面我们就通过HTMLTestRunner.py 来生成测试报告。 HTMLTestRunner支持python2.7。python3可以参见http://blog.51cto.com/hzqldjb/1590802来进行 修改。 HTMLTestRunner.py 文件下载地址 http://tungwaiyip.info/software/HTMLTestRunner.html 下载后将其放在testcase目录中去或者放入…\Python27\Lib 目录下windows。 修改runall.py # -*- coding: utf-8 -*- import unittest,csv import os,sys import time import HTMLTestRunner #手工添加案例到套件 def createsuite(): discoverunittest.defaultTestLoader.discover(../test,patterntest*.py,top_le vel_dirNone) print discover return discover if __name____main__: curpathsys.path[0] #取当前时间 nowtime.strftime(%Y-%m-%d-%H %M %S,time.localtime(time.time())) if not os.path.exists(curpath/resultreport): os.makedirs(curpath/resultreport) filenamecurpath/resultreport/nowresultreport.html with open(filename,wb) as fp: #出html报告 runnerHTMLTestRunner.HTMLTestRunner(streamfp,titleu测试报 告,descriptionu用例执行情况,verbosity2) suitecreatesuite() runner.run(suite)5.异常捕捉与错误截图 用例不可能每一次运行都成功肯定运行时候有不成功的时候。如果可以捕捉到错误并且把错误截图 保存这将是一个非常棒的功能也会给我们错误定位带来方便。 例如编写一个函数关键语句为driver.get_screenshot_as_file def savescreenshot(self,driver,file_name): if not os.path.exists(./image): os.makedirs(./image) nowtime.strftime(%Y%m%d-%H%M%S,time.localtime(time.time())) #截图保存 driver.get_screenshot_as_file(./image/now-file_name) time.sleep(1)一个引用的例子 testscreenshot.py # -*- coding: utf-8 -*- from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import Select from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import NoAlertPresentException import unittest, time, re import os class Baidu1(unittest.TestCase): #test fixture初始化环境 def setUp(self): self.driver webdriver.Firefox() self.driver.implicitly_wait(30) self.base_url http://www.baidu.com/ self.verificationErrors [] self.accept_next_alert True #测试用例必须以test开头 def test_hao(self): driver self.driver driver.get(self.base_url /) driver.find_element_by_link_text(hao123).click() time.sleep(2) try: self.assertEqual(uhao_上网从这里开始, driver.title) except: self.savescreenshot(driver,hao.png) #判断element是否存在可删除 def is_element_present(self, how, what): try: self.driver.find_element(byhow, valuewhat) except NoSuchElementException as e: return False return True #判断alert是否存在可删除 def is_alert_present(self): try: self.driver.switch_to_alert() except NoAlertPresentException as e: return False return True #关闭alert可删除 def close_alert_and_get_its_text(self): try: alert self.driver.switch_to_alert() alert_text alert.text if self.accept_next_alert: alert.accept() else: alert.dismiss() return alert_text finally: self.accept_next_alert True #test fixture清除环境 def tearDown(self): self.driver.quit() self.assertEqual([], self.verificationErrors) def savescreenshot(self,driver,file_name): if not os.path.exists(./image): os.makedirs(./image) nowtime.strftime(%Y%m%d-%H%M%S,time.localtime(time.time())) #截图保存 driver.get_screenshot_as_file(./image/now-file_name) time.sleep(1) if __name__ __main__: #执行用例 unittest.main()可以增加verbosity参数例如unittest.main(verbosity2) 在主函数中直接调用main() 在main中加入verbosity2 这样测试的结果就会显示的更加详细。 这里的verbosity 是一个选项, 表示测试结果的信息复杂度有三个值: 0 ( 静默模式): 你只能获得总的测试用例数和总的结果比如总共100个失败,20 成功80 1 ( 默认模式): 非常类似静默模式只是在每个成功的用例前面有个“ . ” 每个失败的用例前面有个“F” 2 ( 详细模式): 测试结果会显示每个测试用例的所有相关的信息6.数据驱动 之前我们的case都是数据和代码在一起编写。考虑如下场景 需要多次执行一个案例比如baidu搜索分别输入中文、英文、数字等进行搜索这时候需要编写3个 案例吗有没有版本一次运行 python 的unittest 没有自带数据驱动功能。所以如果使用unittest同时又想使用数据驱动那么就可 以使用DDT来完成。 ddt的安装 http://ddt.readthedocs.io/en/latest/ https://github.com/txels/ddt pip install ddt python setup.py installddt使用方法 参考文档http://ddt.readthedocs.io/en/latest/ dd.ddt 装饰类也就是继承自TestCase的类。 ddt.data 装饰测试方法。参数是一系列的值。 ddt.file_data 装饰测试方法。参数是文件名。文件可以是json 或者 yaml类型。 注意如果文件以”.yml”或者”.yaml”结尾ddt会作为yaml类型处理其他所有文件都会作为json文件 处理。 如果文件中是列表每个列表的值会作为测试用例参数同时作为测试用例方法名后缀显示。 如果文件中是字典字典的key会作为测试用例方法的后缀显示字典的值会作为测试用例参数。 ddt.unpack 传递的是复杂的数据结构时使用。比如使用元组或者列表添加unpack之后ddt会自动把元组或者列 表对应到多个参数上。字典也可以这样处理。 下面看一个样例 test_data_list.json [ Hello, Goodbye ]Testddt.py 目录下建data文件夹并建一个test_baidu_data.csv文件用execl最好用TXT文件另 存为csv #-*- coding: utf-8 -*- from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.ui import Select from selenium.common.exceptions import NoSuchElementException from selenium.common.exceptions import NoAlertPresentException import unittest, time, re import os,sys,csv from ddt import ddt, data, unpack ,file_data def getCsv(file_name): rows[] pathsys.path[0].replace(\test,) print path with open(path/data/file_name,rb) as f: readerscsv.reader(f,delimiter,,quotechar|) next(readers,None) for row in readers: temprows[] for i in row: temprows.append(i.decode(gbk)) rows.append(temprows) return rows #引入ddt ddt class Testddt(unittest.TestCase): def setUp(self): self.driver webdriver.Firefox() self.driver.implicitly_wait(30) self.base_url http://www.baidu.com self.verificationErrors [] self.accept_next_alert True #测试用例必须以test开头 #增加ddt数据 #data(selenium,u测试中文,9999999999) #data(2,3,4) #单变更时不使用unpack #data([3, 2], [4, 3], [5, 3]) data(*getCsv(test_baidu_data.csv)) #使用file_data需要在cmd窗口下运行否则找不到文件 #file_data(test_data_list.json) unpack def test_hao(self,value,expected_value): #def test_hao(self,value): driver self.driver driver.get(self.base_url /) driver.find_element_by_id(kw).clear() driver.find_element_by_id(kw).send_keys(value) driver.find_element_by_id(su).click() time.sleep(2) self.assertEqual(expected_value, driver.title) print expected_value print driver.title #判断element是否存在可删除 def is_element_present(self, how, what): try: self.driver.find_element(byhow, valuewhat) except NoSuchElementException as e: return False return True #判断alert是否存在可删除 def is_alert_present(self): try: self.driver.switch_to_alert() except NoAlertPresentException as e: return False return True #关闭alert可删除 def close_alert_and_get_its_text(self): try: alert self.driver.switch_to_alert() alert_text alert.text if self.accept_next_alert: alert.accept() else: alert.dismiss() return alert_text finally: self.accept_next_alert True #test fixture清除环境 def tearDown(self): self.driver.quit() self.assertEqual([], self.verificationErrors) def savescreenshot(self,driver,file_name): if not os.path.exists(./image): os.makedirs(./image) nowtime.strftime(%Y%m%d-%H%M%S,time.localtime(time.time())) #截图保存 driver.get_screenshot_as_file(./image/now-file_name) time.sleep(1) if __name__ __main__: #执行用例 unittest.main()可以增加verbosity参数例如unittest.main(verbosity2) 在主函数中直接调用main() 在main中加入verbosity2 这样测试的结果就会显示的更加详细。 这里的verbosity 是一个选项, 表示测试结果的信息复杂度有三个值: 0 ( 静默模式): 你只能获得总的测试用例数和总的结果比如总共100个失败,20 成功80 1 ( 默认模式): 非常类似静默模式只是在每个成功的用例前面有个“ . ” 每个失败的用例前面有个“F” 2 ( 详细模式): 测试结果会显示每个测试用例的所有相关的信息elf.driver.quit() self.assertEqual([], self.verificationErrors) def savescreenshot(self,driver,file_name): if not os.path.exists(‘./image’): os.makedirs(‘./image’) nowtime.strftime(“%Y%m%d-%H%M%S”,time.localtime(time.time())) #截图保存 driver.get_screenshot_as_file(‘./image/’now‘-’file_name) time.sleep(1) if name “main”: #执行用例 unittest.main() ‘’’ 可以增加verbosity参数例如unittest.main(verbosity2) 在主函数中直接调用main() 在main中加入verbosity2 这样测试的结果就会显示的更加详细。 这里的verbosity 是一个选项, 表示测试结果的信息复杂度有三个值: 0 ( 静默模式): 你只能获得总的测试用例数和总的结果比如总共100个失败,20 成功80 1 ( 默认模式): 非常类似静默模式只是在每个成功的用例前面有个“ . ” 每个失败的用例前面有个“F” 2 ( 详细模式): 测试结果会显示每个测试用例的所有相关的信息 ‘’’ *感谢各位读者的阅读本文章有任何错误都可以在评论区发表你们的意见我会对文章进行改正的。如果本文章对你有帮助请动一动你们敏捷的小手点一点赞你的每一次鼓励都是作者创作的动力哦*
http://www.zqtcl.cn/news/280244/

相关文章:

  • 网站入口设计规范专门做喷涂设备的网站
  • 最简单网站开发软件有哪些企业管理培训课程培训机构
  • 桂城网站制作公司wordpress 导航网站
  • 一个公司做网站需要注意什么条件网站备案 登陆
  • 百度网站介绍显示图片装修公司一般多少钱一平方
  • 网站销售如何做业绩我找伟宏篷布我做的事ko家的网站
  • 建立网站有哪些步骤?jsp网站开发详细教程
  • 网站怎么做直播功能旅游做攻略用什么网站
  • 企业外贸营销型网站如何写好软文推广
  • 免费建站的网址个人网站建设程序设计
  • 淘宝网站建设违规吗上海大公司
  • 大淘客怎么自己做网站自己开网站能赚钱吗
  • 大型门户网站开发北京网站建设管庄
  • 大连建设工程网站网站建设组织管理怎么写
  • wordpress英文站注册域名需要注意什么
  • 营销型网站的建设重点是什么深圳logo设计公司排名
  • 做网站的用什么软件呢网站排名优化服务公司
  • 网站开发完整视频网站集约化建设较好的城市
  • 网站建设和平面设计应用网站如何做
  • 自己做网站需要多少费用asa8.4 做网站映射
  • 商业网站 模板黑龙江省建设厅安全员考试
  • 网站新备案不能访问室内装修网站模板
  • 工程师报考网站wordpress设置视频图片不显示图片
  • 徐州网站建设公司排名成都住建平台
  • 用来备案企业网站国外免费外贸网站
  • 网页背景做的比较好的网站做一个企业网站价格
  • 免费制图网站县级门户网站建设的报告
  • 北京网站建设网怎么用手机做一个网站
  • 网站建设管理办法关于公司门户网站建设的议案
  • 网站开发入职转正申请书体验好的网站