JMeter (2) —— JMeter与WebDriver测试用户登陆以CAS SSO为例(101 Tutorial)


主要内容

  • JMeter与WebDriver测试用户登陆以CAS SSO为例

环境与参考

jvm版本: 1.8.0_65

jmeter版本: 2.13

firefox版本: 39.0.3

参考来源:

jmeter官方网站

Leverage your Load Testing using JMeter and Selenium WebDriver

jmeter-plugins.org:FirefoxDriverConfig

jmeter-plugins.org:WebDriverTutorial

jmeter-plugins.org:WebDriverSampler

Using Selenium with JMeter's WebDriver Sampler

准备

请参照JMeter (1) —— JMeter与WebDriver安装与测试(101 Tutorial) 安装好JMeter。

需要注意的是:

  • JMeter的版本
  • jar依赖冲突
  • firefox版本

待测试的CAS环境

架构

配置

请参照以下文章搭建配置好CAS单点登陆的本地环境。

测试

注意:我们这里只是以CAS单点登陆为应用场景进行测试,此测试可以推广到其他的web应用的登陆场景,也可以扩展到更为丰富的流程或场景中。

准备

  1. 新建测试计划(TestPlan)

  2. 为测试计划添加线程组(TheadGroup)

  3. 依次添加

    • jp@gc - Firefox Driver Config (Thread Group -> Config Element)
    • jp@gc - WebDriver Sampler (Thread Group -> Sampler)
    • View Results Tree (Thread Group -> Listender)
    • View Results in Table (Thread Group -> Listender)

测试本地的CAS单点登陆环境

  1. 脚本

     try {
    
         var pkg = JavaImporter(org.openqa.selenium, org.openqa.selenium.support.ui)
    WDS.log.info('WDS Name:' + WDS.name)
    WDS.sampleResult.sampleStart() WDS.browser.navigate().to('https://app2.hoau.com:8423/cas2')
    WDS.log.info('Browser Title:' + WDS.browser.getTitle())
    WDS.log.info('Browser CurrentUrl:' + WDS.browser.getCurrentUrl())
    WDS.log.info('Cookie:' + WDS.browser.manage().getCookies())
    WDS.log.info('Request Header: ' + WDS.sampleResult.getRequestHeaders()) var what = WDS.browser.findElement(pkg.By.id('username'))
    what.sendKeys(['test01'])
    var where = WDS.browser.findElement(pkg.By.id('password'))
    where.sendKeys(['psw01']) // var button = WDS.browser.findElement(pkg.By.cssSelector('.btn-submit'))
    var button = WDS.browser.findElement(pkg.By.xpath("//input[@type='submit']"))
    button.click() var wait = new pkg.WebDriverWait(WDS.browser, 10)
    wait.until(pkg.ExpectedConditions.presenceOfElementLocated(pkg.By.xpath("//a[@title='Click here to log out']")))
    var results = WDS.browser.findElements(pkg.By.xpath("//a[@title='Click here to log out']"))
    WDS.log.info('Result: ' + results) if(results.empty) {
    WDS.sampleResult.successful = false
    WDS.sampleResult.responseMessage = 'There were no results returned'
    } var iter = results.iterator()
    var element = iter.next()
    WDS.log.info('User: ' + element.getText()) if('test01' != element.getText()) {
    WDS.sampleResult.successful = false
    WDS.sampleResult.responseMessage = 'Login Failure'
    } WDS.sampleResult.sampleEnd()
    } catch(ex) {
    WDS.log.error(ex)
    WDS.sampleResult.successful = false
    WDS.sampleResult.responseMessage = 'There were no results returned'
    WDS.sampleResult.sampleEnd()
    }
  2. 运行

    • 查看“View Results in Table”

    • 查看“View Results Tree”

需要注意的是,诸如JMeter + WebDriver Plugin或Selenium Grid + Remote WebDriver抑或Sahi Web UI这些方式的测试,都是试图模拟用户从终端(浏览器)与服务器进行真实交互,以上这些方式长于流程、场景,而非服务端的压力(当然也可用于服务端压力测试之目的,这里强调的只是意图),如果要对服务端进行压力测试,我们可以有其他更为适合的方式。

测试cnblogs登陆

