当前位置: 首页 > 编程日记 > 正文

Appium+python自动化(八)- 初识琵琶女Appium(千呼万唤始出来,犹抱琵琶半遮面)- 下(超详解)...

​简介

通过上一篇宏哥给各位小伙伴们的引荐,大家移动对这位美女有了深刻的认识,而且她那高超的技艺和婀娜的身姿久久地浮现在你的脑海里,是不是这样呢???不要害羞直接告诉宏哥:是,就对了。宏哥要的就是这个效果。达到这个效果,就说明你学的差不多了,可以出师了。今天继续由宏哥给你引荐这位琵琶美女。

说明:Appium--奴家的大号,提起奴家的大号在江湖上也是无人不知,无人不晓。奴家==Appium;

1、界面认识(奴家外表)

在之前安装appium的时候说过我们有两种方法安装,也就有两种结果,一种是有界面的(客户端安装),一种是没有界面的(终端安装),首先我们先讲一下有界面的,以及界面有哪些东西。

首先和宏哥看一下琵琶女的外表,如果你的是windows系统那么界面就应该是这样的,所以当你发现你的和我的琵琶女不一样也不用担心,这个就是所谓的“龙生九子,各有不同”,但是正常windows版整个界面只有7个按钮,宏哥会按照从左到右从上到下的顺序讲。

(mac的会有一定的差异,但并不是很大,只是排版和样式的问题,但是功能都一样。)

1)Android Settings:左边的第一个按钮,主要是配置android的相关设置,他里面的结构图我们看下张图片

a.Application Path:选择路径,选择需要测试的app在本电脑存放的一个路径。在启动appium时他会默认去该路径下去寻找这个app,然后将他安装到指定的手机上。

b.Package:之前提到过的,我们这个包的身份证,我们需要通过这个去找到包,不然我们安装后我们通过什么去辨别这些包呢?

c.Launch Activity:故名思义,启动的activity,activity的时候提到过,我们启动app时需要去运行的activity,这里我们填写首次启动页面的activity。

备注:这里需要注意一个问题在我们每次通过Choose选择apk后,appium会自动把这个包进行重新签名,那么在package以及activity里面会自动把包名和activity的名称列进去,但是这里会出现一个问题,每次选择apk后列表中会有一个缓存的原因,即使你更改了apk,但是package还是没有变,这样启动的时候就一直报错,遇见这样的情况不要着急,重新启动两次就好。

d.Wait for Activity: 和上面的差不多,意思是等待某个Activity打开,用的时间不是很多,做了解。

e.Launch Device:标签下面的东西用得相对比较少,后面大家可以去了解一下。

f.Capabilities:该标签下和我们做自动化关系很大,后面我们做自动化时如何配置启动app等信息就用的该标签下的数据。

g.Platform Name:我们测试的app的类型,ios选择ios,android选择Android就好。

h.Automation Name:测试引擎的名称,我们使用的是appium,所以你第一眼就能看见Appium,但是他还有一个Selendroid。可能看到这里会有一些疑惑,为什么appium要选择两套系统呢?其实这个应该追溯到android的版本问题,android自己的工具在4.2版本以前是一个,但是后面进行了更新,可能也正是因为这个原因appium也才采用了两套,所以当你测试的app安装的机器时在4.0或之前的版本时那么这里的引擎你就必须选择Selendroid,是否这样大家可以动手去试一试。检验真理的唯一标准就是自己动手尝试。

i.Platform Version:安装应用手机的版本号,android的是几点几的版本。

j.Device Name:设备名称。

备注:这里会有一个问题,如果你测试android时,只把一台手机插入到电脑,即使你输入的Device Name是错误的,但是你依然能够正常安装,使用。但是ios是不行的。不知道在设计的时候是否就是如此考虑的,如果在以后使用中遇见类似问题大家不要惊慌。

k.Advanced标签下的东西在初级阶段不用担心,这个标签只是在你想同一台电脑同时控制多台手机的时候才能使用,需要更改Bootstrap Port的端口号,记住这一点就好。

2)General Setting:

在General Setting里面在通常情况下我们使用默认设置就好,但还是有一些基础设置可以进行调整,方便后期的学习。整个页面分成了Server和log两部分,默认的情况如下面图片。

