因为我们专业,所以我们用Auto Build,所以我们用CI系统。

代码管理使用SVN,自动编译使用Ant,而持续集成使用Hudson,操作系统使用Ubuntu10.04。

1. 安装

1.1 安装JDK

      sudo apt-get install sun-java6-jdk

1.2 安装Ant

      sudo apt-get install ant-optional

1.3 安装Hudson

      sudo apt-get upgrade
      wget -O /tmp/key http://hudson-ci.org/debian/hudson-ci.org.key
      sudo apt-key add /tmp/key
      wget -O /tmp/hudson.deb http://hudson-ci.org/latest/debian/hudson.deb
      sudo dpkg --install /tmp/hudson.deb

1.4 安装Android SDK

      http://androidappdocs.appspot.com/sdk/index.html

2. Project配置

2.1 build.xml

http://androidappdocs.appspot.com/guide/developing/other-ide.html

按照官方的做法,使用自动生成的build文件就可以了。

<?xml version="1.0" encoding="UTF-8"?>
<project name="test-android">

    <!-- The local.properties file is created and updated by the 'android' tool.
         It contains the path to the SDK. It should *NOT* be checked in in Version
         Control Systems. -->
    <property file="local.properties" />

    <!-- The build.properties file can be created by you and is never touched
         by the 'android' tool. This is the place to change some of the default property values
         used by the Ant rules.
         Here are some properties you may want to change/update:

         application.package
             the name of your application package as defined in the manifest. Used by the
             'uninstall' rule.
         source.dir
             the name of the source directory. Default is 'src'.
         out.dir
             the name of the output directory. Default is 'bin'.
 
         Properties related to the SDK location or the project target should be updated
          using the 'android' tool with the 'update' action.

         This file is an integral part of the build system for your application and
         should be checked in in Version Control Systems.
   
         -->
    <property file="build.properties" />

    <!-- The default.properties file is created and updated by the 'android' tool, as well
         as ADT.
         This file is an integral part of the build system for your application and
         should be checked in in Version Control Systems. -->
    <property file="default.properties" />

    <!-- Custom Android task to deal with the project target, and import the proper rules.
         This requires ant 1.6.0 or above. -->
    <path id="android.antlibs">
        <pathelement path="${sdk.dir}/tools/lib/anttasks.jar" />
        <pathelement path="${sdk.dir}/tools/lib/sdklib.jar" />
        <pathelement path="${sdk.dir}/tools/lib/androidprefs.jar" />
        <pathelement path="${sdk.dir}/tools/lib/apkbuilder.jar" />
        <pathelement path="${sdk.dir}/tools/lib/jarutils.jar" />
    </path>

    <taskdef name="setup" classname="com.android.ant.SetupTask" classpathref="android.antlibs" />

    <!-- Execute the Android Setup task that will setup some properties specific to the target,
         and import the build rules files.

         The rules file is imported from
            <SDK>/platforms/<target_platform>/templates/android_rules.xml

         To customize some build steps for your project:
         - copy the content of the main node <project> from android_rules.xml
         - paste it in this build.xml below the <setup /> task.
         - disable the import by changing the setup task below to <setup import="false" />

         This will ensure that the properties are setup correctly but that your customized
         build steps are used.
    -->
    <setup />

</project>

2.2 local.properties

这个配置文件定义了Android SDK的位置
sdk.dir=${tool.android.sdk}

2.3 build.properties

这个文件里面定义了App的Package,以及生成App签名必须用的一些配置。

application.package=test.android
key.store=../test-android.keystore
key.alias=test-android
key.store.password=password
key.alias.password=password

3. Hudson配置

3.1 System Configuration

系统配置很简单,只需要配置JDK、Ant的位置就可以了。

比较有用的还有一项:E-mail Notification,如果你需要在build失败发送邮件的话,那么需要配置这一项。

3.2 Job Configuration

3.2.1 Source Code Management

1. 选择Subversion,并且设置好SVN的地址以及用户名、密码