我们同样可以cnblogs为目标系统,尝试用JMeter来测试cnblogs的登陆。

  1. 脚本

     try {
    
         var pkg = JavaImporter(org.openqa.selenium, org.openqa.selenium.support.ui)
    WDS.log.info('WDS Name:' + WDS.name)
    WDS.sampleResult.sampleStart() WDS.browser.navigate().to('http://passport.cnblogs.com/user/signin')
    WDS.log.info('Browser Title:' + WDS.browser.getTitle())
    WDS.log.info('Browser CurrentUrl:' + WDS.browser.getCurrentUrl())
    WDS.log.info('Cookie:' + WDS.browser.manage().getCookies())
    WDS.log.info('Request Header: ' + WDS.sampleResult.getRequestHeaders()) var what = WDS.browser.findElement(pkg.By.id('input1'))
    what.sendKeys(['weizhe_2008'])
    var where = WDS.browser.findElement(pkg.By.id('input2'))
    where.sendKeys(['********'])
    var button = WDS.browser.findElement(pkg.By.id('signin'))
    button.click() var wait = new pkg.WebDriverWait(WDS.browser, 1)
    // a href="http://home.cnblogs.com/u/richaaaard/"
    wait.until(pkg.ExpectedConditions.presenceOfElementLocated(pkg.By.xpath("//a[@href='http://www.cnblogs.com/richaaaard/']")))
    var results = WDS.browser.findElements(pkg.By.xpath("//a[@href='http://www.cnblogs.com/richaaaard/']"))
    WDS.log.info('Result: ' + results) if(results.empty) {
    WDS.sampleResult.successful = false
    WDS.sampleResult.responseMessage = 'There were no results returned'
    } WDS.sampleResult.sampleEnd()
    } catch(ex) {
    WDS.log.error(ex)
    WDS.sampleResult.successful = false
    WDS.sampleResult.responseMessage = 'There were no results returned'
    WDS.sampleResult.sampleEnd()
    }
  2. 运行

  3. 结果

问题

  • 由于此种测试模式下,我们会使用JMeter配置的Firefox Driver Config组件,同时使用WDS(Web Driver Sampler)Script在JMeter UI环境下测试目标应用,当Thread Group 的循环次数(Loop Count)或线程数(Number of Threads (user))的值大于1时,当前线程关联的浏览器代理实例一直处于生命期,而单点登陆会保留用户的登陆信息,无需反复输入用户名密码,浏览器保持了这些信息,因此后面断言会出现错误,脚本无法反复执行从而达到为“验证用户名密码这个流程”进行压力测试的目的。

    经研究,当前版本的JMeter及其使用的Selenium WebDriver Plugin除PhantomJS外,不支持动态修改Session Cookie,而网上多数文章介绍的相关Cookie的API,无法对浏览器Session Cookie进行操作。

      WDS.browser.manage().getCookies()
    WDS.browser.manage().deleteAllCookies()

    我们会使用HTTPs录制的方式来解决压力测试的问题。

扩展