a.Server Address:配置appium服务的地址,正常情况我们不需要更改,但是如果我们需要配置多台手机的时候启动了多个appium服务,那么这里的端口号我们需要进行调整,如果你多个都弄的同一个端口会报错。

b.Override Existing Session:session覆盖,可能对于初学者不理解什么叫session,你这里暂时理解为会话,我和你会话的唯一标示。

c.Log To File:默认状态是没有任何数据,但是在做自动化时建议选择,因为选择之后appium在运行时产生的日志都会保留到你设置的问题件,这个对后期的bug定位有相当大的帮助。切记!

3)开发者设置(左边第三个按钮,小人图标)很少用,可以忽略。如果有兴趣可以作为兴趣了解一下。

4)关于(左边第四个按钮,问号图标),查看当前appium的版本信息。

5)元素侦测(右边第二个按钮,放大镜图标):这个按钮的功能和firebug的定位工具功能类似,但是他还有一个功能,他会检测你的各个系统配置是否正确,如果前面各项参数不正确时,使用该功能会报错。如果你不正常连接手机也不行。还是建议用sdk工具里面自带的uiautomatorviewer。

6)启动服务(右边第一个按钮,三角图标):所有参数配置好后你需要做的就是启动appium服务,只有启动之后你才能够做自动化。

7)清除日志(右下角,垃圾桶图标):在写脚本、调试过程中会产生很多的日志,但是你可能想看的只是中间某个时间段的,那么你在这个时候可以将页面的日志清除。

2、日志分析(奴家语言)

通过前面的学习加上自己动手练习我相信很多小伙伴都能够将appium启动起来,并且会自动将app安装到手机或者模拟器,但是这个时候很多人看见appium的面板或者控制台会比较头疼。appium服务页面不断的在滚动日志,但是又看不懂,这个可能是通病。下面我们来分析一下这个日志,我们下面大概来解读一下我这个日志,让自己不再迷茫。在每一行的上面我来配置解读,让大家更容易理解。

我启动appium服务,指定了ip、端口、以及我的uid

192:~ ytxu$ appium -a 127.0.0.1 -p 4723 -U 127.0.0.1:62001

启动成功

[Appium] Welcome to Appium v1.6.3

[Appium] Non-default server args:

启动成功后的服务地址

[Appium]   address: ‘127.0.0.1'

我们的uid,因为我这里是链接的模拟器所以用的这个IP

[Appium]   udid: '127.0.0.1:62001'

[Appium] Deprecated server args:

系统自动拼接成字典的形式

[Appium]   -U,--udid => --default-capabilities '{"udid":"127.0.0.1:62001"}'

[Appium] Default capabilities, which will be added to each request unless overridden by desired capabilities:

[Appium]   udid: ‘127.0.0.1:62001'

REST http接口监听的是哪个端口

[Appium] Appium REST http interface listener started on 127.0.0.1:4723

通过POST的方式创建了一个session,这个session里面的值就是我们在配置app时的一些数据,这里系统把他自动转换成了字典的形式,一个key对应一个value。仔细去看你会发现都不陌生。