2. 把Use update和Revert勾选上

3.2.2 Build Triggers

1. 勾选上Build Periodically,然后设置自动Build的时机,这里语法跟cron的语法是一样的。

例如:0 2 * * 1-6

2. 勾选上Poll SCM,设置每隔多长时间检测SVN的变更。

例如:0,15,30,45 9-23 * * 1-5

3.2.3 Build

Step1:删除上次编译的文件

rm –f test-android.keystore
rm –f –R ./test-android/gen
rm –f –R ./test-android/bin

Step2:生成Keystore

http://androidappdocs.appspot.com/guide/publishing/app-signing.html

例如:keytool -genkey -v -alias test-android -keyalg RSA -keysize 2048 -dname 'CN=xxx, OU=xxx, O=xxx, L=xxx, ST=xxx, C=xx' -validity 10000 -keypass password -storepass password -keystore 'test-android.keystore'

Step3:Invoke Ant

设置Targets:release –Dsdk.dir=$your-sdk-dir

例如:release –Dsdk.dir=/home/build/android-sdk-linux

3.2.3 Post-build Actions

1. 勾选上Archive the artifacts,设置Files to archive:test-android/bin/test-android-release.apk

2. 勾选上E-mail Notification,可以设置发送邮件的对象和时机

 

经过以上步骤的设置,大功告成了。

专业就是这么简单!!!

http://www.verycd.com/topics/2837883/

内容很不错的,建议初学者看看啊。

有人玩手机版的World War吗?我现在17级,求同盟,一起干美国!!!

列表(ListView)、表格(GridView),这在手机应用上面肯定是少不了的,怎样实现比较复杂一点的界面呢,先看一下我的效果图。

image image

这样布局的情况是最基本的,也是最常用的,网上关于这样的布局有多种版本的实现方法,但是有很多需要自己实现Adapter,那样子是比较复杂而且没有必要的,因为我们有简约而不简单的SimpleAdapter。

1. ListView

SimpleAdapter的核心代码:

		for (int i = 0; i < 10; i++) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("PIC", R.drawable.pic);
			map.put("TITLE", "Test Title");
			map.put("CONTENT", "Test Content");
			contents.add(map);
		}
		SimpleAdapter adapter = new SimpleAdapter(this,
				(List<Map<String, Object>>) contents, R.layout.listitem,
				new String[] { "PIC", "TITLE", "CONTENT" }, new int[] {
						R.id.listitem_pic, R.id.listitem_title,
						R.id.listitem_content });

		listView.setAdapter(adapter);

 

listitem的Layout:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_width="fill_parent" android:layout_height="?android:attr/listPreferredItemHeight">
	<ImageView android:id="@+id/listitem_pic"
		android:layout_width="wrap_content" android:layout_height="fill_parent"
		android:layout_alignParentTop="true" android:layout_alignParentBottom="true"
		android:src="@drawable/pic" android:adjustViewBounds="true"
		android:padding="2dip" />
	<TextView android:id="@+id/listitem_title"
		android:layout_width="wrap_content" android:layout_height="wrap_content"
		android:layout_toRightOf="@+id/listitem_pic"
		android:layout_alignParentRight="true" android:layout_alignParentTop="true"
		android:layout_above="@+id/listitem_content"
		android:layout_alignWithParentIfMissing="true" android:gravity="center_vertical"
		android:text="@+id/listitem_title" android:textSize="22px" />
	<TextView android:id="@+id/listitem_content"
		android:layout_width="fill_parent" android:layout_height="wrap_content"
		android:layout_toRightOf="@+id/listitem_pic"
		android:layout_alignParentBottom="true"
		android:layout_alignParentRight="true" android:singleLine="true"
		android:ellipsize="marquee" android:text="@+id/item_content"
		android:textSize="14px" />
</RelativeLayout>

 

 

2. GridView