为了解WDS 在JMeterUI下javascript脚本的能力,以及涉及到面问题相关的源码。

  • WDS (JMeterPlugins-WebDriver.jar)

    com.googlecode.jmeter.plugins.webdriver.sampler.WebDriverSampler

    com.googlecode.jmeter.plugins.webdriver.sampler.WebDriverScriptable

      package com.googlecode.jmeter.plugins.webdriver.sampler;
    
      import org.apache.jmeter.samplers.SampleResult;
    import org.apache.log.Logger;
    import org.openqa.selenium.WebDriver; public final class WebDriverScriptable
    {
    private static final String[] EMPTY_ARGS = new String[0];
    private String name;
    private String parameters;
    private Logger log;
    private WebDriver browser;
    private SampleResult sampleResult; public void setName(String name)
    {
    this.name = name;
    } public String getName() {
    return this.name;
    } public void setParameters(String parameters) {
    this.parameters = parameters;
    } public String getParameters() {
    return this.parameters;
    } public String[] getArgs() {
    return this.parameters != null ? this.parameters.trim().replaceAll("\\s+", " ").split(" ") : EMPTY_ARGS;
    } public void setLog(Logger log) {
    this.log = log;
    } public Logger getLog() {
    return this.log;
    } public void setBrowser(WebDriver browser) {
    this.browser = browser;
    } public WebDriver getBrowser() {
    return this.browser;
    } public void setSampleResult(SampleResult sampleResult) {
    this.sampleResult = sampleResult;
    } public SampleResult getSampleResult() {
    return this.sampleResult;
    }
    }
  • WDS.browser (WebDriver - selenium-api-2.47.0.jar)

    org.openqa.selenium.WebDriver

    org.openqa.selenium.Cookie

    package org.openqa.selenium;
    
    import java.net.URL;
    import java.util.List;
    import java.util.Set;
    import java.util.concurrent.TimeUnit;
    import org.openqa.selenium.logging.Logs; public abstract interface WebDriver extends SearchContext
    {
    public abstract void get(String paramString); public abstract String getCurrentUrl(); public abstract String getTitle(); public abstract List<WebElement> findElements(By paramBy); public abstract WebElement findElement(By paramBy); public abstract String getPageSource(); public abstract void close(); public abstract void quit(); public abstract Set<String> getWindowHandles(); public abstract String getWindowHandle(); public abstract TargetLocator switchTo(); public abstract Navigation navigate(); public abstract Options manage(); @Beta
    public static abstract interface Window
    {
    public abstract void setSize(Dimension paramDimension); public abstract void setPosition(Point paramPoint); public abstract Dimension getSize(); public abstract Point getPosition(); public abstract void maximize();
    } public static abstract interface ImeHandler
    {
    public abstract List<String> getAvailableEngines(); public abstract String getActiveEngine(); public abstract boolean isActivated(); public abstract void deactivate(); public abstract void activateEngine(String paramString);
    } public static abstract interface Navigation
    {
    public abstract void back(); public abstract void forward(); public abstract void to(String paramString); public abstract void to(URL paramURL); public abstract void refresh();
    } public static abstract interface TargetLocator
    {
    public abstract WebDriver frame(int paramInt); public abstract WebDriver frame(String paramString); public abstract WebDriver frame(WebElement paramWebElement); public abstract WebDriver parentFrame(); public abstract WebDriver window(String paramString); public abstract WebDriver defaultContent(); public abstract WebElement activeElement(); public abstract Alert alert();
    } public static abstract interface Timeouts
    {
    public abstract Timeouts implicitlyWait(long paramLong, TimeUnit paramTimeUnit); public abstract Timeouts setScriptTimeout(long paramLong, TimeUnit paramTimeUnit); public abstract Timeouts pageLoadTimeout(long paramLong, TimeUnit paramTimeUnit);
    } public static abstract interface Options
    {
    public abstract void addCookie(Cookie paramCookie); public abstract void deleteCookieNamed(String paramString); public abstract void deleteCookie(Cookie paramCookie); public abstract void deleteAllCookies(); public abstract Set<Cookie> getCookies(); public abstract Cookie getCookieNamed(String paramString); public abstract WebDriver.Timeouts timeouts(); public abstract WebDriver.ImeHandler ime(); @Beta
    public abstract WebDriver.Window window(); @Beta
    public abstract Logs logs();
    }
    }

    以上要注意内部静态类 Options里面提供的,对Cookie进行操作的API

结束

