SCMLife.com

 找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 4186|回复: 1

[推荐] IBM Rational Quality Manager 与 Selenium 的集成应用

[复制链接]
发表于 2012-12-2 14:45:04 | 显示全部楼层 |阅读模式
本帖最后由 技术狂人 于 2012-12-2 14:48 编辑
! g( H2 G0 c, g/ G/ ~, d8 ~. \9 d! _- l& {+ L/ h6 V
一、RQM 及其如何管理自动化测试脚本的简介
IBM Rational Quality Manager(RQM)是一款基于 Web 的出色的质量管理软件,用于贯穿软件生命周期的综合测试规划和测试资源管理。它提供了多种适配器与其他工具集成,使 RQM 能够管理并运行由其他工具创建的自动化测试脚本。# c7 R; V& M4 F0 [7 ^( ]: w
Selenium 是一款基于 Web 应用的开源测试工具,它能够支持多种浏览器和多种编程语言,同时它提供了快速、轻量级的浏览器模拟器,为用户提供了最优秀框架的最佳途径。它的诸多优势,令 Selenium 成为当下非常流行的 Web 应用程序的自动化测试工具。
/ ]% S0 t; j" [7 ^RQM4.0 版本中,提供了 JUnit Selenium Adapter 来实施与 Selenium 的集成,使 RQM 可以运行 Selenium 2.0 WebDriver JUnit4 的测试件。+ ^4 K7 n; w9 M& ?
当 JUnit Selenium Adapter 运行时,该 Adapter 会对 RQM 服务器进行轮询,以获取运行 Selenium 测试的请求。请求中包括要运行的 Java 类(例如,JUnit 测试套件或测试用例)、必需的任何其他类路径值以及要为用于运行测试的 Java 虚拟机 (JVM) 设置的任何 Java 系统属性(可选)。运行测试后,Adapter 会将执行结果以及关联的附件上传到服务器。
% K7 p+ g1 S6 P- A  e& V+ R8 I
& i# c7 B7 S2 n

( n# {* Z: ~+ W9 t
二、如何配置 JUnit Selenium Adapter
在配置和使用 JUnit Selenium Adapter 之前,用于运行 JUnit Selenium Adapter 的计算机上必须有 Java 运行时环境 (JRE) 。/ l' U# `8 Y6 B
  • 在运行 JUnit Selenium Adapter 的计算机上,需要下载最新版本的 Selenium 客户机 Java 驱动程序,并解压到某个本地目录中。
  • 当安装 RQM 时,运行此 Adapter 所需要的组件即被放置在 RQM 安装目录中的归档文件中 (QM_install_dir/JazzTeamServer/server/conf/qm/adapters/RQMJUnitSeleniumAdapter.zip)。将此文件复制到运行 JUnit Selenium Adapter 的机器,并将此文件解压缩到本地目录。
  • 进入步骤 2 解压的文件目录,打开 <...>/RQM-Extras-JUnitSeleniumAdapter/selenium.properties 文件,将从 Selenium 客户机驱动程序下载的所有 .jar 文件添加到 com.ibm.rqm.selenium.seleniumClasspath 属性的值中。路径条目至少要包含运行 Selenium V2.0 WebDriver JUnit4 测试套件或测试用例所必需的类。使用者还可以指定其他共享库的类的路径条目来引用。例如,如果您使用的是 Selenium V 2.21.0 和 JUnit4.10,那么 com.ibm.rqm.selenium.seleniumClasspath 属性类似于以下示例:
    1 a3 `1 Z, e) x, K2 w
    com.ibm.rqm.selenium.seleniumClasspath=D:/libs/selenium-2.21.0/selenium-java-2.21.0.jar;
    # K* b+ R. g0 F- Y% _D:/libs/selenium-2.21.0/selenium-server-standalone-2.21.0.jar; , `8 c- k! j6 z/ u( v9 l# X8 V
    D:/libs/selenium-2.21.0/libs/apache-mime4j-0.6.jar;
    ) P2 b1 G' y- \% CD:/libs/selenium-2.21.0/libs/bsh-1.3.0.jar;
    " Z' a! M0 ^. Z- k& m* n/ ID:/libs/selenium-2.21.0/libs/cglib-nodep-2.1_3.jar; 5 g* u& ?% R7 Z6 F! o8 M
    D:/libs/selenium-2.21.0/libs/commons-codec-1.6.jar;
    5 ]" F2 ~' e' ND:/libs/selenium-2.21.0/libs/commons-collections-3.2.1.jar;
    % w3 K& t2 I) H7 v4 @D:/libs/selenium-2.21.0/libs/commons-exec-1.1.jar;
    $ q$ y  _8 i, n3 r# jD:/libs/selenium-2.21.0/libs/commons-io-2.0.1.jar;
    1 x- ?* B# {- M, {D:/libs/selenium-2.21.0/libs/commons-jxpath-1.3.jar;
    5 Z0 @% ~' z  y! b9 N0 M1 L7 jD:/libs/selenium-2.21.0/libs/commons-lang-2.6.jar;
    - {3 r$ E8 F- v' MD:/libs/selenium-2.21.0/libs/commons-logging-1.1.1.jar;
    & Z3 a, c4 o$ X7 }D:/libs/selenium-2.21.0/libs/cssparser-0.9.5.jar;
    : `, T4 T+ n5 C$ D- t8 hD:/libs/selenium-2.21.0/libs/guava-11.0.1.jar;
    3 n6 i  ]( _1 K: S3 Z8 v9 q0 vD:/libs/selenium-2.21.0/libs/hamcrest-core-1.1.jar; + g0 ^- a; a2 e3 M
    D:/libs/selenium-2.21.0/libs/hamcrest-library-1.1.jar;
    : I! [. @4 C  o/ z/ @2 J, C' |D:/libs/selenium-2.21.0/libs/htmlunit-2.9.jar; : X# R0 U0 |& C0 Z( o4 S' B9 s2 Z
    D:/libs/selenium-2.21.0/libs/htmlunit-core-js-2.9.jar;
    1 t0 C1 R% T, {* K& ~D:/libs/selenium-2.21.0/libs/httpclient-4.1.3.jar;
    & n: P; k" m4 W( _6 k$ Q. P- PD:/libs/selenium-2.21.0/libs/httpcore-4.1.3.jar; 7 d4 Q9 X6 x% Z9 v' F" T
    D:/libs/selenium-2.21.0/libs/httpmime-4.1.3.jar;
    , f- `( {5 U3 T: R9 vD:/libs/selenium-2.21.0/libs/ini4j-0.5.2.jar;
    ! x0 [5 Y$ G' a- d+ _! o* ND:/libs/selenium-2.21.0/libs/jcommander-1.13.jar;
    & e+ p. [5 C. C$ Q7 zD:/libs/selenium-2.21.0/libs/jna-3.4.0.jar;
    8 ^9 B! k* w( x8 y' S% z' v+ |D:/libs/selenium-2.21.0/libs/jna-platform-3.4.0.jar; ! U8 {- |( A! x8 o% J- W& |2 ^
    D:/libs/selenium-2.21.0/libs/json-20080701.jar; ; F5 m- o( @$ _& n- T3 z6 l5 Q
    D:/libs/selenium-2.21.0/libs/junit-dep-4.10.jar; " n0 X2 c9 N) O; d- x# t. g
    D:/libs/selenium-2.21.0/libs/nekohtml-1.9.15.jar;
    : P4 M# `0 y( Z% X% J( AD:/libs/selenium-2.21.0/libs/operadriver-v0.11.jar;
    ' N$ r: O2 x' WD:/libs/selenium-2.21.0/libs/protobuf-java-2.4.1.jar;
    ! c" K; w! J- N. u  ?, q' k2 ]; Y% YD:/libs/selenium-2.21.0/libs/sac-1.3.jar; 9 @2 |+ F$ Z. C% G$ ]; ]
    D:/libs/selenium-2.21.0/libs/serializer-2.7.1.jar;
    8 b( f" C8 N' ]D:/libs/selenium-2.21.0/libs/testng-6.0.1-nobsh-noguice.jar; 0 ~# ~" p7 p, D' o0 h/ Y
    D:/libs/selenium-2.21.0/libs/webbit-0.4.6-full.jar;
    6 F, ]! E! V: {% uD:/libs/selenium-2.21.0/libs/xalan-2.7.1.jar;
    " s3 W1 @* o/ Q: O- BD:/libs/selenium-2.21.0/libs/xercesImpl-2.9.1.jar;
    ; w, ^0 ~: r" s! G$ o/ `8 wD:/libs/selenium-2.21.0/libs/xml-apis-1.3.04.jar;
    & H+ Y. P, C/ y1 m# wD:/libs/junit4.10/junit-4.10.jar;
    8 a9 e0 J3 M% P- g; I4 }, R, x


/ V4 u* [9 l% o& M' D& V1 y% O
; ~" |( v: z  ^7 S: i; {/ l
三、如何启动 JUnit Selenium Adapter
为了利用 RQM 管理并运行 Selenium 测试脚本,在配置好 JUnit Selenium Adapter 之后,可以通过命令提示符启动该适配器:; s8 ~6 V0 v, |4 T, O3 K! F
  • 打开命令提示符,进入 JUnit Selenium Adapter 的目录
  • 根据您的操作系统,选择以下任意一种方式:/ q- G) y  R- ~& m
    • Windows:
      ; n/ l  T+ O+ Y
C:start.bat -repository https://qmserver:port/qm -user userid -password password [-adapterName adapter-name] [-projectArea project area] [-sleepTime sleep time] [-configFile configuration file]
4 B7 _  x' @% u/ t$ N- R% E0 P6 @

      D/ j2 G4 |5 N! I0 v) C. G3 |; n; B  N, @
    ! y$ P% k" z9 G
    • Linux:+ P6 u+ ^6 _3 o. K& G8 F
$ start.sh -repository https://qmserver:port/qm -user userid -password password [-adapterName adapter-name] [-projectArea project area] [-sleepTime sleep time] [-configFile configuration file]( |0 h, e7 P9 }$ v0 d
其中:$ h/ o9 P, z" i: Z9 h! i
  • qmserver 是质量管理服务器的主机名或 IP 地址。
  • port 是质量管理服务器运行于的端口。
  • userid 是具有运行适配器的许可证的质量管理的注册用户标识。
  • password 是所提交的用户标识的密码。
  • adapter name 是用户指定的适配器名称。
  • project area 是已登录的项目的名称。
  • sleep time 是两次轮询任务之间的轮询时间间隔。缺省设置是 5 秒钟。
  • configuration file 是用于存储和读取此适配器设置的文件。缺省文件名为 config.ini。
    $ [3 x: x3 j" k! b0 |
当成功启动该适配器时,将看到如下提示:. D# c% U( X4 \& i* n
$ [/ R4 s- \* v$ W3 L5 w
图 1. 启动 JUnit Selenium Adapter
- _, B0 J6 I/ s9 n4 J% o
( o0 W% t2 e: b* l1 D该适配器会生成一个配置文件(config.ini 文件或 -configFile 选项中所指定的文件)以及包含相关的注册信息。当适配器重新启动时,会复用此信息。
* l) C0 \+ X* j6 W因此,若下次要从 config.ini 文件重新启动 JUnit Selenium Adapter,可以不用添加参数直接运行,如 start.bat。
2 A5 ]( G& l8 v. o7 `. G* S8 r

( x9 u5 m  Z$ x& M9 O3 G- K* o
2 O' q7 ^6 y# I5 B3 p6 ]
四、在 RQM 上管理并运行现有的 Selenium V2.0 WebDriver Junit4 测试脚本
- c& q4 O/ e9 R0 {1 Y
Selenium 脚本示例
8 m9 d2 @; t; }  R
public class DemoTestCase {- A' t/ _$ P, l
private WebDriver driver;
- w8 @' W" y: z4 A! B+ v private String baseUrl;* m( [0 ~( ^( y: J, q) L, ~+ \
private StringBuffer verificationErrors = new StringBuffer();5 u9 u% a* z+ k. Y

& L- |/ h  R9 O; ` @Before) E, \4 s  `0 ?3 R2 L. J. S1 D
public void setUp() throws Exception {
& J' C3 }; _) u driver = new FirefoxDriver();
, {$ p% R+ _* V& U+ L baseUrl = "http://www.baidu.com";
; ^. g; X+ b  `/ j- ~ }9 ?( ]8 O& D- v; B$ F- P$ h& U1 N
& \, p9 Z5 t  V, K( k1 z
@After9 [0 N+ d9 q* ~" _. @
public void tearDown() throws Exception {' ?( n8 X' ^- P3 s
driver.quit();$ g, o- n: d, h" F% f& V
String verificationErrorString = verificationErrors.toString();
/ _! b1 d& N1 `: ^0 {% \0 q+ W. b if (!"".equals(verificationErrorString)) {
+ n5 ]" b: w! d6 R  w2 i9 U) R3 M fail(verificationErrorString);9 x* }) z- h' A
}
. E0 `  h+ H& ] }- H: j" D- G5 _: ?$ k$ X

& n8 x; O2 B- S0 k  Z  `" \1 n @Test& I# N, V; a  ?5 D* U3 N  |
public void test() throws Exception {4 _% L, z& q4 o- [% T
driver.get(baseUrl);$ T0 ^6 t5 D# z2 m* d8 L
WebElement element = driver.findElement(By.id("kw"));
9 p! U5 u* Y& @6 ~4 z element.sendKeys("seleniumhq");& l, I3 |% B9 n7 G
element.submit();
* K7 |% x9 |' ~- J System.out.println("Driver:" + driver.getTitle());
$ Y6 e7 I# y4 m }
: y0 _/ W, }0 h}

( N$ a0 u# `) A/ b3 s; n接下来将演示如何在 RQM 中管理并运行现有的 Selenium V2.0 WebDriver Junit4 测试脚本。
: b! ~4 j2 a- Z& G0 _& Z
  • 打开登录 RQM 用户界面,进入 Project Area,通过菜单 Construction >> Create Test Case 创建一个 Demo Test Case.  q0 i. C8 O/ s3 N( X! z0 f! c0 A
# k) }: {0 e1 D( r/ i4 E! h
图 2. 创建 Test Case7 n6 }- h9 `- R
7 Y4 `$ z- T0 y: Y, O9 |9 s: O
  • 通过菜单进入 Construction >> Create Test Script,填写对应的 Selenium 脚本的信息。注意以下关键字段值的填写:9 W+ ?( \# w, z3 Q/ d
    • Type:选择 JUnit Selenium 作为脚本类型。
    • Test Class: 要执行的 JUnit Selenium 类的名称。
    • Classpath: 运行测试类所需要的类路径条目,以分号分隔。
    • Java System Properties: 要传递给 JVM 的 Java 系统属性。1 H/ L# P' ?) s6 e

    8 H5 m7 O0 P% j2 d

$ B3 z' I3 W; Z6 V- j, Z/ h9 `图 3. 创建 Test Script
/ V2 |3 Y$ t3 d 6 O$ Y7 N- Q! P% x, {" Z
  • 将 Test Case 与 Test Script 相关联:8 D1 t) S0 u5 ~( |/ s. K- r2 l
进入步骤 1 创建的 Test Case,加载 Test Script 模块,点击 Add Test Script,选择步骤 2 创建的 Test Script。
7 x! Q6 F- _$ _4 R4 c; g9 D" W点击确认,将选中的 Test Script 加入到当前 Test Case 中,并保存。
* z& L7 Z6 K( g* ^3 T* F# G* M1 C" J* h& O3 a- k4 M! K$ G
图 4. 关联 Test Case 与 Test Script
( Q! g8 l# `0 u
" T0 @# e' o% B  _' ~- J1 u* u! V
  • 创建 Test Case Execution Records (ER):
    " Z& ?0 C1 B; ]0 P
    • 自动生成 ER:若未手动创建 ER,在 run case 之后,RQM 会默认创建相应的 ER。
      * [2 `) R3 J5 ?6 b
    • 手动创建 ER:在 Test Case 页,加载 ER 模块,点击 Generate Test Case Execution Records 图标,输入测试环境的信息即可创建。然后确认运行环境信息,并保存 ER。! @% T9 H8 |0 E4 L5 F

    3 o9 a1 _) P: f1 p; z* d

7 z& U# ~  {. p. y图 5. 手动创建 ER% y: v# w( {- J

1 \, H: X  p# @! b+ t
  • 运行脚本:* e4 j2 C% G! E5 e( ^1 f: }
    • 前置条件:运行的目标计算机上的 Adapter 是启动着的。
    • 方式一:在 ER 模块中,选中相应运行环境的 ER,点击 Run Test。# }1 F. [2 u- C
    7 H& O' X' b* e! g
% W/ ]! a- j" P( i& h
图 6. 选择特定的 ER 记录运行脚本
. v; y9 e' B9 D" Z9 g' W9 ^& C8 N- q  ~ 6 Y$ W4 B- u0 u/ ]$ J0 s

    2 y$ d, e8 Y9 X" N
    7 Z& I- A3 T4 K; @$ j3 k8 A1 f3 b
    $ l2 t) z; G& A5 O
    • 方式二:通过 Test Case 头尾的图标直接调出 Run Test Case 的配置页面。8 N2 s% E  x( r: V" b3 T( `
5 g+ z4 a- K9 M/ f5 Z$ Y9 W
图 7. Run Test Case 的图标所在位置  d! q4 }3 o2 \/ j% [) Y9 O: |* o
# R- Z9 Z$ g6 H" O6 m6 O, e
5 E2 }) y- \  F( D
图 8. Run Test Case 的配置页面
- y" D7 T7 `- h0 i
8 A2 D+ J  |: E
  • 运行过程:5 O( @! J6 E5 X8 P4 ]: ^
' N$ v; {0 _# }
图 9. Test Case 运行时界面
3 C  L# N& O1 h3 x: R) J) b4 s
2 J6 O7 @# O# t, u2 q, d- B! H
1 K2 _( k# T5 I7 |图 10. Test Case 运行结束界面( n; J2 [, i; Z9 G4 e7 L

- s5 m# `0 u+ R8 t7 U8 l4 O6 B
  • 运行后相应的 ER 状态会同步更新。
    : R$ z  x, @) `/ m6 H- H: w/ H
! r! q; S; }. L, x- M" M
图 11. 运行成功的 ER 状态
2 {0 |& s/ ?, Y/ t ' t+ T9 p) r) z! Y" `

9 j* E0 g$ e  P2 Z9 C0 j# r

( y! t8 k! x9 Z) a/ o
五、测试结果和测试报告
运行 Selenium 测试后,RQM 同时提供了相当不错的测试报告。您可以查看执行结果来获取 JUnit 测试的详细信息:( e* ~8 ?+ d+ C2 B" ?4 _4 t/ u2 [( A( P
  • JUnit 测试名称
  • 测试的启动和停止次数
  • 成功 / 失败状态,对于失败的测试,将提供导致失败的异常。
  • 由测试生成的屏幕捕获 ( 可选 )
    4 Q1 ?( T3 J1 o8 W( E
上一章节的示例,运行成功的结果,如图所示:
# m* ~! b, d* `% K  a3 T3 K# o# \4 W: Q6 o, e
图 12. 无屏幕捕获的 Test Case 运行结果报告
/ A* C& _& e+ p+ H" c% t/ O
/ B  {6 h6 t) X1 t3 _由于 Selenium 脚本通常会适当地针对浏览器会话屏幕进行屏幕捕获,以便作为测试结果输出,同时也方便排查错误。因此在通过 RQM JUnit Selenium Adapter 运行 Selenium 脚本时,也考虑到了这一点。只要在代码中做一点简单的改动,便可自动将由 JUnit Selenium 测试创建的屏幕捕获添加至测试用例的执行结果中,以供日后查看。3 q* ?' k: S4 p* t: z* n9 \
在 JUnit Selenium Adapter 执行测试时,它会设置运行 JUnit Selenium 测试的 JVM 中名为"selenium.screenshot.dir"的 Java 系统属性。此 Java 系统属性的值是运行该适配器的机器上的某个目录的完整路径。在每个 JUnit Selenium 测试执行结束时,将搜索由"selenium.screenshot.dir"指定的目录以查找图像文件(.png、.jpg、.jpeg、.gif、.tif 和 .bmp)。如果找到任何图像文件,那么会在 RQM 服务器上创建文件附件,并将对这些文件附件的引用包括在执行结果中。, ]) [9 z$ t7 e6 |: M
修改上一部分中的示例代码:3 C' T$ f3 |0 i: k% o
public class DemoTestCase {8 ]3 I2 h' t" i
        private WebDriver driver;
( K1 ^7 j! f9 R        private String baseUrl;8 R" k% i# r5 z6 c
        private StringBuffer verificationErrors = new StringBuffer();
$ q  ^, r+ f( [% M, k8 {: ]) \: h2 ]; [8 o- J( Z3 H
        @Before       
* n9 c9 n' ]' C# a: I& W" l        public void setUp() throws Exception {! |! w1 ?9 T" h5 U, Y+ T
                driver = new FirefoxDriver();' }" o( l8 F8 M0 w( N3 Q
                baseUrl = "http://www.baidu.com";
/ d; h  y4 c* p        }
  n2 X# J2 W: P3 ^1 U, [; t2 L; L# f* z- k2 w! V% h! E- z7 D
        @After
5 t- }) a  O7 _* i7 q( K1 V        public void tearDown() throws Exception {
  L  N/ c$ M, E! P7 w                driver.quit();
: C7 C+ x# X4 t3 _7 S- h- Z                String verificationErrorString = verificationErrors.toString();
8 u* _6 P% I' U1 s9 T5 {                if (!"".equals(verificationErrorString)) {3 s5 U) B* Z9 o7 E- X6 N, f
                        fail(verificationErrorString);( R. s# [- m/ r' J1 S6 \
                }9 I( N) G1 D* G+ m+ x/ z) P
        }
( ], b0 d$ ?" C! A9 m! I) c. ^5 u: z8 q5 K; H5 z
        @Test' }# Y$ t- @1 y/ S% o; E
        public void test() throws Exception {- F1 S3 `% Q: U' D9 N' ]
                driver.get(baseUrl);
" K6 S" W6 x9 E; `! L                WebElement element = driver.findElement(By.id("kw"));; E" L7 R& v0 F, A! c
                element.sendKeys("seleniumhq");
! Z1 @8 h+ S/ o% d( R/ p+ j                element.submit();1 p+ Z- V+ A; k  Q' o1 q) A
                takeScreenShot("searchresult1.png");8 |: h9 H9 S+ l4 u3 ^& `
                System.out.println("Driver:" + driver.getTitle());                : z* t; s- e- z4 e% Z
        }
- K, U+ w  f- G% v       
) ~+ C3 R) w4 [% r" D" f3 \        private void takeScreenShot(String fname) throws Exception {5 f& m; I/ _) f$ C8 `& }, N8 u3 K2 A
         File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
8 u# p, L& O3 n+ Y! u4 l         String imageFileDir = System.getProperty("selenium.screenshot.dir");
, `% z6 X; z; m         if (imageFileDir == null)
5 w- K2 K* u! x: c7 }2 ^' ~                 imageFileDir = System.getProperty("java.io.tmpdir");
# r1 G  d1 |! A$ d- F) c, C2 ^          FileUtils.copyFile(scrFile, new File(imageFileDir, fname));1 |- q) @5 J" ^
        }
: J& k4 ~$ |5 \8 i# C7 a2 N( I4 i        4 G. M) W3 t0 T% _, z6 T
}

! p$ _. Q/ [4 y修改代码后,重新执行 Test Case,结果如下:* m4 L5 a+ ~, B, c& h
4 [0 K; }2 I' @" [8 e
图 13. 保存了屏幕捕获的 Test Case 运行结果报告
. Z# _: g/ o8 M $ u/ L  ~6 j& q9 ^0 Q+ Z& q

( P( z1 H& g: Q1 ~: D* P9 e

+ i4 E( @7 u4 a- e+ B: q
六、总结
本文通过向读者介绍 JUnit Selenium Adaptor 自动化适配器和 RQM 服务器的连接配置。以及用具体的步骤来演示在 RQM 上执行 Selenium 测试用例,查看执行结果,如何进行调试等场景。让对 RQM 和 Selenium 集成应用有兴趣的读者可以快速入门,并更好的体验这两者集成之后所带来的强大功能。
4 ~) c. C& U) B9 y! p0 o. W) ]6 v8 A0 M0 L% L" u

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
 楼主| 发表于 2012-12-2 14:46:48 | 显示全部楼层
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

关闭

SCMLife推荐上一条 /4 下一条

QQ|小黑屋|手机版|无图版|SCMLife.com ( 京ICP备06056490号-1 )

GMT+8, 2019-11-20 15:40 , Processed in 0.075479 second(s), 10 queries , Gzip On, MemCache On.

Powered by SCMLife X3.4 Licensed

© 2001-2017 JoyShare.

快速回复 返回顶部 返回列表