Python接口自动化测试的实现


Posted in Python onAugust 28, 2020

1)环境准备:

接口测试的方式有很多,比如可以用工具(jmeter,postman)之类,也可以自己写代码进行接口测试,工具的使用相对来说都比较简单,重点是要搞清楚项目接口的协议是什么,然后有针对性的进行选择,甚至当工具不太适合项目时需要自己进行开发。

在我们项目的初期,我们采用的是jmeter进行接口测试,当时觉得这个工具上手简单,团队成员学习成本低,并且接口测试的脚本稍微调整一下还可以用来做性能测试。

不过随着项目规模、团队人数的不断增长,渐渐的这个工具有适应不了当前项目的需求了,为此我们项目也重新开发了相关接口自动化的平台。但是,但是。。。可能是我让大家中毒太深,现在很多同学一提到接口测试关联到jmeter,为此,我深深感到不安。毕竟jmeter只是个工具,换个项目换个协议你是否还能玩转接口测试呢?session和cookie有什么区别?工具又是怎么实现的呢?

比如session如何保存,接口依赖如何处理,case如何管理及执行顺序,测试数据如何管理等等题,这个过程也有助于我们更加深刻的理解接口测试和http协议。

本文主要采用python语言,python中http协议接口相关的库有urllib,urllib2以及reqeusts库,这其中reqeusts库用来起来最方便,因此我也主要采用requests库来做http协议的接口测试。首先来看下需要哪些环境信息:

一、安装python

mac下自带安装了python,这个不多说了。

二、安装虚拟环境:

我们在一台机器上可以安装多个python版本,为了使每个版本的环境相互不受干扰,可以安装虚拟环境,安装方法如下:

1、安装virtualenv:pip install virtualenv

2、新建名为venv的虚拟环境:virtualenv venv

3、进入新环境:source venv/bin/activate

4、退出:deactivate

三、安装requests库

>>>pip install requests

ps:用python做http协议的接口测试会用到这个库。

四、http测试工具:

一个使用 Python + Flask 编写的 HTTP 请求和响应服务,该服务主要用于测试 HTTP 库。后续测试我们都基于这个网站。

http://httpbin.org

五、在本地搭建httpbin:

考虑到测试时要不断访问 httpbin 网站,请求过多担心被拉到黑名单,我们自己在本志搭建一套httpbin服务。

1、安装:pip install gunicorn

2、安装:pip install httpbin

3、启动:gunicorn httpbin:app

至此,环境搭建已经完毕,可以开始玩了~

(2)requests.get()

环境搭建好后,接下来我们先来了解一下requests的一些简单使用,主要包括:

requests常用请求方法使用,包括:get,postrequests库中的Session、Cookie的使用其它高级部分:认证、代理、证书验证、超时配置、错误异常处理等。

本节首先来了解一下requests库中如何发送get请求:

一、看下方法定义:

1、到官方文档去了下requests.get()方法的定义,如下:

Python接口自动化测试的实现

2、点击右上角的【source】,看一下它的源码如下:

Python接口自动化测试的实现

看到最后一行return,get方法最后是通过调用 requests.request方法实现的,其实在其它的请求方法如post,put,head,delete等方法都是调用的request方法,然后把请求方法的类型传递给request方法第一个参数。

3、HTTP协议是一个基于请求/响应模式的、无状态的,应用层协议。既然有请求,就有响应,来看下resquest中常用的响应信息:

Python接口自动化测试的实现

二、get方法简单使用:

1、不带参数的get:

# -*- coding:utf-8 -*-
#不带参数的get

import requests
import json

host = "http://httpbin.org/"
endpoint = "get"

url = ''.join([host,endpoint])
r = requests.get(url)
#response = r.json()

print type(r.text)
print (eval(r.text))

输出:

{
  'origin': '183.14.133.88',
  'headers': {
    'Connection': 'close',
    'Host': 'httpbin.org',
    'Accept-Encoding': 'gzip,
    deflate',
    'Accept': '*/*',
    'User-Agent': 'python-requests/2.18.1'
  },
  'args': {
    
  },
  'url': 'http: //httpbin.org/get'
}