SimpleAdapter的核心代码:

		for (int i = 0; i < 10; i++) {
			Map<String, Object> map = new HashMap<String, Object>();
			map.put("PIC", R.drawable.pic);
			map.put("TITLE", "Test Title");
			contents.add(map);
		}
		SimpleAdapter adapter = new SimpleAdapter(this,
				(List<Map<String, Object>>) contents, R.layout.griditem,
				new String[] { "PIC", "TITLE" }, new int[] { R.id.griditem_pic,
						R.id.griditem_title, });

		gridView.setAdapter(adapter);


griditem的Layout:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
	android:layout_height="fill_parent" android:layout_width="fill_parent"
	android:orientation="vertical">
	<ImageView android:id="@+id/griditem_pic"
		android:layout_width="wrap_content" android:layout_height="wrap_content"
		android:layout_gravity="center_horizontal">
	</ImageView>
	<TextView android:id="@+id/griditem_title"
		android:layout_width="wrap_content" android:layout_height="wrap_content"
		android:layout_gravity="center_horizontal" android:text="test">
	</TextView>
</LinearLayout>

 

最后附上代码:http://files.cnblogs.com/game-over/test.zip

1. App installation on external storage media   把应用安装在外部存储器(SD卡)

http://androidappdocs.appspot.com/guide/appendix/install-location.html

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    android:installLocation="preferExternal"
    ... >

2. Data backup  用户数据备份

http://androidappdocs.appspot.com/guide/topics/data/backup.html

<manifest ... >
    <application android:label="MyApplication"
                 android:backupAgent="MyBackupAgent">
        <activity ... >
            ...
        </activity>
    </application>
</manifest>

3. Graphics 增强了图形处理的功能,特别是3D性能得到大幅度提升

4. Media

5. Speech recognition and third-party recognition engines

  • The platform provides new speech-recognition APIs that allow applications to have a richer interaction with the available voice recognizer. For example, the APIs are sufficient to integrate voice recognition deeply into an IME.
  • The platform also provides a RecognitionService base class that lets third-party developers create plug-in recognition engines.
  • New RecognitionListener interface to receive callbacks.
  • New RecognizerIntent extras that let a requester app specify details as preferred language, minimum length in milliseconds, and so on.

6. Camera and camcorder

 

7. Device policy manager

New device policy management APIs allow developers to write "device administrator" applications that can control security features of the device, such as the minimum password strength, data wipe, and so on. Users can select the administrators that are enabled on their devices. For more information, see the android.app.admin classees or the example application code inDeviceAdminSample.java.

8. UI Framework
  • New UI modes "car mode" and "night mode" and UiModeManager let applications adjust their application UI for specific user modes.
  • New ScaleGestureDetector that lets Views detect and handle transformation gestures that involve more than one pointer (multitouch) using the supplied MotionEvents.
  • Improvements in the way that multitouch events are reported in MotionEvent objects.
  • The layout attribute fill_parent is renamed to match_parent. This affects both XML and Java code (seeViewGroup.LayoutParams). Note that the platform will continue to honor uses of fill_parent in legacy applications.
  • New layout attributes tabStripEnabled, tabStripRight, and tabStripLeft let developers customize the bottom strip of TabWidgets.
  • Better support for managed dialogs in Activity.
9. Accounts and sync
  • New method AddPeriodicSync() lets you schedule a periodic sync with a specific account, authority, and extras at the given frequency.
10. New manifest elements and attributes
  • For specifying the application's preferred install location (see App Installation on External Storage Media, above):
    • New android:installLocation attribute of the <manifest> element. Specifies the default install location defined by an application.
  • For managing user data backup (see Backup manager, above, for more information):
    • New android:backupAgent attribute of the <application> element. Specifies the component name of the BackupAgent subclass provided by the application to handle backup/restore operations, if any.
    • New android:restoreAnyVersion attribute of the <application> element. Boolean value that indicates whether the application is prepared to attempt a restore of any backed-up dataset, even if the backup is apparently from a newer version of the application than is currently installed on the device.
  • For managing the platform's JIT compiler:
    • New android:vmSafeMode attribute of the <application> element. Boolean value that specifies whether to disable JIT compiler optimizations when running the application.