[HTTP] --> POST /wd/hub/session {"requiredCapabilities":{},"desiredCapabilities":{"deviceName":"127.0.0.1:62001","app":"/Users/ytxu/Desktop/AppiumPython/apps/mukewang.apk","autoLaunch":"true","platformVersion":"4.1","appPackage":"cn.com.open.mooc","platformName":"Android","appActivity":"cn.com.open.mooc.index.splash.MCSplashActivity"}}[debug] [MJSONWP] Calling AppiumDriver.createSession() with args: [{“deviceName":"127.0.0.1:62001","app":"/Users/ytxu/Desktop/AppiumPython/apps/mukewang.apk","autoLaunch":"true","platformVersion":"4.1","appPackage":"cn.com.open.mooc","platformName":"Android","appActivity":"cn.com.open.mooc.index.splash.MCSplashActivity"},{},null,null,null]

创建一个会话,准备开始对话,把开始填写的数据,传入数据后用服务端验证,如果成功就会话开始。

[Appium] Creating new AndroidDriver session[Appium] Capabilities:[Appium]   deviceName: '127.0.0.1:62001'[Appium]   app: '/Users/ytxu/Desktop/AppiumPython/apps/mukewang.apk'[Appium]   autoLaunch: 'true'[Appium]   platformVersion: '4.1'[Appium]   appPackage: 'cn.com.open.mooc'[Appium]   platformName: 'Android'[Appium]   appActivity: 'cn.com.open.mooc.index.splash.MCSplashActivity'[Appium]   udid: '127.0.0.1:62001'[debug] [AndroidDriver] AndroidDriver version: 1.10.38

看到这里你是否还觉得这个很麻烦?其实只要你仔细去看你会很容易都了解的。可能这里会有小伙伴说这个启动的很容易,但是在实际中遇见的问题就没这么容易了,那么下面我们看一个实际遇见的问题,直接看日志:

 1 debug] [ADB] We tried to start an activity that doesn't exist, retrying with . prepended to activity
 2 
 3 [debug] [ADB] Device API level: 19
 4 
 5 [debug] [ADB] Getting connected devices...
 6 
 7 [debug] [ADB] 1 device(s) connected
 8 
 9 [debug] [ADB] Running '/Users/ytxu/Library/Android/sdk/platform-tools/adb' with args: ["-P",5037,"-s","127.0.0.1:62001","shell","am","start","-W","-n","cn.com.open.mooc/.cn.com.open.mooc.aindex.splash.MCSplashActivity","-S","-a","android.intent.action.MAIN","-c","android.intent.category.LAUNCHER","-f","0x10200000"]
10 
11 [ADB] Error: Activity used to start app doesn't exist or cannot be launched! Make sure it exists and is a launchable activity
12 
13     at Object.wrappedLogger.errorAndThrow (lib/logger.js:60:13)
14 
15     at ADB.callee$0$0$ (../../../lib/tools/apk-utils.js:68:13)
16 
17     at tryCatch (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:67:40)
18 
19     at GeneratorFunctionPrototype.invoke [as _invoke] (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:315:22)
20 
21     at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:100:21)
22 
23     at GeneratorFunctionPrototype.invoke (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:136:37)
24 
25  Error: Activity used to start app doesn't exist or cannot be launched! Make sure it exists and is a launchable activity
26 
27     at Object.wrappedLogger.errorAndThrow (lib/logger.js:60:13)
28 
29     at ADB.callee$0$0$ (../../../lib/tools/apk-utils.js:68:13)
30 
31     at tryCatch (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:67:40)
32 
33     at GeneratorFunctionPrototype.invoke [as _invoke] (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:315:22)
34 
35     at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:100:21)
36 
37     at GeneratorFunctionPrototype.invoke (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:136:37)
38 
39 [ADB] Error: Error occured while starting App. Original error: Activity used to start app doesn't exist or cannot be launched! Make sure it exists and is a launchable activity
40 
41     at Object.wrappedLogger.errorAndThrow (lib/logger.js:60:13)
42 
43     at ADB.callee$0$0$ (../../../lib/tools/apk-utils.js:80:9)
44 
45     at tryCatch (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:67:40)
46 
47     at GeneratorFunctionPrototype.invoke [as _invoke] (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:315:22)
48 
49     at GeneratorFunctionPrototype.prototype.(anonymous function) [as next] (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:100:21)
50 
51     at GeneratorFunctionPrototype.invoke (/usr/local/lib/node_modules/appium/node_modules/babel-runtime/regenerator/runtime.js:136:37)
52 
53  Error: Error occured while starting App. Original error: Activity used to start app doesn't exist or cannot be launched! Make sure it exists and is a launchable activity
54 
55     at Object.wrappedLogger.errorAndThrow (lib/logger.js:60:13)

从第一眼看见这个日志我知道大家的第一反应已经晕了,没事我们来仔细看。就日志的第一行说的大概意思就是“我们尽力去运行这个Activity了,但是他还是不存在。”那么看到这里小伙伴应该思考一个问题,在前面配置页面时就讲过如果你配置package或者activity错误那么是无法启动的。现在已经告诉我们说这个Activity不存在了是否应该去仔细检查一下呢?

其实在整个日志中我们应该直接去看error的部分,[ADB] Error: Activity used to start app doesn't exist or cannot be launched! Make sure it exists and is a launchable activity,这是error的日志,给出的提示也是这个activity不能够被启动,让你再次确认后再去启动。