2、 带参数的get:

# -*- coding:utf-8 -*-
#带参数的get

import requests
import json

host = "http://httpbin.org/"
endpoint = "get"

url = ''.join([host,endpoint])
params = {"show_env":"1"}
r = requests.get(url=url,params=params)

print r.url

输出:

http://httpbin.org/get?show_env=1
{
  'origin': '183.14.133.88',
  'headers': {
    'X-Request-Id': 'ebe922b4-c463-4fe9-9faf-49748d682fd7',
    'Accept-Encoding': 'gzip,
    deflate',
    'X-Forwarded-Port': '80',
    'Total-Route-Time': '0',
    'Connection': 'close',
    'Connect-Time': '0',
    'Via': '1.1vegur',
    'X-Forwarded-For': '183.14.133.88',
    'Accept': '*/*',
    'User-Agent': 'python-requests/2.18.1',
    'X-Request-Start': '1504755961007',
    'Host': 'httpbin.org',
    'X-Forwarded-Proto': 'http'
  },
  'args': {
    'show_env': '1'
  },
  'url': 'http: //httpbin.org/get?show_env=1'
}

3、带header的get:

# -*- coding:utf-8 -*-

import requests
import json

host = "http://httpbin.org/"
endpoint = "get"

url = ''.join([host,endpoint])
headers = {"User-Agent":"test request headers"}

r = requests.get(url)
r = requests.get(url,headers=headers)
#response = r.json()
print (eval(r.text))['headers']['User-Agent']

输出:

test request headers

4、同时带参数和header:

# -*- coding:utf-8 -*-
import requests
import json

host = "http://httpbin.org/"
endpoint = "get"

url = ''.join([host,endpoint])
headers = {"User-Agent":"test request headers"}
params = {"show_env":"1"}

r = requests.get(url)
r = requests.get(url,headers=headers,params=params)

#response = r.json()
print (eval(r.text))['headers']['User-Agent']
print r.url

输出:

test request headers
http://httpbin.org/get?show_env=1

(3)requests.post()

一、方法定义

二、post方法简单使用

1、带数据的post

2、带header的post

3、带json的post

4、带参数的post

5、普通文件上传

6、定制化文件上传

7、多文件上传

一、方法定义:

1、到官方文档去了下requests.post()方法的定义,如下:

Python接口自动化测试的实现

2、源码:

Python接口自动化测试的实现

3、常用返回信息:

Python接口自动化测试的实现

二、post方法简单使用:

1、带数据的post:

# -*- coding:utf-8 -*-
import requests
import json

host = "http://httpbin.org/"
endpoint = "post"
url = ''.join([host,endpoint])
data = {'key1':'value1','key2':'value2'}

r = requests.post(url,data=data)
#response = r.json()
print (r.text)

输出:

{
 "args": {}, 
 "data": "", 
 "files": {}, 
 "form": {
  "key1": "value1", 
  "key2": "value2"
 }, 
 "headers": {
  "Accept": "*/*", 
  "Accept-Encoding": "gzip, deflate", 
  "Connection": "close", 
  "Content-Length": "23", 
  "Content-Type": "application/x-www-form-urlencoded", 
  "Host": "httpbin.org", 
  "User-Agent": "python-requests/2.18.1"
 }, 
 "json": null, 
 "origin": "183.14.133.88", 
 "url": "http://httpbin.org/post"
}

2、带header的post:

# -*- coding:utf-8 -*-
import requests
import json

host = "http://httpbin.org/"
endpoint = "post"

url = ''.join([host,endpoint])
headers = {"User-Agent":"test request headers"}

# r = requests.post(url)
r = requests.post(url,headers=headers)
#response = r.json()

输出:

{
 "args": {}, 
 "data": "", 
 "files": {}, 
 "form": {}, 
 "headers": {
  "Accept": "*/*", 
  "Accept-Encoding": "gzip, deflate", 
  "Connection": "close", 
  "Content-Length": "0", 
  "Host": "httpbin.org", 
  "User-Agent": "test request headers"
 }, 
 "json": null, 
 "origin": "183.14.133.88", 
 "url": "http://httpbin.org/post"
}

3、带json的post:

# -*- coding:utf-8 -*-
import requests
import json

host = "http://httpbin.org/"
endpoint = "post"

url = ''.join([host,endpoint])
data = {
  "sites": [
        { "name":"test" , "url":"www.test.com" },
        { "name":"google" , "url":"www.google.com" },
        { "name":"weibo" , "url":"www.weibo.com" }
  ]
}

r = requests.post(url,json=data)
# r = requests.post(url,data=json.dumps(data))
response = r.json()

输出:

{
 "args": {}, 
 "data": "{\"sites\": [{\"url\": \"www.test.com\", \"name\": \"test\"}, {\"url\": \"www.google.com\", \"name\": \"google\"}, {\"url\": \"www.weibo.com\", \"name\": \"weibo\"}]}", 
 "files": {}, 
 "form": {}, 
 "headers": {
  "Accept": "*/*", 
  "Accept-Encoding": "gzip, deflate", 
  "Connection": "close", 
  "Content-Length": "140", 
  "Content-Type": "application/json", 
  "Host": "httpbin.org", 
  "User-Agent": "python-requests/2.18.1"
 }, 
 "json": {
  "sites": [
   {
    "name": "test", 
    "url": "www.test.com"
   }, 
   {
    "name": "google", 
    "url": "www.google.com"
   }, 
   {
    "name": "weibo", 
    "url": "www.weibo.com"
   }
  ]
 }, 
 "origin": "183.14.133.88", 
 "url": "http://httpbin.org/post"
}

4、带参数的post:

# -*- coding:utf-8 -*-
import requests
import json

host = "http://httpbin.org/"
endpoint = "post"

url = ''.join([host,endpoint])
params = {'key1':'params1','key2':'params2'}

# r = requests.post(url)
r = requests.post(url,params=params)
#response = r.json()
print (r.text)

输出:

{
"args": {
"key1": "params1",
"key2": "params2"
},
"data": "",
"files": {},
"form": {},
"headers": {
"Accept": "*/*",
"Accept-Encoding": "gzip, deflate",
"Connection": "close",
"Content-Length": "0",
"Host": "httpbin.org",
"User-Agent": "python-requests/2.18.1"
},
"json": null,
"origin": "183.14.133.88",
"url": "http://httpbin.org/post?key2=params2&key1=params1"
}

5.普通文件上传:

# -*- coding:utf-8 -*-
import requests
import json

host = "http://httpbin.org/"
endpoint = "post"

url = ''.join([host,endpoint])
#普通上传
files = {
      'file':open('test.txt','rb')
    }

r = requests.post(url,files=files)
print (r.text)

输出:

{
 "args": {}, 
 "data": "", 
 "files": {
  "file": "hello world!\n"
 }, 
 "form": {}, 
 "headers": {
  "Accept": "*/*", 
  "Accept-Encoding": "gzip, deflate", 
  "Connection": "close", 
  "Content-Length": "157", 
  "Content-Type": "multipart/form-data; boundary=392865f79bf6431f8a53c9d56c62571e", 
  "Host": "httpbin.org", 
  "User-Agent": "python-requests/2.18.1"
 }, 
 "json": null, 
 "origin": "183.14.133.88", 
 "url": "http://httpbin.org/post"
}

6.定制化文件上传:

# -*- coding:utf-8 -*-
import requests
import json

host = "http://httpbin.org/"
endpoint = "post"

url = ''.join([host,endpoint])
#自定义文件名,文件类型、请求头
files = {
    'file':('test.png',open('test.png','rb'),'image/png')
}

r = requests.post(url,files=files)
print (r.text)heman793

7.多文件上传:

# -*- coding:utf-8 -*-
import requests
import json

