qileilove

blog已经转移至github,大家请访问 http://qaseven.github.io/

关于安卓通过webservice访问数据库问题

 ============问题描述============
  访问数据库时,手机能增删数据库的数据就是显示不了数据库的里的数据不知道是哪里的问题,用的HTTP
  这是我webservice中的产看所有信息的方法:
public List<string> selectAllCargoInfor()
{
List<string> list = new List<string>();
try
{
string sql = "select * from C";
SqlCommand cmd = new SqlCommand(sql,sqlCon);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
//将结果集信息添加到返回向量中
list.Add(reader[0].ToString());
list.Add(reader[1].ToString());
list.Add(reader[2].ToString());
}
reader.Close();
cmd.Dispose();
}
catch(Exception)
{
}
return list;
}
  接下来是安卓端的:
  这个是MainActivity中的设置LISTVIEW的方法
private void setListView() {
listView.setVisibility(View.VISIBLE);
List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
list = dbUtil.getAllInfo();
adapter = new SimpleAdapter(MainActivity.this, list, R.layout.adapter_item,
new String[] { "Cno", "Cname", "Cnum" },
new int[] { R.id.txt_Cno, R.id.txt_Cname, R.id.txt_Cnum });
listView.setAdapter(adapter);
}
  这个是操作类:
public List<HashMap<String, String>> getAllInfo() {
List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
arrayList.clear();
brrayList.clear();
crrayList.clear();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
crrayList = Soap.GetWebServre("selectAllCargoInfor", arrayList, brrayList);
}
}).start();
HashMap<String, String> tempHash = new HashMap<String, String>();
tempHash.put("Cno", "Cno");
tempHash.put("Cname", "Cname");
tempHash.put("Cnum", "Cnum");
list.add(tempHash);
for (int j = 0; j < crrayList.size(); j += 3) {
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("Cno", crrayList.get(j));
hashMap.put("Cname", crrayList.get(j + 1));
hashMap.put("Cnum", crrayList.get(j + 2));
list.add(hashMap);
}
return list;
}
连接webservice的那个方法HttpConnSoap应该是没问题的因为数据库的增删都是可以的,就是无法实现这个显示所有信息到LISTVIEW中的这个功能不知道为什么,LOGCAT中也是一片绿没什么问题
  LOGCAT中的信息:
05-02 15:51:40.642: I/System.out(3678): <?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><selectAllCargoInforResponse xmlns="http://tempuri.org/"><selectAllCargoInforResult><string>1</string><string>rice</string><string>100</string><string>2</string><string>dog</string><string>50</string><string>3</string><string>白痴</string><string>25</string></selectAllCargoInforResult></selectAllCargoInforResponse></soap:Body></soap:Envelope>
05-02 15:51:40.647: I/System.out(3678): <?xml version="1.0" encoding="utf-8"?
05-02 15:51:40.647: I/System.out(3678): soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
05-02 15:51:40.647: I/System.out(3678): soap:Body
05-02 15:51:40.647: I/System.out(3678): selectAllCargoInforResponse xmlns="http://tempuri.org/"
05-02 15:51:40.647: I/System.out(3678): selectAllCargoInforResult
05-02 15:51:40.647: I/System.out(3678): 0
05-02 15:51:40.647: I/System.out(3678): string>1</string
05-02 15:51:40.647: I/System.out(3678): string>rice</string
05-02 15:51:40.647: I/System.out(3678): string>100</string
05-02 15:51:40.647: I/System.out(3678): string>2</string
05-02 15:51:40.652: I/System.out(3678): string>dog</string
05-02 15:51:40.652: I/System.out(3678): string>50</string
05-02 15:51:40.652: I/System.out(3678): string>3</string
05-02 15:51:40.652: I/System.out(3678): string>白痴</string
05-02 15:51:40.652: I/System.out(3678): string>25</string
05-02 15:51:40.652: I/System.out(3678): /selectAllCargoInforResult
05-02 15:51:40.652: I/System.out(3678): 1
  ============解决方案1============
  分析原因就是在线程还没有执行完时候,getAllInfo早已执行完毕以后,,所以在执行for (int j = 0; j < crrayList.size(); j += 3)时候, crrayList为零行。你取出的LOGCAT是执行请求以后的返回数据,这时候setListView方法早已经走完,所以只有一行数据。截图中的一行数据来自
  HashMap<String, String> tempHash = new HashMap<String, String>();
  tempHash.put("Cno", "Cno");
  tempHash.put("Cname", "Cname");
  tempHash.put("Cnum", "Cnum");
  list.add(tempHash);
  使用Thread应该配合Handler来使用。
  我把代码修改一下