从这个小小的实验我们能够看出日志本身并不难,难的是我们没仔细看。所以以后遇见问题不要烦躁,应该仔细看日志,然后解决问题。

3、 appium的工作原理(奴家的看家本领)

我们在去熟悉一套系统或者框架的时候,我们想去学好,我们是不是都要了解一下工作原理呢?只有我们知道了他是如何工作之后,在以后我们遇见棘手的问题时才能够从根本去解决问题。但是在讲这个之前需要讲一个题外话,不知道有谁思考过appium是如何实现自动化的吗?无论ios还是android在做自动化时考虑到安全等因素他们都是不允许直接去操作的,所以我们要做自动化那么就必须借助他们本身公布出来的一些工具,android是UIAutomator,ios使用的是UIAutomation,其实我们所谓的自动化就是我们使用的工具去调用他们公布出来的框架的方法,然后再去执行。下面我们来看一下appium的工作原理,首先来看一张图片。

通过上面的图片我们可以知道appium是基于WebDriver协议的,他利用Bootstrap调用google公布的android的自动化测试框架UIautomator的命令来实现我们的app自动化,再能理解一点就是我们的电脑(client)上运行自动化测试脚本,调用的是webdriver的接口,appium server接收到我们client上发送过来的命令后他会将这些命令转换为UIautomator认识的命令,然后由UIautomator来执行自动化。

可能这里有些小伙伴会迷糊,说android是这样那么ios也是这样吗?其实真的差不多,只是他们支持的工具不一样,ios使用的是UIAutomation,首先client发送脚本请求,再到我们的appium服务,这里appium会调用instruments去启动一个server,然后让他去执行后面的操作来完成自动化。备注:UIAutomation是instruments下面的一个工具,所以不要惊慌。

4、Appium的优势(奴家优点)

现在市面上做自动化的框架无论是成熟还是一般的都有很多,我们不可能都去熟悉,但是我们需要了解一个常见的,不然你怎么知道好与坏呢?我相信在学习自动化时就想过为什么需要学appium,其实我在刚开始做移动自动化时选择的是robotium,但是后来因为项目的需要发现我如果只是用robotium发现ios根本没法做,那么我就需要去单独做一个,这个会很麻烦,这个时候appium刚好出来了,刚接触他我就决定使用了,因为在之前做web自动化时用的就是selenium,所以这个用起来会很方便。下面我们来列举一下他的优点:

1、可以同时支持android、ios

2、支持多种语言,java、python、php、Ruby等等

3、不用为复杂的环境发愁

4、如果你有selenium经验,直接上手

从上面来看他的优点还是很多的,当然缺点也有,这里不列举了,免得破坏美好的印象。

当看到这里的时候你对奴家(appium)是否已经有一个更加清晰的影子了呢?接下来我们需要的就是去动手实战吧。

5、小结

1、appium mac和windows下都有两种安装模式,一种是通过客户端安装,一个是终端安装,这里说一下区别:

做自动化肯定不可能只是在一台机器上做自动化,因为那样的意义并不是很大,所以很多时候我们都是链接多台电脑去执行,但是appium去链接多台电脑时就需要启动多个appium的服务,如果说你安装是通过客户端去安装的,你链接多台机器就需要启动多次,配置多次,这样对你电脑本身也是一个性能考验。如果你是通过终端命令安装的在启动的时候你只需要通过命令启动多个服务就好。这里为什么说这么多,就是因为曾经作者在做一个项目时统一体啊机器上appium客户端启动了5个,长期运行case后appium的服务会自动挂掉,但是通过终端安装启动超过10个服务,同时去运行依然没有问题。这是我的经历不一定全对,读者可以根据自己爱好进行选择。

appium客户端安装:

(1)去官方下载:http://appium.io/  比较慢,相比之下慢,其实宏哥这边还是嗖嗖的很快地

(2)国内下载:链接: https://pan.baidu.com/s/1SqGzEFzWfNjyQBE1lsiKOw 提取码: 48af (贼快,推荐)

现在安装包后直接傻瓜式的安装,一切下一步,默认即可。(windows也是一样)

appium终端安装:

直接在终端输入命令:npm install -g appium。(切记不要用sudo去执行) 在安装过程中不报错,你就安装成功了,报错也不要着急,可以百度解决,也可以联系我。appium命令安装默认的是在国外去请求,因为n多原因你失败了,so建议使用如下命令 访问国内的镜像安装npm --registry http://registry.cnpmjs.org install -g appium  成功后输入appium会提示: Welcome to Appium 说明安装成功了。