host = "http://httpbin.org/"
endpoint = "post"

url = ''.join([host,endpoint])
#多文件上传
files = [
  ('file1',('test.txt',open('test.txt', 'rb'))),
  ('file2', ('test.png', open('test.png', 'rb')))
  ]

r = requests.post(url,files=files)
print (r.text)

8.流式上传:

# -*- coding:utf-8 -*-
import requests
import json

host = "http://httpbin.org/"
endpoint = "post"

url = ''.join([host,endpoint])

#流式上传
with open( 'test.txt' ) as f:
  r = requests.post(url,data = f)

print (r.text)

输出:

{
 "args": {}, 
 "data": "hello world!\n", 
 "files": {}, 
 "form": {}, 
 "headers": {
  "Accept": "*/*", 
  "Accept-Encoding": "gzip, deflate", 
  "Connection": "close", 
  "Content-Length": "13", 
  "Host": "httpbin.org", 
  "User-Agent": "python-requests/2.18.1"
 }, 
 "json": null, 
 "origin": "183.14.133.88", 
 "url": "http://httpbin.org/post"
}

(4)Cookie&Session

掌握了前面几节的的内容,就可以做一些简单的http协议接口的请求发送了,但是这些还不够。HTTP协议是一个无状态的应用层协议,也就是说前后两次请求是没有任何关系的,那如果我们测试的接口之前有相互依赖关系怎么办呢(比如我要在博客园发文章,是需要先登录的),这时我们就要用到cookie和session技术来保持客户端与服务器端连接的状态,这也就是本节要介绍的内容:

一、Cookie:

1、获取cookie:

# -*- coding:utf-8 -*-
#获取cookie
import requests
import json

url = "https://www.baidu.com/"
r = requests.get(url)

#将RequestsCookieJar转换成字典
c = requests.utils.dict_from_cookiejar(r.cookies)

print r.cookies
print c

for a in r.cookies:
  print a.name,a.value

输出:

<RequestsCookieJar[<Cookie BDORZ=27315 for .baidu.com/>]>
{'BDORZ': '27315'}
BDORZ 27315

2、发送Cookie

# -*- coding:utf-8 -*-
#发送cookie到服务器
import requests
import json

host = "http://httpbin.org/"
endpoint = "cookies"

url = ''.join([host,endpoint])
#方法一:简单发送
# cookies = {"aaa":"bbb"}
# r = requests.get(url,cookies=cookies)
# print r.text

#方法二:复杂发送
s = requests.session()
c = requests.cookies.RequestsCookieJar()
c.set('c-name','c-value',path='/xxx/uuu',domain='.test.com')
s.cookies.update(c)

二、Session

1、保持会话同步:

# -*- coding:utf-8 -*-
import requests
import json

host = "http://httpbin.org/"
endpoint = "cookies"

url = ''.join([host,endpoint])
url1 = "http://httpbin.org/cookies/set/sessioncookie/123456789"

r = requests.get(url)
print r.text

print "------"


s = requests.session()  #初始化一个session对象
s.get(url1)        #cookie的信息存在了session中
r = s.get(url)

print r.text

输出:

{
 "cookies": {}
}

------
{
 "cookies": {
  "sessioncookie": "123456789"
 }
}

2、保存绘画信息:

# -*- coding:utf-8 -*-
import requests
import json

host = "http://httpbin.org/"
endpoint = "headers"

url = ''.join([host,endpoint])

header1 = {"testA":"AAA"}
header2 = {"testB":"BBB"}

s = requests.session()  #初始化一个session对象
s.headers.update(header1)  #已经存在于服务中的信息
r = s.get(url,headers=header2) #发送新的信息

print r.text

输出:

{
 "headers": {
  "Accept": "*/*", 
  "Accept-Encoding": "gzip, deflate", 
  "Connection": "close", 
  "Host": "httpbin.org", 
  "Testa": "AAA", 
  "Testb": "BBB", 
  "User-Agent": "python-requests/2.18.1"
 }
}