private final static int   REQUEST_SUCCESS = 1;
private final static int   REQUEST_FALSE = 0;
private void RequestData()
{
arrayList.clear();
brrayList.clear();
crrayList.clear();
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
crrayList = Soap.GetWebServre("selectAllCargoInfor", arrayList, brrayList);
Message msg = new Message();
if(crrayList.size()>0)
{
msg.what = REQUEST_SUCCESS;
}
else
{
msg.what = REQUEST_FALSE;
}
// 发送消息
mHandler.sendMessage(msg);
}
}).start();
}
public Handler mHandler = new Handler(){
// 接收消息
@Override
public void handleMessage(Message msg) {
// TODO Auto-generated method stub
super.handleMessage(msg);
switch (msg.what)
{
case REQUEST_SUCCESS:
setListView();
break;
case REQUEST_FALSE:
// 做错误处理
break;
default:
break;
}
}
};
private void setListView() {
listView.setVisibility(View.VISIBLE);
List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
list = dbUtil.getAllInfo();
adapter = new SimpleAdapter(MainActivity.this, list, R.layout.adapter_item,
new String[] { "Cno", "Cname", "Cnum" },
new int[] { R.id.txt_Cno, R.id.txt_Cname, R.id.txt_Cnum });
listView.setAdapter(adapter);
}
public List<HashMap<String, String>> getAllInfo() {
List<HashMap<String, String>> list = new ArrayList<HashMap<String, String>>();
HashMap<String, String> tempHash = new HashMap<String, String>();
tempHash.put("Cno", "Cno");
tempHash.put("Cname", "Cname");
tempHash.put("Cnum", "Cnum");
list.add(tempHash);
for (int j = 0; j < crrayList.size(); j += 3) {
HashMap<String, String> hashMap = new HashMap<String, String>();
hashMap.put("Cno", crrayList.get(j));
hashMap.put("Cname", crrayList.get(j + 1));
hashMap.put("Cnum", crrayList.get(j + 2));
list.add(hashMap);
}
return list;
}
  执行RequestData就可以,我没法编译,细节自己再调整看一下,应该能解决问题了。
  你给的分数太少了,大牛们都不给你解答。如果解决问题就给分哈。
  另外,Java多线程的操作可以系统学习一下。工作中使用极为频繁

posted @ 2014-12-11 23:42 顺其自然EVO 阅读(867) | 评论 (0)编辑 收藏

PLSQL Developer鲜为人知的快捷键

注释:
  使用PLSQL Developer的朋友们是否有遇到如下情况
  ① 不小心关闭了有用的窗口;
  ② 有意义的sql前几分钟不用了且关闭的情况;
  ③ PLSQL Developer界面中其中1个session 死掉了不得不关闭时,再重新开启点击恢复会话后可能不会和之前场景一摸一摸时;
  如上的情况都可以通过如下快捷键进行恢复.
  Ctrl+E【default】  ==> Edit / Recall Statement
  显示结果:
  选中任意一行 双击 直接进入源编辑界面.
  更改该快捷键步骤:
  PLSQL Developer --> tools --> preferences --> key configuration

posted @ 2014-12-11 23:40 顺其自然EVO 阅读(1381) | 评论 (0)编辑 收藏

淘宝分布式配置管理服务Diamond

 在一个分布式环境中,同类型的服务往往会部署很多实例。这些实例使用了一些配置,为了更好地维护这些配置就产生了配置管理服务。通过这个服务可以轻松地管理这些应用服务的配置问题。应用场景可概括为:
  zookeeper的一种应用就是分布式配置管理(基于ZooKeeper的配置信息存储方案的设计与实现)。百度也有类似的实现:disconf。
  Diamond则是淘宝开源的一种分布式配置管理服务的实现。Diamond本质上是一个Java写的Web应用,其对外提供接口都是基于HTTP协议的,在阅读代码时可以从实现各个接口的controller入手。
  分布式配置管理
  分布式配置管理的本质基本上就是一种推送-订阅模式的运用。配置的应用方是订阅者,配置管理服务则是推送方。概括为下图:
  其中,客户端包括管理人员publish数据到配置管理服务,可以理解为添加/更新数据;配置管理服务notify数据到订阅者,可以理解为推送。
  配置管理服务往往会封装一个客户端库,应用方则是基于该库与配置管理服务进行交互。在实际实现时,客户端库可能是主动拉取(pull)数据,但对于应用方而言,一般是一种事件通知方式。
  Diamond中的数据是简单的key-value结构。应用方订阅数据则是基于key来订阅,未订阅的数据当然不会被推送。数据从类型上又划分为聚合和非聚合。因为数据推送者可能很多,在整个分布式环境中,可能有多个推送者在推送相同key的数据,这些数据如果是聚合的,那么所有这些推送者推送的数据会被合并在一起;反之如果是非聚合的,则会出现覆盖。
  数据的来源可能是人工通过管理端录入,也可能是其他服务通过配置管理服务的推送接口自动录入。
  架构及实现
  Diamond服务是一个集群,是一个去除了单点的协作集群。如图:

服务之间同步
  Diamond服务集群每一个实例都可以对外完整地提供服务,那么意味着每个实例上都有整个集群维护的数据。Diamond有两种方式保证这一点:
  任何一个实例都有其他实例的地址;任何一个实例上的数据变更时,都会将改变的数据同步到mysql上,然后通知其他所有实例从mysql上进行一次数据拉取(DumpService::dump),这个过程只拉取改变了的数据
  任何一个实例启动后都会以较长的时间间隔(几小时),从mysql进行一次全量的数据拉取(DumpAllProcessor)
  实现上为了一致性,通知其他实例实际上也包含自己。以服务器收到添加聚合数据为例,处理过程大致为:
DatumController::addDatum // /datum.do?method=addDatum
PersistService::addAggrConfigInfo
MergeDatumService::addMergeTask // 添加一个MergeDataTask,异步处理
MergeTaskProcessor::process
PersistService::insertOrUpdate
EventDispatcher.fireEvent(new ConfigDataChangeEvent // 派发一个ConfigDataChangeEvent事件
NotifyService::onEvent // 接收事件并处理
TaskManager::addTask(..., new NotifyTask // 由此,当数据发生变动,则最终创建了一个NoticyTask
// NotifyTask同样异步处理
NotifyTaskProcessor::process
foreach server in serverList // 包含自己
notifyToDump // 调用 /notify.do?method=notifyConfigInfo 从mysql更新变动的数据
DatumController::addDatum // /datum.do?method=addDatum
PersistService::addAggrConfigInfo
MergeDatumService::addMergeTask // 添加一个MergeDataTask,异步处理
MergeTaskProcessor::process
PersistService::insertOrUpdate
EventDispatcher.fireEvent(new ConfigDataChangeEvent // 派发一个ConfigDataChangeEvent事件
NotifyService::onEvent // 接收事件并处理
TaskManager::addTask(..., new NotifyTask // 由此,当数据发生变动,则最终创建了一个NoticyTask
// NotifyTask同样异步处理
NotifyTaskProcessor::process
foreach server in serverList // 包含自己
notifyToDump // 调用 /notify.do?method=notifyConfigInfo 从mysql更新变动的数据
  虽然Diamond去除了单点问题,不过问题都下降到了mysql上。但由于其作为配置管理的定位,其数据量就mysql的应用而言算小的了,所以可以一定程度上保证整个服务的可用性。
  数据一致性
  由于Diamond服务器没有master,任何一个实例都可以读写数据,那么针对同一个key的数据则可能面临冲突。这里应该是通过mysql来保证数据的一致性。每一次客户端请求写数据时,Diamond都将写请求投递给mysql,然后通知集群内所有Diamond实例(包括自己)从mysql拉取数据。当然,拉取数据则可能不是每一次写入都能拉出来,也就是最终一致性。
  Diamond中没有把数据放入内存,但会放到本地文件。对于客户端的读操作而言,则是直接返回本地文件里的数据。
  服务实例列表
  Diamond服务实例列表是一份静态数据,直接将每个实例的地址存放在一个web server上。无论是Diamond服务还是客户端都从该web server上取出实例列表。
  对于客户端而言,当其取出了该列表后,则是随机选择一个节点(ServerListManager.java),以后的请求都会发往该节点。
  数据同步
  客户端库中以固定时间间隔从服务器拉取数据(ClientWorker::ClientWorker,ClientWorker::checkServerConfigInfo)。只有应用方关心的数据才可能被拉取。另外,为了数据推送的及时,Diamond还使用了一种long polling的技术,其实也是为了突破HTTP协议的局限性。如果整个服务是基于TCP的自定义协议,客户端与服务器保持长连接则没有这些问题。
  数据的变更
  Diamond中很多操作都会检查数据是否发生了变化。标识数据变化则是基于数据对应的MD5值来实现的。
  容灾
  在整个Diamond系统中,几个角色为了提高容灾性,都有自己的缓存,概括为下图:
  每一个角色出问题时,都可以尽量保证客户端对应用层提供服务。
  图中可分为以下部分讲解:

posted @ 2014-12-11 23:39 顺其自然EVO 阅读(2228) | 评论 (0)编辑 收藏

静态自动检查代码缺陷与隐患

代码缺陷和代码错误的最大区别是,代码缺陷不影响游戏编译,而代码错误编译都不通过。但是代码缺陷会影响游戏发布后产生的一系列BUG。。我今天无意间逛外国论坛发现的一个方法,使用了一下感觉挺给力的第一时间分享给大家。 下载下来以后,它是一个文件夹把整个文件夹拷贝在你unity的工程里面就行了。
  然后下载最新的mono 它是跨平台的,我用的是MAC所以我下载的就是一个 dmg文件, 下载完毕后安装完成即可。
  如下图所示, 选择Assets->Gendarme Report Level 选项,将弹出Gendarme界面,你可以选择它的优先级,然后点击Start按钮。如果报错的话,请把Assets文件夹下的gendarme文件夹和gendarme-report.html文件删除。
  如果你的项目比较大的话需要耐心的等待一下,大概1分钟左右。Report生成完毕后会弹出如下窗口,点击Open Report按钮即可。
  如下图所示,他会生成一个Html的页面在本地,打开后写的非常清晰,并且已经分好了类,他会告诉你那一行代码有缺陷,如何来修改你的代码。一不小心代码就一大堆隐患,赶快一个一个修改吧~

posted @ 2014-12-11 23:38 顺其自然EVO 阅读(449) | 评论 (0)编辑 收藏

敏捷开发下平衡质量和进度

  敏捷软件开发团队必须确保他们开发出来的产品质量能够满足要求,管理团队也经常希望开发团队能够提高速度以实现为客户提供更多的功能。本篇文章中多个作者探讨了质量和速度之间的关系,并提出了一些既能提高质量也能加快进度的方法。
  Bob Galen曾今在他的博客中发表了读懂我的唇语-敏捷并不快速的文章,在其中写到了追求软件开发进度下质量的重要性。
  敏捷是一个“质量游戏”,如果你以正直,承诺以及平衡的心态来玩这个游戏的话,那么结果将会是非常好的“速度游戏”,但它(速度)却并非没有代价。。。
  如果你无法玩转这个质量游戏,你所采纳的敏捷开发方法甚至比你以前使用的开发方法更慢。
  团队必须致力于把工作在一个迭代中完成,这也就意味着这些工作需要满足定义工作完成的所有标准。
  很多敏捷团队允许返工 – 修复漏洞,完成测试自动化,重构,或者设计不良导致sprint迭代的延误。即使大多数的敏捷工具允许拆分用例故事以捕捉在sprint迭代中已经完成的工作对比延期的工作,我也还是认为这给团队传达了错误的信息,让他们认为工作不在一个sprint迭代内完成是可以接受的。
  读懂我的唇语 – 并不是把所有事情做完,做完,做完!
  正如Bob解释的:一个组织不应该总是力图让进度变得更快,而应该更加注重质量。
  因此,下一次当你听到有人在激情澎湃的谈论着敏捷代表了更快的速度时,请打断他们,尝试向他们解释敏捷并不是一个“速度游戏”,而是应该强调敏捷是一个“或许能够快速运转的质量游戏”。
  Tim Ottinger曾今写过关于敏捷团队进度的14个奇怪观点,其中一个观点中就提到了质量和速度之间的关系。
  尽管大家通常会降低质量要求以求在较短时间内尽快完成工作,但是如果团队所开发的代码质量不高的话,经过全部sprint迭代后的进度最终都还是会被降低。
  Stephen Haunts在他的题目为进度并不是目标或者目的博客帖子中,描述了当管理者设定团队的进度目标后对质量会产生什么影响:
  (…)为了增加交付的功能点数目以满足绩效目标,团队会牺牲掉系统的质量,但从长远来看这样最终还是会降低团队的进度,并且会引入技术隐患。敏捷团队最好关注正在开发系统的质量与流程过程(持续交付和集成等等),以及负责开发系统的团队成员本身。
  软件开发者必须在进度和质量之间掌握平衡,正如Blake Haswell在文章什么是代码质量中解释的那样:
  虽然经常会有很多的外部压力向进度方面倾斜,但是如果你不够重视质量的话,进度最终还是会趋于缓慢以及停滞,以至最终整个项目走向颠覆。考虑到一个项目的代码质量决定了它能够在多大程度上适应需求的变化,一个可以持续改进的事情是你需要花费一部分时间来优化自己项目的代码质量。
  Blake提供了一个可以用来检查代码质量的属性列表:
  可理解性: 代码需要在各个层面上能够被容易地理解。理想情况下,软件应该非常简单,并没有非常明显的缺陷。
  可测试性: 代码需要被编写的非常容易被测试。
  正确性: 代码需要满足功能和非功能性的需求。
  有效性: 代码需要有效的使用系统资源(内存,CPU,网络连接,等)。
  Hugo Baraúna在他的博客文章名为内部质量低下软件的症状中解释了软件是如何因为变更而“变得更糟”的,最终导致质量低下并且降低进度。
  假如你正在领导一家创业公司的技术或者产品团队,你是首席技术官,并且已经推出了你们产品的第一个版本,做的还挺成功的。你们的业务模型已经得到了验证,现在你们正处于快速发展期。这真是太棒了!但这也是有代价的,它带来了一系列新的挑战。
  你们产品的第一个版本工作的很好,但是代码库却无法满足持续发展的要求。或许你的团队进度并没有像以前那样好了,团队成员一直在抱怨代码的质量问题,首席执行官和产品经理想要一些新的功能,但你现在代码规划根本无法满足业务的需求。
  他提供了一个指示质量低下的症状列表,这个列表能够帮助你来决定是否需要重写或者重构:
  所有事情都很艰难
  进度慢
  测试套件运行缓慢
  无法避免的缺陷
  你的团队是消极的
  知识缺乏共享
  新开发人员成长周期太长
  你又是如何平衡质量和进度的呢?

posted @ 2014-12-11 23:37 顺其自然EVO 阅读(684) | 评论 (0)编辑 收藏

Appium Inspector 真机定位元素

对环境的需求:
  iOS
  Mac OSX 10.7+
  XCode 4.5+ 和 Command Line Tools
  npm 0.8 or greater
  Mac OS X 10.7 or higher, 10.8.4 recommended
  XCode >= 4.6.3
  检查一下:
  发现两个网址的说法不同,安全第一,弄个高版本的吧。
  我弄了一个Xcode5.0.2,安装好了以后,继续安装Command Line Tools:
  好了,环境基本上弄好了,看看别人的帖子说法:
  1、安装node.js
  2、安装appium
  $ npm install -g appium@0.12.3
  注意appium的版本和os的兼容。
  3、启动appium
  $appium &
  真机上测试,启动时指定设备的UUID
  $appium -U xxxxxxxxxxxxxxxxxxxxxxxxxx
  appium启动服务的参数详细:
  https://github.com/appium/appium/blob/master/docs/server-args.md
 4、真机上运行,被测app必须是Developer版本。
  再看看官方网页的说法:
  npm install -g appium
  npm install wd
  appium &
  node your-appium-test.js
  哇,好简单呀!想得美,会者不难而已。
  开始吧:
  需要先安装一个node,不过我的机器上没有brew所以还得先安装一下brew,brew类似于ubuntu下面的apt-get,就是用做联网搜软件然后帮你安装上的一个管理工具,哎呀,这种描述好粗糙,能明白我的意思就行了 ^_^,先搜了一个方法:
  cd /usr/local
  mkdir homebrew
  cd homebrew
  curl -LsSf http://github.com/mxcl/homebrew/tarball/master | tar xvz -C/usr/local --strip 1
  cd bin
  ./brew -v
  file brew
  sudo ./brew update
  more brew
  自己做了一遍,大致是这个步骤,顺利安装上了:
  admins-Mac:local admin$ cd bin
  admins-Mac:bin admin$ ./brew -v
  Homebrew 0.9.5
  admins-Mac:bin admin$ file brew
  brew: POSIX shell script text executable
  cd
  vi .bash_profile
  export PATH=/usr/local/homebrew/bin:$PATH
  关闭后重新打开terminal,使.bash_profile被执行,使得PATH环境变量生效,当然你也可以source ./.bash_profile
  在这个安装的过程中,唯一需要注意的是权限,我的作法是在所有步骤之前直接把/usr/local目录都改为了admin所有,就不用每次安装都用sudo来搞了
  sudo chown -Rf admin:staff /usr/local
  这下安装node.js就简单了,一行命令:
  brew install node
  然后就是看看node安装的对不对,先vi hello_world.js,输入以下内容(假定你会用vi,vim一类的编辑器)
  var sys = require('sys'),
  http = require('http');
  http.createServer(function(req, res) {
  setTimeout(function() {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write('Hello World');
  res.end();//截至最新版 res.close(); 以替换为 res.end();
  }, 2000);
  }).listen(8000);
  执行命令:
  node hello_world.js
  下面这样浏览器返回了Hello World字样就是成功了。
  最后检查一下:
  node -v
  v0.10.15
  npm -v
  1.4.6
  好了,全齐了。这下该正事了:
  npm install -g appium
  npm install wd
  运行appium-doctor来检查一下appium是不是都彻底ok了:
  admins-Mac:bin admin$ pwd
  /usr/local/bin
  admins-Mac:bin admin$ ls -l
  total 39064
  lrwxr-xr-x  1 admin  staff        40 Apr 14 16:33 appium -> ../lib/node_modules/appium/bin/appium.js
  lrwxr-xr-x  1 admin  staff        47 Apr 14 16:33 appium-doctor -> ../lib/node_modules/appium/bin/appium-doctor.js
  lrwxr-xr-x  1 admin  staff        47 Apr 14 16:33 authorize_ios -> ../lib/node_modules/appium/bin/authorize-ios.js
  -rwxrwxr-x  1 admin  staff       813 Apr 14 08:53 brew
  -rwxr-xr-x  1 admin  staff  19975968 Jul 26  2013 node
  lrwxr-xr-x  1 admin  staff        38 Jul 31  2013 npm -> ../lib/node_modules/npm/bin/npm-cli.js
  lrwxr-xr-x  1 admin  staff        33 Jul 31  2013 weinre -> ../lib/node_modules/weinre/weinre
  因为这台mac上没有android环境,所以报错,我也没打算在这台mac上测试android程序,所以不用搭理。Appium已经OK了。
  启动appium(&的意思是后台执行,不占用窗口):
  admins-Mac:appium admin$ appium &
  [1] 1886
  admins-Mac:appium admin$ info: Welcome to Appium v0.18.1 (REV d242ebcfd92046a974347ccc3a28f0e898595198)
  info: Appium REST http interface listener started on 0.0.0.0:4723
  info: socket.io started
  info: Non-default server args: {"merciful":true}
  检查进程,顺带删除掉这个后台进程:
  admins-Mac:appium admin$ ps -ef|grep appium
  501  1886  1274   0  4:47PM ttys000    0:00.73 node /usr/local/bin/appium
  501  1892  1274   0  4:48PM ttys000    0:00.00 grep appium
  admins-Mac:appium admin$ kill 1886
  好了,环境部分差不多就这样了。

posted @ 2014-12-11 23:36 顺其自然EVO 阅读(2022) | 评论 (0)编辑 收藏

Appium Inspector 真机定位元素

  自动化测试过程中,对被测试元素的定位是相当重要的。前面文章中也讲到了一些儿定位方法。今天讲解,如何用真机运行程序,用Appium Inspector,UI Automation Viewer来定位App的元素。
  一、Inspector定位
  平时我们定位元素的时候,通常是按下面的方式设置的。
  Device Name填写的是模拟器的名称,启动模拟器,appium后,再启动Inspector就能Reflesh启动App,来进行操作。可是这存在一个问题:模拟器比较慢,而且多少和真机不一样,比如说模拟器不能调出手机键盘等;所以如果我们要做自动化测试的时候,最好还是用真机来运行app,然后进行定位。
  真机运行Inspector的时候也非常简单,首先将手机连接到电脑上。如果有91手机助手或是类似的软件的时候,就会提示是否连接成功!一定要确保连接成功,然后将Device Name替换成手型号,如下所示:
  然后运行appium,启动inspector,就可以在真机上安装并启动App,此时刷新就可以获取最新的Screenshot,左边就能展开对应的分支,你就可以大展拳脚,进行定位了。
  注:用Appium Inspector在真机上运行并定位元素的时候,不管你现在有没有安装这个App,它都会给你重新安装一下,然后再打开,这个是很不爽的。不过运行测试用例的时候,如果有安装,则直接打开,没有安装时才会安装。
  二、UI Automation Viewer定位
  只要你用真机连接上电脑,并运行了要测试的App,打开UI Automation Viewer后,单击“Device Screenshot”按钮,就能刷新出手机上的界面,并能展示定位,如果有任何变动。再次刷新即可。

posted @ 2014-12-11 23:36 顺其自然EVO 阅读(701) | 评论 (0)编辑 收藏

Appium安装教程

 一、适用操作系统
  Win7 旗舰版Sp1 64位操作系统 或 32位操作系统
  二、所需软件
  jdk-7u45-windows-i586.exe
  node-v0.10.28-x86.msi (32位)下载地址:http://nodejs.org/download/
  adt-bundle-windows-x86-20140321.zip
  SDK下载地址:http://developer.android.com/sdk/index.html
  apache-ant-1.9.4-bin.zip ( 非必装) http://ant.apache.org/bindownload.cgi
  apache-maven-3.1.1-bin.zip (非必装) http://maven.apache.org/download.cgi
  ActivePython-2.7.5.6-win32-x86.msi
  三、安装步骤
  1)安装JDK,并进行环境变量配置
  JDK安装很简单,按默认安装即可。
  环境变量配置:
  添加JAVA_HOME变量, 值:Jdk的安装路径,如:D:\Java\jdk1.7.0_45
  添加CLASSPATH变量,值 .;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\lib\dt.jar
  修改path变量,加上这句 %JAVA_HOME%\bin;
  检查JAVA环境是否配置好,进入CMD命令行,输入java或javac,可以看到好多的命令提示,说明成功了。
  2)安装Node.js,按默认安装即可,可以改变安装的路径。
  安装完成以后,检查Node版本安装是否成功:进入CMD,输入node -v, 可以看到版本号,说明成功了。
  3)安装ADT,配置环境变量
  下载地址:http://developer.android.com/sdk/index.html?hl=sk
  下载 adt-bundle-windows-x86-20140321.zip,直接解压即可。
  配置环境变量,设置ANDROID_HOME 系统变量为你的 Android SDK 路径,并把tools和platform-tools两个目录加入到系统的 Path路径里。
  变量名:ANDROID_HOME 值: D:\AutoTest\adt\sdk
  设置Path值: %ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools
  4)联网安装Appium
  进入cmd命令行,输入:
  npm install –g appium 或者
  npm --registry http://registry.cnpmjs.org install -g appium (推荐这种,npm的国内镜像)
  注:-g全局参数
  多等几分钟,可以看到appium的版本1.1.0及安装目录
  5)检查一下appium是否安装成功。
  进入cmd命令行,输入appium
  提示:socket.io started 说明安装好了。
  6)检查appium所需的环境是否OK(这步很重要)
  进入Cmd命令行,输入appium-doctor ,出现以下提示,All Checks were successful ,说明环境成功。
  7)安装Apache Ant (这一步可省)
  安装Apache Ant(http://ant.apache.org/bindownload.cgi)。解压缩文件夹,并把路径加入环境变量。
  变量: ANT_HOME 值: D:\AutoTest\ant-1.9.4
  设置Path: %ANT_HOME%\bin;
  测试Ant是否安装成功,进入cmd命令行:输入ANT,如果没有指定build.xml就会输出:Buildfile: build.xml does notexist! Build failed
  8)安装Apache Maven (这一步可省)
  下载Maven(http://maven.apache.org/download.cgi),并解压缩文件夹,把路径加入环境变量。
  变量M2_HOME 值:D:\AutoTest\maven-3.1.1
  设置Path: %M2_HOME%\bin;
  测试Maven是否成功,运行cmd,输入mvn -version如果成功,则出现maven版本等环境信息。
  安装:python+webdriver环境
  第一步:安装active-python,双击可执行文件,直接默认安装即可。
  第二步:安装selenium webdriver
  1. 打开cmd
  2. 命令为:pip install selenium -i http://pypi.douban.com/simple (使用国内地址)
  3. 打开python的shell或者IDEL界面 ,输入from selenium import webdriver 如果不报错那就说明你已经安装selenium for python成功了。
  4. 安装appium-python-client:(这步很重要,必须)
  进入cmd,输入:pip install Appium-Python-Client
  以上全部安装好以后,最后就是执行实例来测试一下:
  1. 打开Adt,创建一个模拟器,并启动android模拟器。
  2. 在cmd启动appium
  输入:appium
  3. 另开一个cmd终端窗口。切换到实例代码路径下,执行android_contacts.py文件。
English »
 
Text-to-speech function is limited to 100 characters

posted @ 2014-12-11 23:34 顺其自然EVO 阅读(599) | 评论 (0)编辑 收藏

Appium框架中Android下EditText内容清除

在做手机自动化测试过程中 ,难免会对EditText的内容进行修改,通常我们对EditText输入 内容的时候,用的是Send_key()函数。可是这个函数不会先清除原来的内容,只会在光标当前位置上输入函数参数中的数据。如果我们需要修改,必须清除原来的内容,查看了一下clear()参数不好使用,只好去网上搜索了。
  找到了如下方法:
  “首先 clear(), send_keys(), set_text(),在android上不太好用是个已知的bug (在IOS上不清楚,没有测试环境),会在Appium 1.2.3上修复。请参见github的issue:https://github.com/appium/python-client/issues/53
  在这之前我们可以用 press_keycode的方式实现删除,删除速度比忽略 clear()抛出的异常要快很多。
  大概思路是:
  1. 点击要清除的edit field
  2. 全选
  3. 删除
  element.click()
  sleep(1)   #waiting for 1 second is important, otherwise 'select all' doesn't work. However, it perform this from my view
  self.driver.press_keycode(29,28672)   # 29 is the keycode of 'a', 28672 is the keycode of META_CTRL_MASK
  self.driver.press_keycode(112)   # 112 is the keycode of FORWARD_DEL, of course you can also use 67“
  我试了一下上面的方法,没有什么效果,只好继续寻找了。搜了好多网页,在一个网页上看到了一个不错的办法,不过可以打开的网页太多了,一忙忘记是哪儿个网页了。具体的方案就是:
  先将光标移到文本框最后,然后取一下EditText中文本的长度,最后一个一个地删除文本。
  具体示例如下:
  def edittextclear(self,text):
  '''
  请除EditText文本框里的内容
  @param:text 要清除的内容
  '''
  DRIVER.keyevent(123)
  for i in range(0,len(text)):
  DRIVER.keyevent(67)
  使用实例:
  adr=DRIVER.find_element_by_id('com.subject.zhongchou:id/edit_person_detailaddress') #找到要删除文本的EditText元素
  adr.click()#激活该文本框
  context2=adr.get_attribute('text')#获取文本框里的内容
  self.edittextclear(context2)#删除文本框中是内容

posted @ 2014-12-11 23:33 顺其自然EVO 阅读(2344) | 评论 (0)编辑 收藏

JUnit:Hamcrest的使用

hamcrest 是一款比较不错的 JUnit 测试 jar 包,本文介绍 hamcrest 在 Java 语言的使用。
  如果你使用过 eclipse 和 JUnit4 的话,hamcrest 的使用会让你如虎添翼。
  1. 下载hamcrest
  连接 Google,搜索 hamcrest 即可。
  下载列表:http://code.google.com/p/hamcrest/downloads/list
  选择 Full Hamcrest distribution 版本,完整版。如果是在 linux 下面,可以下载tgz格式的。
  win 下面下载 zip 吧。其他系统的可以根据情况下载。
  2. 解压缩
  tar   -zxvf   ×××.tgz
  解压之后,将文件夹放到合适的目录下面。假设路径为 /home/mark/tools/hamcrest-1.2
  3. hamcrest 与 Eclipse
  假设你已经新建一个测试项目叫 TestHamcrest,并且已经导入了 JUnit4 这个包。
  如果没有的话,请参考其他关于 JUnit 的使用的文章
  在 Eclipse 中,对项目 TestHamcrest 右键,选择 Build Path / Add External Archives。
  选择 /home/mark/tools/hamcrest-1.2 下面的 hamcrest-core-1.2.jar、hamcrest-library-1.2.jar 两个 jar 文件。
  项目中可以:
  import static org.hamcrest.Matchers.*;
  那么,就可以直接使用其中的方法。更多关于 hamcrest 的使用,请参阅文档!
  4. 遇到麻烦
  trouble:    SecurityException 异常
  methond:删除 JUnit 包,然后在 Referenced  Library 中再导入 Junit 包。

posted @ 2014-12-11 23:32 顺其自然EVO 阅读(452) | 评论 (0)编辑 收藏

仅列出标题
共394页: 上一页 1 2 3 4 5 6 7 8 9 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