宏哥不能保证所整理都符合大家的口味,但我能保证每一篇都是用心去写和用心去整理,我始终认同“分享的越多,你的价值增值越大”,欢迎大家关注我的博客和个人公众号的技术分享。在分享中进步,越努力越幸运,期待我们都有美好的明天!

支持宏哥的朋友们和宏哥的宏粉记得点波推荐哦,您的肯定就是我进步的动力。鄙人先在这里给您道谢了,谢您嘞~~

个人公众号(因为许多文章都被搬到别人的公众号里了,还是原创,所以宏哥果断也开一个公众号。打算与博客园文章同步,希望大家随时随地学习与进步):

微信群(因为有人给我发短消息说公司不让用QQ,就帮忙建立一个微信群,欢迎加入讨论和交流)

转载于:https://www.cnblogs.com/du-hong/p/11057116.html

相关文章:

蜻蜓resin服务器虚拟目录的设置

首先&#xff0c;别急着打开服务器先&#xff0c;接住打开resin主目录下的conf文件夹的resin.conf文件&#xff0c;老规矩&#xff0c;备份先&#xff0c;mv resin.conf resin.conf.bak然后vi resin.conf 文件&#xff0c;找到如下这段代码&#xff1a;1 <!--configures the…

【java】兴唐第十节课知识点总结

1、使用main里的成员方法也要实例化对象吗&#xff1f; 必须实例化 ///重点&#xff01; 2、在成员方法中调用另一个成员方法可以直接调用&#xff08;前面省略一个this.&#xff09; 3、 \n也可以在java里用 4、null可以是除了基本数据类型外的任何数据类型 5、基本数据类…

SharePoint2010是个什么东西

Microsoft SharePoint Foundation is an application that is built on top of Internet Information Services (IIS) and the Microsoft ASP.NET Framework. Microsoft SharePoint Foundation 是架构在IIS和ASP.NET Framework上的一个应用程序。IIS是与互联网站点相关的&#…

Linux Shell高级技巧(目录)

为了方便我们每个人的学习&#xff0c;这里将给出Linux Shell高级技巧五篇系列博客的目录以供大家在需要时参阅和查找。 Linux Shell高级技巧(一) http://www.cnblogs.com/stephen-liu74/archive/2011/12/22/2271167.html一、将输入信息转换为大写字符后再进行条件判断二、为调…

Keras卷积+池化层学习

转自&#xff1a;https://keras-cn.readthedocs.io/en/latest/layers/convolutional_layer/ https://keras-cn.readthedocs.io/en/latest/layers/pooling_layer/ 1.con1D keras.layers.convolutional.Conv1D(filters, kernel_size, strides1, paddingvalid, dilation_rate1, ac…

【Java】阿里巴巴java开发手册总结(我能看懂的)

尽管这本《手册》句句是精华&#xff0c;但由于我还是个菜鸟&#xff0c;这里仅作&#xff08;我能用的到的&&我能看懂的&#xff09;的笔记 1.1命名风格 1、类名用UpperCamelCase的风格 2、方法名、参数名、成员变量、局部变量都统一用lowerCameCase的风格&#xff…

关于maya与max互导FBX出现错误的解决方案。

因为自己实在是不愿意一次又一次把时间浪费在导入导出的问题上。每一次都是多试几次才成功&#xff0c;也没有真正去测试这个东西。但是今天实在是碰到了错误中的极品了。最后还是决定写下来。。算是给自己做笔记吧。。大家如果在导入导出的时候遇到一些问题不妨试试以下几种方…

AS3.0中的显示编程(六)-- 几何结构

几何结构&#xff0c;主要是完成Flash编程中&#xff0c;一些和几何相关的内容。如显示对象的变形角度、公式计算等。可能很多人和我一样&#xff0c;高中学的几何知识&#xff0c;差不多都已经还给老师了。不过也不用太担心&#xff0c;因为一般情况下&#xff0c;我们也用不到…

Win10命令行激活 电脑组装

系统激活&#xff1a; 1. 管理员身份运行 cmd 2. slmgr.vbs /upk //卸载产品密匙 3. slmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GX //安装 4. slmgr /skms zh.us.to …