3.删除已存在的会话信息,保存为None

# -*- coding:utf-8 -*-
import requests
import json

host = "http://httpbin.org/"
endpoint = "headers"

url = ''.join([host,endpoint])

header1 = {"testA":"AAA"}
header2 = {"testB":"BBB"}

s = requests.session()  #初始化一个session对象
s.headers.update(header1)  #已经存在于服务中的信息
r = s.get(url,headers=header2) #发送新的信息

print r.text

print '--------'

s.headers['testA'] = None  #删除会话里的信息testA
r1 = s.get(url,headers = header2)
print r1.text
{
 "headers": {
  "Accept": "*/*", 
  "Accept-Encoding": "gzip, deflate", 
  "Connection": "close", 
  "Host": "httpbin.org", 
  "Testa": "AAA", 
  "Testb": "BBB", 
  "User-Agent": "python-requests/2.18.1"
 }
}

--------
{
 "headers": {
  "Accept": "*/*", 
  "Accept-Encoding": "gzip, deflate", 
  "Connection": "close", 
  "Host": "httpbin.org", 
  "Testb": "BBB", 
  "User-Agent": "python-requests/2.18.1"
 }
}

4、提供默认数据:

s = requests.Session()
s.auth = ('user', 'pass')
s.headers.update({'x-test': 'true'})

# both 'x-test' and 'x-test2' are sent
s.get('http://httpbin.org/headers', headers={'x-test2': 'true'})

参考:

http://docs.python-requests.org/en/master/user/quickstart/#cookies
http://docs.python-requests.org/en/master/user/advanced/#session-objects

(5)其他(认证&代理&超时设置)

一、认证

1、基本认证:

# -*- coding:utf-8 -*-
import requests

url = "http://httpbin.org/basic-auth/user/passwd"

r1 = requests.get(url)
print "未提供用户名密码:" + str(r1.status_code)

#Basic Authentication
r2 = requests.get(url,auth=('user','passwd'))
print "已提供用户名密码:" + str(r2.status_code)

输出:

未提供用户名密码:401
已提供用户名密码:200

2、数字认证:

>>> from requests.auth import HTTPDigestAuth
>>> url = 'http://httpbin.org/digest-auth/auth/user/pass'
>>> requests.get(url, auth=HTTPDigestAuth('user', 'pass'))
<Response [200]>

3、OAuth认证:

参考:http://docs.python-requests.org/en/master/user/authentication/

二、代理

1、方法一:proxy参数:

import requests

proxies = {
 "https": "http://41.118.132.69:4433"
}
r = requests.post("http://httpbin.org/post", proxies=proxies)
print r.text

2、方法二:设置环境变量:

$ export HTTP_PROXY="http://10.10.1.10:3128"
$ export HTTPS_PROXY="http://10.10.1.10:1080"

$ python
>>> import requests
>>> requests.get('http://example.org')

3、HTTP Basic Auth使用代理方法:http://user:password@host/

proxies = {'http': 'http://user:pass@10.10.1.10:3128/'}

三、证书验证

1、SSL证书(HTTPS):

import requests

#跳过12306 的证书验证,把 verify 设置为 False: 
r = requests.get('https://kyfw.12306.cn/otn/', verify=False)
print r.text

2、客户端证书:

>>> requests.get('https://kennethreitz.org', cert=('/path/client.cert', '/path/client.key'))
<Response [200]>

or

s = requests.Session()
s.cert = '/path/client.cert'

四、超时配置

1 、利用timeout参数来配置最大请求时间:

r = requests.get('https://github.com', timeout=5)

2、设置timeout=None,告诉请求永远等待响应,而不将请求作为超时值传递

r = requests.get('https://github.com', timeout=None)

五、错误异常

1、所有Requests显式抛出的异常都继承自:requests.exctptions.RequestException

2、遇到网络问题(如:DNS查询失败,拒绝连接等)时,requests会抛出一个ConnectionError异常

3、遇到罕见的无效HTTP响应时,Request则会抛出一个HTTPError异常