JMeter (2) —— JMeter与WebDriver测试用户登陆以CAS SSO为例(101 Tutorial)的更多相关文章

  1. JMeter (3) —— JMeter录制脚本并压力测试用户登陆场景以CAS SSO为例(101 Tutorial)

    JMeter (3) -- JMeter录制脚本并压力测试用户登陆场景以CAS SSO为例(101 Tutorial) 主要内容 JMeter录制脚本并进行压力测试用户登陆场景,并以CAS SSO单点 ...

  2. Sahi (3) —— 压力测试Load Test以CAS SSO登陆场景为例(103 Tutorial)

    Sahi (3) -- 压力测试Load Test以CAS SSO登陆场景为例(103 Tutorial) jvm版本: 1.8.0_65 sahi版本: Sahi Pro 6.1.0 参考来源: S ...

  3. JavaWeb基础之Servlet简单实现用户登陆

    学习javaweb遇到了一些坑,一些问题总结下来,记个笔记. 学习servlet遇到的一些坑: servlet实现用户登陆遇到的坑解决办法: https://www.cnblogs.com/swxj/ ...

  4. JMeter (1) —— JMeter与WebDriver安装与测试(101 Tutorial)

    JMeter (1) -- JMeter与WebDriver安装与测试(101 Tutorial) 主要内容 JMeter安装 WebDriver安装 一个简单的JMeter+WebDriver示例 ...

  5. 使用JMeter进行简单的压力测试

    一.压力测试 顾名思义:压力测试,就是  被测试的系统,在一定的访问压力下,看程序运行是否稳定/服务器运行是否稳定(资源占用情况). 比如: 2000个用户同时到一个购物网站购物,这些用户打开页面的速 ...

  6. JMeter使用jar进行压力测试

    最近需要对改造的redis缓存接口做压力测试,使用了开源压力测试工具JMeter,分享一下自己的使用经验,希望能对需要进行压力测试的开发同学有所帮助. JMeter介绍 JMeter是Apache软件 ...

  7. Windows和Linux的Jmeter分布式集群压力测试

    Windows的Jmeter分布式集群压力测试 原文:https://blog.csdn.net/cyjs1988/article/details/80267475 在使用Jmeter进行性能测试时, ...

  8. Jemter 压测基础(一)——基本概念、JMeter安装使用、分布式测试、导出测试结果、编写测试报告

    Jemter   压测基础(一) 1.压力测试的基本概念: 1.吞吐率(Requestspersecond) 服务器并发处理能力的量化描述,单位是reqs/s,指的是某个并发用户数下单位时间内处理的请 ...

  9. JMeter性能(压力)测试--使用解锁

    1. 首先去官网下载JMeter:  http://jmeter.apache.org/download_jmeter.cgi 2. 解压缩后到目录 \apache-jmeter-5.0\bin 下找 ...

随机推荐

  1. Java 9 揭秘(1. 入门介绍)

    文 by / 林本托 在第一部分中,主要讲解如下内容: JDK 9 包含了哪些内容 运行代码的系统要求 如何安装 NetBeans 1 JDK 介绍 JDK 9是Java开发工具包的第九个主要版本,计 ...

  2. 【转载】Oracle死锁概念,阻塞产生的原因以及解决方案

    参考原文:http://blog.sina.com.cn/s/blog_9d12d07f0102vu72.html 锁是一种机制,一直存在:死锁是一种错误,尽量避免.​ 首先,要理解锁和死锁的概念:​ ...

  3. Android中五种常用的menu

    Android Menu在手机的应用中起着导航的作用,作者总结了5种常用的Menu. 1.左右推出的Menu 前段时间比较流行,我最早是在海豚浏览器中看到的,当时耳目一新.最早使用左右推出菜单的,听说 ...

  4. PHP的生成器、yield和协程

    虽然之前就接触了PHP的yield关键字和与之对应的生成器,但是一直没有场景去使用它,就一直没有对它上心的研究.不过公司的框架是基于php的协程实现,觉得有必要深入的瞅瞅了. 由于之前对于生成器接触不 ...

  5. 【剑道】日常练习相关Q&A 整理

    Q:如何使手腕灵活,手指灵活.有力量? A: 1)提重物.将手腕搁在膝盖上,凭手指和手腕的力量将重物提上来 2)指卧撑.用十个指头着地的方法做俯卧撑 Q:怎样才算肩膀放松,如何方式? A:收放自如,多 ...

  6. SQL Server 2008 附加数据库之后显示为 只读 的解决方法

    嗯,附加完成后,数据库的灰色的,后面括号里写着(只读). 方法一: 碰到这中情况一般是使用的 sa 或者其它 SQL Server 身份验证登录的,只要改为 Windows 身份验证,再附加数据库即可 ...

  7. UIButton 标题靠右

    _classBtn =  [UIButton buttonWithType:UIButtonTypeCustom]; _classBtn.frame = CGRectMake(  kDeviceWid ...

  8. MySQL循环语句实例教程 mysql while循环测试

    在mysql数据库中操作同样有循环语句操作,标准的循环方式: while 循环 . loop 循环和repeat循环.还有一种非标准的循环: goto. 鉴于goto 语句的跳跃性会造成使用的的思维混 ...

  9. Android4.4r1(KitKat)源码下载地址

    未经验证 http://blog.csdn.net/gaojinshan/article/details/14228737 百度云盘保存了大量android源码,没有经过验证,并不能保证能够正常编译, ...

  10. 转:\r,\n,\r\n的区别

    回车.换行的区别   他们间的区别其实是个回车换行的问题 先来段历史 回车”(Carriage Return)和“换行”(Line Feed)这两个概念的来历和区别. 符号        ASCII码 ...