【java】兴唐第十五节课

知识点&#xff1a; 1、定义包名不能以java.为开头。 2、获取系统时间的方法&#xff1a; 注意&#xff1a; &#xff08;1&#xff09; 引入Date类时&#xff0c;引入的是java.util.Date 而不是java.sql.Date(后者是前者的子类)。 代码实现 Date date new Date(); System.o…

SQL Server 日期和时间相关的数据类型有两种

SQL Server 日期和时间相关的数据类型有两种&#xff1a;DateTime和SmallDateTime。 DateTime:需要8个字节&#xff0c;前4个字节用1900年1月1日以后的天数表示日期&#xff0c;后4个字节表示一天中的时间。支持的日期范围&#xff1a;1/1/1753 12:00:00 AM到12/31/9999 11:59…

序列化pickle

import pickle d { name:alex, role:police, blood: 76, weapon:AK47 } d_dump pickle.dumps(d) #序列化 print (pickle.loads(d_dump)) #反序列化 f open(game.pkl, wb) pickle.dump(d, f) #First in first out (FIFO) pickle.dump(alive_players, f) dump 写入文件 du…

T-SQL笔记3:事务、锁定和并发

T-SQL笔记3&#xff1a;事务、锁定和并发 本章摘要 1&#xff1a;事务 1.1&#xff1a;显式事务 1.2&#xff1a;使用DBCC OPENTRAN显示最早的活动事务 2&#xff1a;锁定 2.1&#xff1a;查看锁的活动 3&#xff1a;并发影响及隔离级别 3.1&#xff1a;并发影响 3.2&#xff1…

几种常用数据库比较

目前&#xff0c;商品化的数据库管理系统以关系型数据库为主导产品&#xff0c;技术比较成熟。面向对象的数据库管理系统虽然技术先进&#xff0c;数据库易于开发、维护&#xff0c;但尚未有成熟的产品。国际国内的主导关系型数据库管理系统有Oracle、Sybase、INFORMIX和INGRES…

成功将BlogEngine 1.5 升级到了BlogEngine 2.0

使用BlogEngine.Net博客系统有两年时间了。官方的最新版本已经出到了2.5。但它是基于.net4.0的。也就是说服务器必须安装.net4.0&#xff0c;运行环境必须选择4.0。出于移植性的考虑。我决定将我的博客升级到2.0。BlogEngine.Net2.0是继续.net2.0的。虽说必须安装.net 3.5&…

【java】4.27上课及做作业时遇到的问题及第十六节课笔记整理

注意&#xff1a; 部分知识点只在eclipse运行环境中适用 1、字符串转化为字符数组的方法: 代码实现&#xff1a; char[] strcs text.toCharArray();2、字符数字转化为字符串 String reStr new String(re,0 ,position);3、打包及 引包的方法 &#xff08;1&#xff09; 用ex…

【Android】基于A星寻路算法的简单迷宫应用

简介 基于【漫画算法-小灰的算法之旅】上的A星寻路算法&#xff0c;开发的一个Demo。目前实现后退、重新载入、路径提示、地图刷新等功能。没有做太多的性能优化&#xff0c;算是深化对A星寻路算法的理解。 界面预览: 初始化: 寻路: 后退: 提示: 完成: 刷新地图: 下载地址: 项目…

[转]SQL 约束讲解

约束主要包括&#xff1a; •NOT NULL •UNIQUE •PRIMARY KEY •FOREIGN KEY •CHECK •DEFAULT 1、not null &#xff1a;用于控制字段的内容一定不能为空&#xff08;NULL&#xff09;。 用法 &#xff1a;Create table MyTable ( id …

JSON 转 VO

需求 将获取的json数据直接转为vo 解决 利用net.sf.json.JSONObject的toBean() 确保json中的key值和vo中的字段名称一致 JSONObject jsonObject new JSONObject();UserVO vo new UserVO(); vo (UserVO) net.sf.json.JSONObject.toBean(jsonObject, UserVO.class);参考文档地…

怎样查看一个端口有无开启