4、若请求超时,则抛出一个Timeout异常

5、若请求超过了最大的重写向次数,则会抛出一个TooManyRedirects异常

(6)unittest-单个用例管理:

上面主要介绍了环境搭建和requests库的使用,可以使用这些进行接口请求的发送。但是如何管理接口案例?返回结果如何自动校验?这些内容光靠上面五节是不行的,因此从本节开始我们引入python单元测试框架 unittest,用它来处理批量用例管理,校验返回结果,初始化工作以及测试完成后的环境复原工作等等。

一、单个用例管理起来比较简单,参考如下图,单个用例一般多用在调试的时候:

Python接口自动化测试的实现

二、代码如下:

# -*- coding:utf-8 -*-
# 单个用例执行
# 1、导入模块
import unittest

# 2、继承自unittest.TestCase类
class TestOne(unittest.TestCase):
  # 3、配置环境:进行测试前的初始化工作
  def setUp(self):
    print '\ncases before'
    pass

  # 4、定义测试用例,名字以“test”开头
  def test_add(self):
    '''test add method'''
    print 'add...'
    a = 3 + 4
    b = 7
    # 5、定义assert断言,判断测试结果
    self.assertEqual(a, b)

  def test_sub(self):
    '''test sub method'''
    print 'sub...'
    a = 10 - 5
    b = 4
    self.assertEqual(a, b)

  # 6、清理环境
  def tearDown(self):
    print 'case after'
    pass

# 7、该方法会搜索该模块下所有以test开头的测试用例方法,并自动执行它们
if __name__ == '__main__':
  unittest.main()

输出:

Ran 2 tests in 0.001s
OK

cases before
add...
case after

cases before
sub...
case after

Process finished with exit code 0

(8)unittest-生成测试报告:

用例的管理问题解决了后,接下来要考虑的就是报告我问题了,这里生成测试报告主要用到HTMLTestRunner.py 这个模块,下面简单介绍一下如何使用:

一、下载HTMLTestRunner下载:

这个模块不能通过pip安装,只能下载安装,下载地址如下:

python2.x版本:http://tungwaiyip.info/software/HTMLTestRunner.html

python3.x版本:http://hzqldjb.blog.51cto.com/9587820/1590802

二、mac下配置

1、终端进入python环境

2、输入:

import sys
print sys.path

3、找到site-packages文件夹的路径并将下载的HTMLTestRunner.py文件拷贝到此的文件夹下

4、在python环境下,输入 import HTMLTestRunner 不报错即安装成功

三、使用该模块生成报告:

1、目录结构

  • case包下面有baidu,httpbin两个包
  • 每个包下面分别有两个测试的py文件
  • 每个test_00x.py文件里各有2个test case
  • run_all_case.py文件:用来执行所有的test case且生成测试报告

Python接口自动化测试的实现

2、运行后生成报告如下:

Python接口自动化测试的实现

3、run_all_case.py代码如下:

# -*- coding:utf-8 -*-
import unittest
import os
import time
import HTMLTestRunner

# 用例路径
case_path = os.path.join(os.getcwd())
# 报告存放路径
report_path = os.path.join(os.getcwd(), 'report')
print report_path

def all_case():
  discover = unittest.defaultTestLoader.discover(case_path, pattern="test*.py", top_level_dir=None)

  print discover
  return discover

if __name__ == '__main__':
  # 1、获取当前时间,这样便于下面的使用。
  now = time.strftime("%Y-%m-%d-%H_%M_%S", time.localtime(time.time()))

  # 2、html报告文件路径
  report_abspath = os.path.join(report_path, "result_"+now+".html")

  # 3、打开一个文件,将result写入此file中
  fp = open(report_abspath, "wb")
  runner = HTMLTestRunner.HTMLTestRunner(stream=fp,
                      title=u'接口自动化测试报告,测试结果如下:',
                      description=u'用例执行情况:')
  # 4、调用add_case函数返回值
  runner.run(all_case())
  fp.close()

