github 代码下载: git clone https://github.com/HappyFreeAngel/arcgis-performance-test-by-selenium-grid.git
1.测试思路
创建一台测试虚拟机,使用selenium 自动化UI测试方法测试 arcgis 地图引擎, 验证200台终端同时持续的随机访问arcgis 服务器时,arcgis 服务器是否可以正常服务.
Arcgis 服务器配置: 虚拟机 Arcgis 10.5 安装在windows2008, 内存32GB,硬盘500GB,CPU 4个
内存 100GB,硬盘100GB,CPU 40个,操作系统cenos7
创建完成后,记得优化centos7
2.构造一个简单的页面,可以打开指定的地图,这里用的是cgs2000坐标系, index.html 内容如下面的web代码,
3.用浏览器打开这个页面,确保可以打开地图。
4.把这个页面部署到nginx 服务器测试虚拟机上。
这里我用的是nginx docker, 外挂一个目录,目录里放的是index.html
记得打开web端口,8777 (不用80,8080 因为测试机在单位内网,单位禁止使用这2个端口)
5. 用浏览器打开 http://11.23.3.114:8777/index.html 确保一切正常浏览。
6.测试方法 地图上找个中心点 (下面用的是福州市的地图中心点) //119.30239300, latitude=26.06971100 福州茶亭公园 wgs84, 修改index.html
7. 采用本地WebDriver 方式测试(我是在Mac + chrome )
8. 浏览器打开 http://11.23.3.114:8777/index.html 这个页面后, 随机生成经度和纬度,偏差控制在 新的点在指定城市(福州市)地图上即可,最好加上市区的落点概率80%,郊区的20%,也就是20%的市区面积有80%的访问率,80%面积的郊区有20%的落点概率。
9. 加载图层后,联系点击+ 放大图层,直到最大。
9.重复7的步骤。
10. 确认单一chrome 浏览器测试正常,达到预期。
11. 部署 整套测试环境
1.部署nginx
happy:nginx happy$ tree
.
├── start-docker.sh
└── www
└── index.html
1 directory, 2 files
happy:nginx happy$ more start-docker.sh
#!/bin/bash
#确保shell 切换到当前shell 脚本文件夹
current_file_path=$(cd "$(dirname "$0")"; pwd)
cd ${current_file_path}
sudo firewall-cmd --add-port=8777/tcp --zone=public --permanent
sudo firewall-cmd --add-port=443/tcp --zone=public --permanent
sudo firewall-cmd --reload
sudo firewall-cmd --list-all
docker stop testnginx
docker rm testnginx
docker run \
--restart=always \
--name=testnginx \
-p 8777:80 \
-p 443:443 \
-v `pwd`/www:/usr/share/nginx/html \
-d nginx:1.13-alpine
echo "打开http://localhost:8777/index.html 可以浏览"
happy:nginx happy$ more www/index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>ArcGIS JavaScript API: Image2013_CGCS2000</title>
<script src="http://11.23.2.101/arcgis_js_api/library/3.20/3.20/init.js"></script>
<link rel="stylesheet" href="http://11.23.2.101/arcgis_js_api/library/3.20/3.20/esri/css/esri.css">
<script type="text/javascript">
var m_map={};
require([
"esri/layers/ArcGISDynamicMapServiceLayer",
"esri/layers/ArcGISTiledMapServiceLayer",
"esri/map",
"dojo/parser",
"dojo/domReady!",
"dijit/layout/BorderContainer",
"dijit/layout/ContentPane"
], function(ArcGISDynamicMapServiceLayer, ArcGISTiledMapServiceLayer, Map, parser){
parser.parse();
var map = new Map("map");
var layer;
layer = new ArcGISTiledMapServiceLayer("http://11.23.2.101/arcgis/rest/services/Image2013_CGCS2000/MapServer");
map.addLayer(layer);
map.setZoom(3);
//map.centerAt(new esri.geometry.Point(119.3,25.9,new esri.SpatialReference({wkid:4490})));
//119.30239300, latitude=26.06971100
map.centerAt(new esri.geometry.Point(119.30239300,26.06971100,new esri.SpatialReference({wkid:4490})));
m_map=map;
m_map.test = function (lon,lat,level) {
map.setZoom(level);
map.centerAt(new esri.geometry.Point(lon,lat,new esri.SpatialReference({wkid:4490})));
}
});
var m_randomMove = function (lon,lat,level) {
m_map.test(lon,lat,level);
}
</script> </head> <body > <div id="map" style="width:1200px;height:1500px;" >
</div> </body>
</html>
2.部署selenium-grid
在测试虚拟机上。
mkdir -p /var/server/selenium-grid
happy:selenium-grid happy$ more start-selenium-grid-docker.sh
#!/bin/bash
#确保shell 切换到当前shell 脚本文件夹
current_file_path=$(cd "$(dirname "$0")"; pwd)
cd ${current_file_path}
echo "命令格式 ./start-selenium-grid-docker.sh {浏览器docker容器数量}"
echo "命令格式 ./start-selenium-grid-docker.sh {浏览器docker容器数量}"
echo "将运行$1个浏览器docker,按CTRL+C 中断退出"
if [ ! -n "$1" ] ;then
echo "请输入浏览器docker容器数量"
exit 1
else
echo "浏览器docker容器数量 是 $1"
fi
sleep 10
docker stop $(docker ps -a | grep 'selenium' | awk '{print $1 }')
docker rm $(docker ps -a | grep 'selenium' | grep 'Exited' | awk '{print $1 }')
#docker stop $(docker ps -a | grep 'selenium' | awk '{print $1 }')
#docker rm $(docker ps -a | grep 'selenium' | awk '{print $1 }')
#docker stop selenium-hub
#docker rm selenium-hub
dockerimage_compressed_tgz="selenium-hub-20180930.image.tgz"
dockerimage_name_version="selenium/hub:latest"
dockerimagelist=$(docker images | grep -v REPOSITORY | awk '{a=$1;b=$2;c=(a":"b);print c}')
found=0
#判断dockerimagelist里是否包含$dockerimage_name_version
case "${dockerimagelist}" in
*${dockerimage_name_version}*)
found=1;;
esac
if found==1 ; then
echo "${dockerimage_name_version}已经存在."
else
echo "本系统尚未加载${dockerimage_name_version} docker镜像,马上加载,请稍等一会儿..."
gunzip -c ${dockerimage_compressed_tgz} | docker load
fi
#gunzip -c selenium-hub-20180930.image.tgz | docker load
#gunzip -c selenium-node-chrome-20180930.image.tgz | docker load
#gunzip -c selenium-node-firefox-20180930.image.tgz | docker load
firewall-cmd --add-port=4444/tcp --zone=public --permanent
firewall-cmd --reload
docker run -d -p 4444:4444 --name selenium-hub selenium/hub:latest
COUNT=$1
for i in $(seq 1 $COUNT);
do
echo $i;
#docker run -d --link selenium-hub:hub selenium/node-firefox:latest
docker run -d --link selenium-hub:hub selenium/node-chrome:latest
done
echo "http://localhost:4444/grid/console"
12. 修改webdriver 为 RemoteWebDriver
public static void main(String[] args) throws Exception {
ArcgisPerformanceTest test = new ArcgisPerformanceTest();
String driverType="chrome";
// //1.本地测试,方便初期验证测试方法是否正确.
// for(int i=0;i<5;i++) {
// new Thread(()-> test.localTask(driverType)).start();
// test.waitFor(100);
// }
// test.waitFor(1000*60*60*24);
//2.selenium-grid 远程测试,用于大规模的压力测试,模拟真实用户访问.
int thread_number=180; //
for(int i=1;i<=thread_number;i++){
new Thread(()-> test.remoteTask(driverType)).start();
test.waitFor(100);
}
}
13. 运行测试 我是采用200个docker 实例
14. 手动打开Arcgis 看看是否还能打开,监控网络流量.
java 测试代码如下:
package com.linyingjie.tool.documentTranslate;
import com.linyingjie.tool.documentTranslate.translate.GoogleFreeTranslate;
import com.linyingjie.tool.documentTranslate.translate.TranslateDirection;
import com.linyingjie.tool.documentTranslate.webdriver.config.DriverFactory;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.openqa.selenium.remote.RemoteWebDriver;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;
public class Application {
private static List<DriverFactory> webDriverThreadPool = Collections.synchronizedList(new ArrayList<DriverFactory>());
private static ThreadLocal<DriverFactory> driverThread;
public static void main(String[] args) throws Exception {
String driverType="chrome";
for(int i=1;i<=180;i++){
new Thread(()-> remoteTask(driverType)).start();
waitFor(100);
}
for(int i=0;i<20;i++) {
new Thread(()-> localTask(driverType)).start();
waitFor(100);
}
waitFor(1000*60*60*24);
}
public static void remoteTask(String driverType){
String seleniumGridHubURL="http://11.23.3.114:4444/wd/hub";
try {
WebDriver webDriver = getRemoteDriver(driverType, seleniumGridHubURL);
String entryURL = "http://11.23.3.114:8777/index.html";
arcgisTest(webDriver, entryURL);
}catch(Exception e){
e.printStackTrace();
}
}
public static void localTask(String driverType){
try {
WebDriver webDriver = getLocalDriver(driverType);//getDriver();
String entryURL = "http://11.23.3.114:8777/index.html";
arcgisTest(webDriver, entryURL);
}catch(Exception e){
e.printStackTrace();
}
}
/**
* 远程版
* @throws Exception
*/
public static void remoteDriverTest() throws Exception {
DesiredCapabilities firefoxDesiredcap = DesiredCapabilities.firefox();
DesiredCapabilities chromeDesiredcap = DesiredCapabilities.chrome();
//DesiredCapabilities ieDesiredcap = DesiredCapabilities.internetExplorer();
//DesiredCapabilities desiredCapabilities = firefoxDesiredcap;
DesiredCapabilities desiredCapabilities = chromeDesiredcap;
//String seleniumGridHubURL="http://192.168.102.6:4444/wd/hub";
String seleniumGridHubURL="http://11.23.3.114:4444/wd/hub";
WebDriver webDriver = new RemoteWebDriver(new URL(seleniumGridHubURL), desiredCapabilities);
webDriverTest(webDriver);
}
/**
* 远程版
* @throws Exception
*/
public static WebDriver getRemoteDriver(String driverType,String seleniumGridHubURL) throws Exception {
DesiredCapabilities desiredCapabilities = null;
if("firefox".equals(driverType.toLowerCase())){
desiredCapabilities = DesiredCapabilities.firefox();
}
else if("chrome".equals(driverType.toLowerCase())){
desiredCapabilities = DesiredCapabilities.chrome();
}
else if("ie".equals(driverType.toLowerCase())){
desiredCapabilities = DesiredCapabilities.internetExplorer();
}
else {
throw new UnsupportedOperationException("尚未支持的类型....");
}
System.out.println("driverType="+driverType+" desiredCapabilities="+desiredCapabilities);
WebDriver webDriver = new RemoteWebDriver(new URL(seleniumGridHubURL), desiredCapabilities);
return webDriver;
}
public static void localWebDriverTest(){
WebDriver driver = getLocalDriver("chrome");//getDriver();
webDriverTest(driver);
}
//http://11.23.3.114:8777/
public static void arcgisTest(WebDriver webDriver, String entryURL) {
try {
try {
webDriver.manage().window().maximize();
}catch(Exception e){
e.printStackTrace();
}
webDriver.manage().timeouts().implicitlyWait(8, TimeUnit.SECONDS);
//driver.manage().timeouts().pageLoadTimeout(20,TimeUnit.SECONDS);
//driver.manage().timeouts().setScriptTimeout(20,TimeUnit.SECONDS);
webDriver.get(entryURL);
Thread.sleep(4000);
System.out.println(entryURL+" 加载成功.");
long step = 100000+System.nanoTime()%100000;
randomMove(webDriver,step);
webDriver.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
if (webDriver != null) {
System.out.println("driver!=null");
} else {
System.out.println("driver==null");
}
}
private static void randomMove(WebDriver webDriver,long step){
WebElement plusButton = null;
try {
plusButton = webDriver.findElement(By.xpath("//div[contains(@class,'esriSimpleSliderIncrementButton')]"));
}catch(Exception e){
e.printStackTrace();
}
//WebElement minusButton = webDriver.findElement(By.xpath("//div[contains(@class,'esriSimpleSliderDecrementButton')]"));
for(int i=0;i<step;i++) {
//119.30239300, latitude=26.06971100 福州茶亭公园
//119.30033306347656,26.06078460839844
double fuzhouCenterLongitude=119.30239300;
double fuzhouCenterLatitude=26.06971100;
double longitude=(fuzhouCenterLongitude-0.5)+0.5*Math.random();
double latitude=(fuzhouCenterLatitude-0.2)+0.5*Math.random();
int zoomLevel=1+(int)(Math.random()*8);
String randomMoveJavascript = "m_randomMove("+longitude+","+latitude+","+zoomLevel+");";
waitFor(1000);
if (webDriver instanceof JavascriptExecutor) {
try {
((JavascriptExecutor) webDriver).executeScript(randomMoveJavascript);
}catch(Exception e){
e.printStackTrace();
}
} else {
throw new IllegalStateException("This driver does not support JavaScript!");
}
int maxZoomLevel=12;
int k=1+(int)(Math.random()*maxZoomLevel);
if(plusButton!=null) {
for (int t = 0; t < k; t++) {
plusButton.click();
waitFor(100);
}
}
long timeWaitForInMilliseconds=3000+(long)(Math.random()*2000);
System.out.println("将等待"+timeWaitForInMilliseconds+"毫秒. longitude="+longitude+" latitude="+latitude);
waitFor(timeWaitForInMilliseconds);
}
}
public static void waitFor(long timeInMilliseconds) {
try {
Thread.sleep(timeInMilliseconds);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public static WebDriver getLocalDriver(String name) {
if ("firefox".equals(name.toLowerCase())) {
return getLocalFireFoxDriver();
}
if ("chrome".equals(name.toLowerCase())) {
return getLocalChromeDriver();
}
return null;
}
public static WebDriver getLocalFireFoxDriver() {
// declaration and instantiation of objects/variables
System.setProperty("webdriver.firefox.marionette", "/Users/happy/server/selenium/firefox/mac/0.21.0/geckodriver");
WebDriver driver = new FirefoxDriver();
return driver;
}
public static WebDriver getLocalChromeDriver() {
System.setProperty("webdriver.chrome.driver", "/Users/happy/server/selenium/chrome/mac/2.40/chromedriver");
WebDriver driver = new ChromeDriver();
return driver;
}
}