有时候我们需要确定一下某个端口有无开启&#xff0c;有两种方法。 方法 1&#xff1a;查看一个端口有无开启的最简单方法 查看端口有无开启&#xff0c;需要在dos里使用命令来完成。这个命令就是&#xff1a; netstat -ano这个命令能显示当前电脑有哪些端口正在使用&#xff0…

一道SQL统计试题

根据上图A表和B表&#xff0c;按照年份和地区生成1至12个月的数据&#xff0c;结果如下&#xff1a; 方法一&#xff1a; select YEAR,AreaName, MAX(case Month when 1 then Money else 0 end) as [1月], MAX(case Month when 2 then Money else 0 end) as [2月], MAX(case Mo…

【单片机】时钟周期 器械周期 指令周期的关系

1、 时钟周期&#xff08;振荡周期&#xff09;&#xff1a;始终周期也称振荡周期&#xff0c;定义为时钟频率的倒数。时钟周期是计算机中最基本的、最小的单位。在一个始终周期内&#xff0c;CPU仅完成一个最基本的动作。时钟周期是一个时间的量。始终周期表示了SDRAM&#xf…

Painting A Board --POJ 1691

1、题目类型&#xff1a;暴力法、DFS。 2、解题思路&#xff1a;题意&#xff0c;一块大的矩形区域的被分成多个矩形区域&#xff0c;现在要给不同的区域涂上不同的颜色&#xff0c;有不同颜色的刷子可以提供&#xff0c;每个刷子可以刷一种不同的颜色。每刷一次&#xff0c;将…

《JavaScript高级程序设计》读书笔记【一】

JavaScript介绍 ECMAScript&#xff0c;由ECMA-262定义&#xff0c;提供核心语言功能&#xff1b;  文档对象模型&#xff08;DOM&#xff09;&#xff0c;提供访问和操作网页内容的方法和接口&#xff1b;  浏览器对象模型&#xff08;BOM&#xff09;&#xff0c;提供与浏…

上不了名校?可以在 GitHub 上读他们的课程

今天开始&#xff0c;全国各大区域的高考成绩陆续公布&#xff0c;又到了几家欢喜几家愁的时刻&#xff0c;如果你准备报考计算机相关专业&#xff0c;但是又由于分数不高而苦恼。别担心&#xff0c;在 GitHub 上有着大量的名校教学资源&#xff0c;即使上不了名校&#xff0c;…

【java】各种方法的使用(不定期更新)

疑难杂症篇 1、输入一个字符的方法 问题在于Scanner中没有一个类似于nextInt()之类的函数。 代码实现 char num scanner.next().charAt(0);2、将字符串转化为数字 没啥问题就是记不下来 代码实现&#xff1a; int a1 Integer.parseInt(i1);3、字符串转化为字符数组的方法 …

SQL SERVER 触发器示例

触发器是一种特殊的存储过程。 触发器语法 &#xff1a; CREATE TRIGGER trigger_name ON { table | view } [ WITH ENCRYPTION ] { FOR | AFTER | INSTEAD OF } { [ INSERT ] [ DELETE ] [ UPDATE ] } [ WITH APPEND ] [ NOT FOR REPLICATION ] AS sql_statement [ ...n ] 示…

vc数据库知识

在连接SQL数据库时&#xff0c;数据库的链接: _bstr_t strConn"ProviderSQLOLEDB.1;Data Source.;Initial Catalogdb_test;Integrated SecuritySSPI;Persist Security InfoFalse"; _ConnectionPtr m_pConnection; m_pConnection.CreateInstance(__uuidof(connection)…

jmeter 测试 api 接口方法

双击 “jmeter.bat” 打开 Jmeter 页面&#xff0c;如下图所示。 右击“测试计划”&#xff0c;添加 -> Theaders&#xff08;Users&#xff09; -> 线程组 在线程组中可以设置线程数、并发数、循环数等。 下面开始进行几种 jmeter 的接口测试方法。 1、get 请求配置 右击…

我要学ASP.NET MVC 3.0(一): MVC 3.0 的新特性

摘要 MVC经过其1.0和2.0版本的发展&#xff0c;现在已经到了3.0的领军时代&#xff0c;随着技术的不断改进&#xff0c;MVC也越来越成熟。使开发也变得简洁人性化艺术化。 园子里有很多大鸟都对MVC了如指掌&#xff0c;面对问题犹同孙悟空的七十二变一般游刃有余&#xff0c;令…