11. Permissions
  • android.permission.BIND_DEVICE_ADMIN — Any device administration broadcast receiver must require this permission, to ensure that only the system can interact with it.
  • android.permission.KILL_BACKGROUND_PROCESSES — Allows an application to callkillBackgroundProcesses(String).
  • android.permission.BIND_WALLPAPER — Any WallpaperService must require this permission, to ensure that only the system can interact with it.
  • android.permission.SET_TIME — Allows an application to set the system time.

如何在JMeter中使用外部数据,JMeter也提供了一系列元件,大多包含在配置元件中,例如:CSV Data Set Config,Random Variable,用户定义的变量等,另外,前置处理器 >> 用户参数也可以使用自定义的变量。

我这里着重介绍用户参数和CSV Data Set Config的使用方法。

用户参数可以给测试计划或者测试计划中的每个线程设置参数,如果设置的参数比线程数少的话,这些参数就会被重复利用。

继续以Google为例,如果你想用不同的关键字来搜索,可以在用户参数中作如下设置:

1. 右键单击[线程组],添加 >> 前置处理器 >> 用户参数,在用户参数元件中添加5个用户。然后再添加一个变量[keyword],5个用户对应的值可以随便填写。

设置用户参数

2. 设置[线程组]的线程数为5

3. 修改脚本中名称为/search的请求。把名称为[q]的字段的值修改为${keyword}

用户参数

 

用户参数也可以读取CSV文件,上面的例子如果改为读取CSV的话,则需要

1. 在ApacheJMeter.jar的同级目录下新建一个文件,keyword.txt,其中内容是每一行一个关键字

2. 设置[线程组]的线程数为5

3. 如下图设置用户和变量,名称为keyword,用户_1是${_StringFromFile(keyword.txt)}

设置用户参数2

4. 修改脚本中名称为/search的请求。把名称为[q]的字段的值修改为${keyword}

做完上述操作后,点击运行 >> 启动,就会看到JMeter右上角的线程数从0升到5,执行完后,又变成0

注意点:在一般情况下,线程数和用户参数中定义的变量数是相同的,除非你有特殊的需要

 

我一般使用用户参数定义一些很重要的常量,像读取大规模数据这样的,我们可以使用CSV Data Set Config。CSV Data Set Config默认是读取指定的CSV文件中的数据,每个线程会按照顺序使用其中一条数据,如果线程数比实际数据多的话,数据则按顺序会被重复利用。

1. 右键单击[线程组],添加 >> 配置元件 >> CSV Data Set Config,设置Filename为CSV文件的存放路径,Variable Names就是变量名,设置为keyword,Delimiter一般就是逗号了,四个选框一般就是按照下图设置即可

CSV

2. 设置[线程组]的循环次数为永远,线程数为1

3. 修改脚本中名称为/search的请求。把名称为[q]的字段的值修改为${keyword}

做完上述操作后,点击运行 >> 启动,就会看到JMeter右上角的线程数从0升到1,执行完后,又变成0

 

当然了,我的例子比较简单,有一个稍微复杂一点,而且经常用到的情况就是用户名、密码的组合。在大数据量测试的时候,因为涉及到缓存等的问题,不可能都用同一个用户来执行操作,所以要用很多用户来执行,这个时候CSV Data Set Config就很有用;或者是在进行数据插入的时候,也是很有用的。

 

怎样利用外部数据已经晓得了,但是怎样确认每个线程执行的都是我们定义好的关键字呢?

有多种方法,可以使用监听器,也可以使用断言,这两种元件留到以后再做介绍。

JMeter的中文资料不是很多,我Google了一下,发现基本上没有介绍如何一步步使用的资料。我这里就先整理一下。

大概就是以下几个方面:

  1. 录制脚本
  2. 使用用户自定义参数
  3. 使用控制器
  4. 使用定时器
  5. 使用前置后置处理器
  6. 使用监听器