到此这篇关于Python接口自动化测试的实现的文章就介绍到这了,更多相关Python接口自动化测试内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
简单文件操作python 修改文件指定行的方法
May 15 Python
pycharm 使用心得(五)断点调试
Jun 06 Python
python实现批量下载新浪博客的方法
Jun 15 Python
Python多进程同步简单实现代码
Apr 27 Python
利用Hyperic调用Python实现进程守护
Jan 02 Python
python tensorflow学习之识别单张图片的实现的示例
Feb 09 Python
Python初学者需要注意的事项小结(python2与python3)
Sep 26 Python
Python开发之Nginx+uWSGI+virtualenv多项目部署教程
May 13 Python
Python图像处理库PIL的ImageFilter模块使用介绍
Feb 26 Python
python GUI库图形界面开发之PyQt5输入对话框QInputDialog详细使用方法与实例
Feb 27 Python
Django 如何使用日期时间选择器规范用户的时间输入示例代码详解
May 22 Python
python中的None与NULL用法说明
May 25 Python
解决python和pycharm安装gmpy2 出现ERROR的问题
Aug 28 #Python
Python自动登录QQ的实现示例
Aug 28 #Python
python opencv pytesseract 验证码识别的实现
Aug 28 #Python
简单的命令查看安装的python版本号
Aug 28 #Python
python进行OpenCV实战之画图(直线、矩形、圆形)
Aug 27 #Python
python opencv实现简易画图板
Aug 27 #Python
python实现画图工具
Aug 27 #Python
You might like
我用php+mysql写的留言本
2006/10/09 PHP
php数据库配置文件一般做法分享
2012/07/07 PHP
ThinkPHP的Widget扩展实例
2014/06/19 PHP
php中error与exception的区别及应用
2014/07/28 PHP
php无限分类使用concat如何实现
2015/11/05 PHP
slice函数的用法 之不错的应用
2006/12/29 Javascript
js切换光标示例代码
2013/10/10 Javascript
实现checkbox全选、反选、取消JavaScript小脚本异常
2014/04/10 Javascript
jquery根据属性和index来查找属性值并操作
2014/07/25 Javascript
node.js中的events.emitter.listeners方法使用说明
2014/12/10 Javascript
JavaScript中的null和undefined区别介绍
2015/01/01 Javascript
JavaScript实现获取dom中class的方法
2015/02/09 Javascript
利用css+原生js制作简单的钟表
2020/04/07 Javascript
Node.js学习之地址解析模块URL的使用详解
2017/09/28 Javascript
微信小程序模版渲染详解
2018/01/26 Javascript
javascript实现智能手环时间显示
2020/09/18 Javascript
VUE实现吸底按钮
2021/03/04 Vue.js
[01:38]【DOTA2亚洲邀请赛】Sumail——梦开始的地方
2017/03/03 DOTA
python创建列表并给列表赋初始值的方法
2015/07/28 Python
pandas中去除指定字符的实例
2018/05/18 Python
Python3使用TCP编写一个简易的文件下载器功能
2019/05/08 Python
基于python的列表list和集合set操作
2019/11/24 Python
在 Python 中使用 7zip 备份文件的操作
2020/12/11 Python
HTML5 CSS3打造相册效果附源码下载
2014/06/16 HTML / CSS
美国精油公司:Plant Therapy
2019/05/17 全球购物
会计自我鉴定范文
2013/10/06 职场文书
实习求职信
2013/12/01 职场文书
中学生团员自我评价分享
2013/12/07 职场文书
英语自荐信范文
2013/12/11 职场文书
学校教研活动总结
2014/07/02 职场文书
国际政治学专业推荐信
2014/09/26 职场文书
护士个人年终总结
2015/02/13 职场文书
求职自我评价怎么写
2015/03/09 职场文书
2015银行年终工作总结范文
2015/05/26 职场文书
学习心得体会
2019/06/20 职场文书
「月刊Comic Alive」2022年5月号封面公开
2022/03/21 日漫