我也只是入门级别,所以写出来的东西可能比较简单,适合新手参考使用。

这次就介绍使用HTTP代理服务器进行脚本的录制。

JMeter可以录制脚本,也可使用别的工具,如Badboy录制适合JMeter使用的脚本,我们默认使用JMeter自带的功能。

打开JMeter,在工作台节点点击右键,添加 >> 非测试元件 >> HTTP代理服务器,使用默认设置即可。

HTTP代理服务器

然后设置浏览器,把代理服务器设置为127.0.0.1:8080。

Firefox代理

 

 

然后启动HTTP代理服务器,以打开Google为例,它生成的脚本如下:

Google1

它把许多JS、CSS、PNG、GIF的路径都录制了进来,而这些对于测试脚本是没有用处的,我们可以在HTTP代理服务器的排除模式设置,不记录这些。

排除模式

设置完排除模式,重新启动HTTP代理服务器,再次打开Google的首页,发现录制完的脚本简洁多了。

以搜索“JMeter”为例,录制完的脚本是这样的:

Google2

在一些用到JS很多的网页中,JS的动作也会被录制进来,像其中的/complete/search是输入提示框JS的动作,可以删掉的。

JMeter的脚本录制就是这样,另外还可以利用别的工具,例如Badboy,它的使用更加简单,具体可以参考官方网站http://www.badboy.com.au/.

最后,在设置HTTP代理服务器的时候,有两个地方需要注意:

  1. 要确认8080端口是否有冲突,被别的程序,例如Web服务器占用。如果有冲突,可以更改为别的没有冲突的端口
  2. JMeter HTTP代理服务器的端口和浏览器设置的端口要一致

昨天注册了人间网围脖服务,我感觉融合了Google Wave、豆瓣等诸多Web2.0网站的创意,目前没有开放注册,可以点击这个邀请链接。

我的绝技

http://v.youku.com/v_show/id_XMTQ0NDU0MjA0.html

压力测试以软件响应速度为测试目标,尤其是在较短时间内大量并发用户的同时访问时,软件的性能和抗压能力。

JMeter是一款开源的压力测试工具,目前最新Release版本是2.3.4,它不仅可以测试Web服务器,还可以测试数据库、JMS、Web Service、LDAP、JUNIT 等多种对象的测试能力。下载地址:http://jakarta.apache.org/site/downloads/downloads_jmeter.cgi

下面简单介绍一下JMeter。

测试计划

  • 测试计划是测试的起点,其他所有组件的容器。
  • 线程组是用来模拟用户并发的组件。JMeter的每个任务都是用线程来处理的。线程组主要有三个属性,线程数、Ramp-up Period和循环次数。线程数就是并发的数量,Ramp-up Period表示在多长时间内创建线程数中定义的所有线程。
  • 逻辑控制器可以组织取样器,做出复杂的测试用的请求。
  • 配置元件中主要配置取样器中所需要的配置。
  • 定时器设置请求间的时间间隔。
  • 前置处理器一般用来修改请求(Request)。
  • Sampler(取样器),主要的执行组件。每一个取样器都可以被监听器监听,并生成测试结果。
  • 后置处理器一般用来出来返回的数据(Response)。
  • 断言,判断取样器是否正常工作。
  • 监听器,收集整理测试结果,并可以指定格式生成XML、CSV等形式的文件。

工作台

工作台中可以添加非测试元件,其中一个最重要的就是HTTP代理服务器。

HTTP代理服务器可以用来录制测试脚本。将浏览器的代理服务器设置为127.0.0.1:8080,然后启动JMeter的HTTP代理服务器,就可以录制在浏览器中进行的操作。HTTP代理服务器可以设置包含模式和排除模式,我一般用排除模式来排除一些CSS、JS、GIF、PNG之类的。

JMeter的基本元件就是这样,这些元件具体怎么运用请期待下一篇!