qileilove

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

Selenium2.0功能测试之设置浏览器大小

设置浏览器的大小有什么用处呢?
  我想是这样的,当我们需要在测试中使用一些第三方的图像或者基于坐标的辅助工具时,就需要我们的浏览器在每次测试的时候处于同一个分辨率的状态,这样在同一个分辨率的情况下进行图片比对以及坐标的点击操作。 举一个例子:如果用Selenium操作带有Flash插件的页面,就需要借助第三方的Sikuli工具进行图形化的比对操作(具体怎么操作以后有机会在说吧,内容有点复杂),这样为了保证分辨率一致最大化浏览器肯定就是最简单省力的方案了:
  最大化浏览器:
package org.coderinfo.demo;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class MaximizeBrowser {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize(); //将浏览器设置为最大化的状态
driver.get("http://www.google.com.hk");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
driver.quit();  //彻底退出WebDriver
}
}
  自定义浏览器的大小:
package org.coderinfo.demo;
import org.openqa.selenium.Dimension;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
public class ResizeBrowser {
public static void main(String[] args) {
WebDriver driver = new ChromeDriver();
driver.manage().window().setSize(new Dimension(600, 400)); //将浏览器的大小自定义为600*400
driver.get("http://www.google.com.hk");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
driver.quit();  //彻底退出WebDriver
}
}
相关文章
Selenium2.0功能测试之访问站点及获取页面信息
Selenium2.0功能测试之Close browser

posted @ 2013-10-14 10:19 顺其自然EVO 阅读(4670) | 评论 (0)编辑 收藏

Android性能测试工具 Emmagee

 Emmagee是监控指定被测应用在使用过程中占用机器的CPU、内存、流量资源的性能测试小工具。
  支持SDK:Android2.2以及以上版本
  Emmagee功能介绍
  1、检测当前时间被测应用占用的CPU使用率以及总体CPU使用量
  2、检测当前时间被测应用占用的内存量,以及占用的总体内存百分比,剩余内存量
  3、检测应用从启动开始到当前时间消耗的流量数
  4、测试数据写入到CSV文件中,同时存储在手机
  5、可以选择开启浮窗功能,浮窗中实时显示被测应用占用性能数据信息
  6、在浮窗中可以快速启动或者关闭手机的wifi网络
  Emmagee如何使用?
  1、安装Emmagee应用
  apk下载地址:http://code.google.com/p/emmagee/downloads/list
  2、启动Emmagee,列表中会默认加载手机安装的所有应用
  3、选择你需要测试的应用,点击“开始测试”,被测应用会被启动


  4、开始你的功能测试吧,测试过程中会自动记录相关性能参数
  5、测试完成后回到Emmagee界面,点击“结束测试”,测试结果会保存在手机指定目录的CSV文件中
  生成的CSV文件内容见图:


  6、使用Excel打开CSV文件,使用自带的统计图标功能生成统计图:


posted @ 2013-10-14 10:17 顺其自然EVO 阅读(382) | 评论 (0)编辑 收藏

Android下junit单元测试、logCat的使用

 Android下junit单元测试
  软件测试小知识:
  根据测试是否知道源代码:
  黑盒测试:只关心程序执行的过程和结果
  白盒测试:根据源代码写测试方法或者测试用例
  根据测试的粒度:
  方法测试:function test
  单元测试:unit test
  集成测试:intergration test
  根据测试的次数:
  冒烟测试:smoke test(android 猴子)
  压力测试:prssure test
  Android单元测试:
  1.Android测试类要继承AndroidTestCase类
  2.写测试方法,在测试方法内使用断言assert来测试要测试的方法
  3.在AndroidManifest.xml中,要设置
  <instrumentation
  android:name="android.test.InstrumentationTestRunner"
  android:targetPackage="com.lee.test" />
  和<uses-library android:name="android.test.runner" >
  4.确保adb连接正常。
  MyService.java

package com.lee.test.service;

public class MyService {

 /**
  * 计算器相加的业务
  * @param a
  * @param b
  * @return
  */
 public int add(int a,int b){
  return a+b;
 }
}



 TestMyService.java
package com.lee.test.service.test;
import com.lee.test.service.MyService;
import android.test.AndroidTestCase;
public class TestMyService extends AndroidTestCase {
/**
* add方法的测试代码
* 把异常抛给测试框架
* @throws Exception
*/
public void testAdd()throws Exception{
MyService myService = new MyService();
int retVal = myService.add(3, 5);
//断言,预期结果是8,实际结果是retVal
assertEquals(8, retVal);
}
}
package com.lee.test.service.test;
import com.lee.test.service.MyService;
import android.test.AndroidTestCase;
public class TestMyService extends AndroidTestCase {
/**
* add方法的测试代码
* 把异常抛给测试框架
* @throws Exception
*/
public void testAdd()throws Exception{
MyService myService = new MyService();
int retVal = myService.add(3, 5);
//断言,预期结果是8,实际结果是retVal
assertEquals(8, retVal);
}
}

  AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lee.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<!-- 这里是进行单元测试必须要添加,指令集必须在manifest节点下 -->
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.lee.test" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.lee.test.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 这里也是进行单元测试必须要添加,在application节点下,使用函数库 -->
<uses-library android:name="android.test.runner" >
</uses-library>
</application>
</manifest>
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lee.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<!-- 这里是进行单元测试必须要添加,指令集必须在manifest节点下 -->
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="com.lee.test" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.lee.test.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- 这里也是进行单元测试必须要添加,在application节点下,使用函数库 -->
<uses-library android:name="android.test.runner" >
</uses-library>
</application>
</manifest>


  logCat的使用
  日志信息是分等级的:
  verbose:提醒  黑色
  debug:调试  蓝色
  info:信息  绿色
  warn:警告  橙色
  error:错误  红色
  使用上面的程序,可以做一个demo
  修改MyService.java

package com.lee.test.service;
import android.util.Log;
public class MyService {
private static final String TAG = "MyService";
/**
* 计算器相加的业务
* @param a
* @param b
* @return
*/
public int add(int a,int b){
Log.v(TAG, ""+a);
Log.d(TAG, ""+b);
Log.i(TAG, ""+b);
Log.w(TAG, ""+a);
Log.e(TAG, ""+b);
System.out.println("System.out的log");
System.err.println("System.err的log");
return a+b;
}
}
package com.lee.test.service;
import android.util.Log;
public class MyService {
private static final String TAG = "MyService";
/**
* 计算器相加的业务
* @param a
* @param b
* @return
*/
public int add(int a,int b){
Log.v(TAG, ""+a);
Log.d(TAG, ""+b);
Log.i(TAG, ""+b);
Log.w(TAG, ""+a);
Log.e(TAG, ""+b);
System.out.println("System.out的log");
System.err.println("System.err的log");
return a+b;
}
}


posted @ 2013-10-14 10:16 顺其自然EVO 阅读(777) | 评论 (0)编辑 收藏

单元测试利器之google test

 一、概述
  gtest是Google开源的一款跨平台的C++单元测试框架,支持自动发现测试、断言集、用户定义的断言、death测试、致命与非致命的失败、类型参数化测试、各类运行测试的选项和XML的测试报告,更多信息请参看官网,也可以参看这里。
  二、安装
  点击这里下载gtest,当前最新的稳定版本是gtest-1.7.0,如下来安装gtest:
  #unzip gtest-1.7.0.zip
  #cd gtest-1.7.0
  #./configure
  #make
  确认lib/.libs目录下生成了libgtest.a和libgtest_main.a,这是测试程序需要链接的两个库。
  三、测试
  下面将举例说明如何应用gtest来做单元测试
  1、被测试程序
  编写被测试程序,在foo.h中编写函数max,求两个数中的大数:
#ifndef __FOO_H__
#define __FOO_H__
int max(int a, int b)
{
return a>b?a:b;
}
#endif
  2、测试程序
  编写测试程序test_foo.cpp来对foo.h进行测试:
#include "gtest/gtest.h"
#include "foo.h"
TEST(foo, max)
{
EXPECT_EQ(2, max(2, 1));
EXPECT_EQ(3, max(2, 3));
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

 3、编译测试
#g++ -g test_foo_cpp -o test_foo \
#-I../gtest-1.7.0/include \
#../gtest-1.7.0/lib/.libs/libgtest.a \
#../gtest-1.7.0/lib/.libs/libgtest_main.a \
#-lpthread
  编译链接生成可执行文件test_foo,执行结果如下:
  4、测试说明
  (1)用TEST宏编写测试用例
  gtest提供了TEST宏来编写测试用例,这个宏有两个参数,这两个参数只是起到提示作用,可以根据需要如下理解或使用:
  (A)第一个参数表示测试用例名称,第二个参数表示测试名称;
  (B)第一个参数表示类名,第二个参数表示方法名;
  (C)第一个参数表示文件名,第二个参数表示函数名。
  比如前面test_foo.cpp中的TEST(foo, max)就是采用的(C)这种方式。
  (2)用EXPECT_*/ASSERT_*宏设置检查点
  gtest提供了一系列EXPECT_*和ASSERT_*宏在测试用例中设置检查点进行检查,EXPECT系列和ASSERT系列宏的区别在于:
  (A)EXPECT_*失败时,用例继续往下执行。
  (B)ASSERT_*失败时,直接在当前函数中返回,当前函数中ASSERT_*后面的语句将不会执行。
  比如前面TEST(foo, max)函数中的语句EXPECT_EQ(2, max(2, 1))用于测试max(2, 1)的执行结果是否等于2,如果不相等,则用例执行失败,否则成功。
  (3)初始化环境变量设置用例
  gtest测试用例允许接收一系列命令行参数以进行一些初始化操作,通常在main函数中调用::testing::InitGoogleTest(&argc, argv)来初始化一些环境变量。
  (4)运行测试用例
  一切准备妥当后,接着就运行所有测试用例以完成单元测试。gtest提供了RUN_ALL_TEST()宏用于调用所有TEST宏编写的测试用例以达到我们的终极目标。

posted @ 2013-10-14 10:16 顺其自然EVO 阅读(585) | 评论 (0)编辑 收藏

Web压力测试系统 nGrinder

  nGrinder是一个基于Grinder开发的一个非常易于管理和使用的性能测试系统。
  它是由一个controller和连接它的多个agent组成,用户可以通过web界面管理和控制测试,以及查看测试报告,controller会把测试分发到一个或多个agent去执行。用户可以设置使用多个进程和线程来并发的执行该脚本,而且在同一线程中,来重复不断的执行测试脚本,来模拟很多并发用户。
  nGrinder的测试是基于一个python的测试脚本,用户按照一定规则编写测试脚本以后,controller会将脚本以及需要的其他文件分发到agent,用Jython执行。并在执行过程中收集运行情况、响应时间、测试目标服务器的运行情况等。并保存这些数据生成运行报告,以供以后查看。
  nGrinder的一大特点就是非常容易使用,安装也非常容易,可以做到开箱即用,测试用户也可以很容易就开始测试任务。当然,如果想执行一些比较复杂场景的性能测试,就需要测试人员对python有一定认识。

posted @ 2013-10-14 10:14 顺其自然EVO 阅读(365) | 评论 (0)编辑 收藏

如果做好测试项目组管理者

 1 如何认识测试
  测试是一个方法论而不是一个技术论;
  2 软件测试的误区
  * 软件开发完成后进行软件测试;
  *软件质量问题是测试人员的错误,软件发布后如果发现问题,那是软件策划四人员的错;
  *测试技术要求不高比编程容易,随便找一个人就可以完成;
  *测试跟着开发动,有时间就多测试,没时间就少测。
  * 测试是测试人员的事,与开发人员无关;
  软件测试从这里开始
  * 需求测试和设计测试也是软件测试的一种;
  * 软件测试应该涵盖整个软件生命周期。同时软件测试本身也应被测试。
  * 测试要执行所有可能测输入;
  在测试中,穷举测试工作量太大,实践上行不通,一般采用等价类和边界值分析等措施来进行实际的软件测试;
  * 好的测试一定要使用很多的测试工具。
  工具所能发挥的作用依赖于使用工具的人,因此,对工具的过分依赖将降低人的能动性,并最终使测试本身受到损害。适当的使用测试工具能够减轻策划人员的机械性工作,提高工作效率,而滥用工具会降低测试的质量。并不是任何工作都适合自动化的,如何合理的自动化测试,合理的选择适当的测试工具已经是研究人员感兴趣的一个课题。
  3 测试工程师的素质
  3.1基本素质
  沟通能力,自信心,幽默感记忆力,耐心,怀疑精神,自我督促,洞察力;
  广泛的经验;
  表达能力,问题描述能力;
  会提问,会寻求help;
  逻辑思维能力;
  团队协作能力;处理日常事务的能力和处理突发事件的能力;
  3.2基本素质
  对于系统测试,把握需求是第一位,对产品熟练,能够快速熟悉新的产品需求,很强的需求理解能力显得很重要。
  测试基础:明确测试流程中各个阶段的工作,对测试的认知程度,决定了测试流程管理的规范性,测试工作的质量;
  测试方案的分析设计能力,测试案例的设计能力;
  测试工具的使用;
  编程你呢管理,数据库知识,网络知识,操作系统知识;
  团队协作能力,与各个小组之间的沟通能力;
  测试管理,管理决定了工作质量,尤其是测试经理,需要管理团队的测试能力。
  4测试工程师的分类
  测试工程师一般分为两类:测试工具软件开发工程师和软件测试工程师。
  测试工具软件开发工程师主要负责编写测试工具代码,并利用测试工具对软件进行测试,或者开发测试工具为软件测试工程师服务。
  软件测试工程师主要负责理解产品的功能要求,然后对其进行测试,检查软件有没有错误,决定软件是否具备稳定性,并写出想要的测试规范和测试案例。
  按照测试类型分类:功能测试工程师,自动化测试工程师,性能测试工程师等。
  按照测试对象分类:web测试工程师,数据库测试工程师,数据库测试工程师,c/s测试工程师,个人软件测试工程师;
  5测试工作的未来
  bug 预防和早期检测
  因为现在把重点放在产品交付的质量上来,预防实践和静态分析仪这样的检测工具将成为主流。
 第2章软件质量体系
  2.1 软件能力成熟度模型:cmm
  cmm为企业的软件过程能力提供了一个阶级式的进化框架,接替工五级。
  第一级:初始级,第二级:可重复级;第三极:已定义级;第四级:受管理级; 第五级:优化级;
  第二级:可重复级;第三极:已定义级;第四级:受管理级;第五级:优化级;
  初始级:工作方式处于救火状态,不断的应对突如其来的危机;
  工作组:软件开发组,工程组;
  需要建立项目过程管理,建立各种计划,开展qa活动;
  2.2可重复级
  人们总结出软件开发的首要问题不是技术问题而是管理问题。因此第二级的焦点集中在软件管理过程上,一个可管理的过程则是一个可重复的过程,可重复的过程才能逐渐改进和成熟。可重复级的管理过程包括需求管理,项目管理,质量管理,配置管理和子合同管理5个方面
  关注点:引入需求管理,项目管理,质量管理,配置管理,子合同管理;
  引入工作组:测试组,评估组,质量保证组,配置管理组,合同组,文档支持组,培训组;
  2.3 在可重复级定义了管理的基本过程,而没有定义执行的步骤标准。在第三极则要求制定企业范围的工程化标准,并将这些标准集成到企业软件开发标准过程中去,所有开发的项目需求根据这个标准过程,剪裁出与项目适宜的过程,并且按照过程执行,过程的裁剪不是随意的,在使用前必须经过企业有关人员的批准。
  关注点:文档化,标准的一致化;软件过程标准话文档化,质量可以得到控制;工作组:sepg软件评估组。提高:对软件过程定量分析,加强质量管理。
  第三章  软件的生命周期
  3.1 需求管理:
  需求应当具备一下特点:
  完整性:每一项需求都必须将所要实现的功能描述清楚,以使开发人员获得设计和实现这些功能所需的所有必要信息。
  正确性:每一项需求都必须准确滴陈述其要开发的功能。
  一致性:一致性是指与其它软件需求或者高层需求不相矛盾。
  可行性:每一项需求都必须是在已知系统和环境的权能和限制范围内可以实施的。
  无二义性:对所有需求说明的读者都只能有一个明确统一的解释,由于自然语言极易导致二义性,所以尽量巴
  每项需求用简洁明了的用户性的语言表达出来。
  致二义性:所以尽量巴每项需求用简洁明了的用户性的语言表达出来。
  健壮性:需求的说明中是否对可能出现的异常进行分析,并且对这些异常进行了容错出来。
  必要性:可以理解为每项需求都是用来授权你编写文档的根源,要使每项需求都能回溯至某项客户的输入,如use case或者别的来源。
  可测试性:每项需求都能通过设计测试用力或者其他的验证方法来进行测试。
  可修改性:每项需求只应该在srs中出现一次,这样更改时易于保持一致。另外,使用目录表,索引和相互参照列表方法将使软件需求规格说明书更容易修改。
  可跟中性:应能在每项软件需求与他的根源和设计元素,源代码,测试用例之间建立起连接连,这种可跟踪要求每项需求以一种结构化的,粒度好的方式编写单独标明,而不是大段大段的叙述。
  3.2需求建模
  需求的建模包括巴需求转换成图形模型或者形式语言模型。需求的图形化分析模型包括数据流图,实体关系图,状态转换图,对话图,和类图,这些图形化模型一般都需要借助一定的工具,选择好的分析工具应该有助于获得需求质量特性,包括有效性一致性可靠性 可存活性可用性 正确性 可维护行 可测试性  可扩展性 可交互性  可重用性 可携带x带性等。
  3.3审查
  需求必须经过产品经理,软件经理 系统测试组,软件工程组,系统工程组,质量保障组,软件配置管理组,文档支持组等小组审查。
  通过静态手工方法进行需求测试中最常用的手段是同行评审。
  3.4执行
  建议需求文档,分配需求文档 修改需求。
  需求的管理需求在应用领域和软件工程方面经验比较丰富的人来担任。
  建议使用配套的需求管理工具
  除了建立相关的文档,还需要对所有软件工程组人员进行项目应用领域的培训。
  3.5需求变更
  变更审查:
  变更对现有约定的影响;
  提出需求变更引起的后续软件活动变更,评估风险,建立文档,全程跟踪。
  3.6交付工件
  程序陈述和需求说明书;
  需求文档的分类:用户需求cr,技术需求tr,项目需求pr;
  需求的状态:已批准已分配已实现。。
  3.7 软件项目计划
  为软件工程的运作和软件项目获得的管理提供合理的基础和可行的工作计划。
  3.8 设计阶段
  包括功能的描述和设计
  交付工件:设计说明书和功能说明书
  3.9编码阶段
  包括实施源代码,对目标代码进行单元测试
  交付工件:软件,文档和产品信息
  3.91  核实阶段
  包括各种测试行为
  第二节 软件开发过程中常见的问题
  需求说明差
  不切合实际的时间表
  测试不充分
  不断的增加功能
  交流问题
  第三节  流程中的组及工作
  3.31 流程中的组
  系统分析人员
  提出测试需求并跟中,确定测试的对象/方法和范围。
  软件开发人员
  提供开发计划sdp,参与制定和评审测试计划;
  提供软件功能需求规格/需求分析/测试建议等文档,参与制定和评审测试方案和案例;
  响应测试需求,跟踪解决缺陷。
  配置管理人员
  对测试文档测试代码及相关配置项进行配置管理。
  质量保证人员
  质量保证,参与相关评审,由于质量保证和测试关系比较密切,多谢一点
  保障软件组织流程体系得到遵守,促使软件组织过程改进,指导项目实施流程,增加卡发货的透明度,评审项目活动,审核工作产品,协助工作产品问题解决,度量数据采集,分析,提供决策参考,进行缺陷预防,实现质量目标。
  组织和协调产品开发组对标内部的软件技术和开发标准,流程的培训和教育。
  部门的和特定的产品的软件开发过程量,以及软件产品质量的度量
  指出产品开发过程中应该准寻的有关软件开发的标准和流程,并监督开发过程标准和流程的符合度。
  软件质量管理,采用inspection review audit技术
  通过软件开发流程及标准的推行以及对软件开发过程的不断总结和优化,使软件开发过程得到持久不断的优化和提高



第四章  软件测试基础
  4.1.1测试定义:IEEE中对测试的定义:使用人工或者自动手段来运行或者测试某段系统的过程。其目的在于检验他是否满足规定的需求或者是弄清语气结果与实际结果之间的差异。
  4.1.2测试前提
  软件可测试性:是一个计算机程序能够被测试的容易程序。
  软件可测试性检查表:
  可操作性--运行滴越好,被测试的效率越高。
  可观察性--所看见的,就是所测试的。
  可控制性--对软件的控制越好,测试越能够被自动执行与优化。
  可分解性----通过控制测试范围,能够更好滴分解问题,执行更灵巧的在测试。
  简单性--需要测试的内容越少测试的的速度越快。
  稳定性--改变越少,对测试的破坏性越小。
  易理解性--得到的信息越多,进行的测试越灵活。
  4.1.3测试的目的
  目的:发现程序中的错误,提高产品的可靠性。
  4.1.4 测试规律
  规律:木桶原理/八二原则。
  4.1.4.1木桶原理
  产品质量的关键因素是分析,设计和实现,测试应该是溶于其中的补充检查手段,其他管理,支持,甚至文化因素也会影响最终产品的质量,应该说,测试是提高产品质量的必要条件,也是提高产量质量的最直接的最快捷的手段,单绝不是根本手段,反过来说,如果将提高产品质量的却吗全部压在测试上,那将是一个恐怖而漫长的灾难。
  第二节测试生命周期
  4.2.1测试生命周期
  对测试人员进行业务培训
  测试需求分析
  编写测试计划
  编写测试案例
  测试执行
  编写测试报告
  4.2.2流程中的文档
  4.2.2.1测试计划
  测试计划和产品开发紧密相关,有多个部分组成,所以大型的商业软件都需要完整的测试计划,需要具体的每一步骤,并且每一部分都要符合规范要求。
  测试计划包括内容:1,概述;2测试目标和发布标准,3计划将测试的领域,4测试方法描述5测试进度表6测试资源7配置范围和测试工具;
  4.2.2.3测试案例
  测试案例是指描述如何测试某一个领域的文档。这些文档负荷测试规范中的需求说明,根据测试规范的测试想定开发,根据测试反馈信息,对于没有考虑的心问题,不断增加测试案例。测试案例没有固定格式,只要清楚表名了测试步骤和需求验证的事实,使得任何一个测试人员都可以根据测试案例的描述完好成测试。
  测试报告
  测试管理人员以测试报告的形式向整个产品开发部门报告测试结果及发现的缺陷或者错误。撰写测试报告的目的为了让整个产品开发部门了解产品开发的进展情况,以使缺陷或者才错误能够迅速得到修复,测试报告的格式并无定式要求能够完整清楚的翻页当前的测试进展情况 要易懂不要使人迷惑或者产生误解
  4.4.1测试分类
  白盒测试   黑盒测试
  4.4.2黑盒测试的测试用力设计方法:
  等价类化分方法
  边界值分析方法
  错误推测方法
  因果图方法
  判定表驱动分析方法
  正交实验设计方法
  功能图分析方法
  4.4.3系统测试类型
  恢复测试;
  完整>安全>性能测试;
  强度测试
  容量测试
  结构测试
  性能测试
  配置测试
  安装,卸载测试
  用户界面测试
  功能测试
  比较测试
  可移植性
  接口间测试
  数据库测试

posted @ 2013-10-14 10:13 顺其自然EVO 阅读(254) | 评论 (0)编辑 收藏

java使用序列化实现深克隆

public static Object deepClone(Object source) {
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
File file = null;
try {
FileOutputStream fos = new FileOutputStream("objFile");
oos = new ObjectOutputStream(fos);
oos.writeObject(source);
FileInputStream fis = new FileInputStream("objFile");
ois = new ObjectInputStream(fis);
return ois.readObject();
} catch (Exception e) {
System.err.println("对象克隆失败");
e.printStackTrace();
return null;
} finally {
try {
if(null != oos) {
oos.close();
}
if(null != ois) {
ois.close();
}
file = new File("objFile");
if(null != file) {
file.delete();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

posted @ 2013-10-14 10:08 顺其自然EVO 阅读(342) | 评论 (0)编辑 收藏

使用java读写properties文件属性

 自己定义一个属性文件:例如prop.properties
  baseFilePath=D\:/kuanter/resource
  tesx=abcd
  我们要做的第一步就是要将文件读取到Properties类对象中,由于load有一个参数是InputStream,所以我们可以用 InputStream的子类FileInputStream将属性文件读取到Properties对象中,知道prop.properties的路径,我们就用FileInputStream(String name)构造函数:
  Properties prop = new Properties();//属性集合对象
  FileInputStream fis = new FileInputStream("prop.properties");//属性文件流
  prop.load(fis);//将属性文件流装载到Properties对象中
  1.//获取属性值,baseFilePath已在文件中定义
  2.System.out.println("获取属性值:baseFilePath=" + prop.getProperty("baseFilePath"));
  3.//获取属性值,country未在文件中定义,将在此程序中返回一个默认值,但并不修改属性文件
  4.System.out.println("获取属性值:country=" + prop.getProperty("country", "中国"));
  在保存属性集合到文件之前,我们还有一件事情就是如何修改和添加新的属性到属性集合,这里使用了一个方法就是setProperty(String key, String value),这个方法就是当属性集合中存在指定的key时,就修改这个key的值,如果不存在,就新建一个key,同样是通过键值关系保存的,但值得注意的是,Properties类继承自Hashtable,所以也可以用Hashtable的put和putAll方法保存,但强烈反对使用这两个方法,因为它们允许调用方插入其键或值不是 Strings 的项。相反,应该使用 setProperty 方法。如果在“有危险”的 Properties 对象(即包含非 String 的键或值)上调用 store 或 save 方法,则该调用将失败。那好,下面我们就来看看修改、添加和保存属性的程序:
//修改baseFilePath的属性值
prop.setProperty("baseFilePath", "Boxcode");
//添加一个新的属性studio
prop.setProperty("studio", "Boxcode Studio");
//文件输出流
FileOutputStream fos = new FileOutputStream("prop.properties");
//将Properties集合保存到流中
prop.store(fos, "Copyright (c) Boxcode Studio");
fos.close();//关闭流
  在我们知道如何读写一个属性文件之后,我们仍然还有很多需要注意的问题,因为load和store方法都是按照ISO-8859-1的编码方式读写属性流文件的,而ILatin1 的字符和某些特殊字符,而对于非Latin1 的字符和某些特殊字符,则要使用与字符和字符串字面值所用的类似转义序列,以值和元素的形式来表示它们。所以当我们在处理中文时,不可以在直接修改属性文件时,将中文的值赋予给属性,而是要在JAVA程序中通过setProperty方法给属性赋予中文的值,因为这样store会将中文转换成 unicode码,在读取时系统会将读取到的unicode码按系统的编码打印出来,对于中文系统,通常是GBK码,这样中文才能够正常显示。

 具体在项目中的属性文件读写
package TestPropertis;
//import java.io.FileInputStream;
//import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
//import java.net.URL;
import java.util.Properties;
/**
* TODO
* @author admin
* @date 2012-11-22 下午05:17:28
*/
public class ReadWirtePropertis {
public static void main(String[] args) {
Properties pro = new Properties();//属性集合对象
//      URL url = Thread.currentThread().getContextClassLoader().getResource("prop.properties");//获取项目中文件的路径
InputStream path =Thread.currentThread().getContextClassLoader().getResourceAsStream("prop.properties");//获取路径并转换成流
//      try {
//          FileInputStream fis = new FileInputStream("属性文件创建在电脑上");
try {
//              pro.load(fis);//将属性文件流装载到Properties对象中
pro.load(path);
//              fis.close();
System.out.println(pro.getProperty("baseFilePath"));
pro.setProperty("shuzi", "1111");//往属性文件插值
pro.setProperty("shuzi", "222");//更改属性值
System.out.println(pro.getProperty("shuzi"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//      } catch (FileNotFoundException e) {
//          // TODO Auto-generated catch block
//          e.printStackTrace();
//      }
}
}

posted @ 2013-10-14 10:07 顺其自然EVO 阅读(207) | 评论 (0)编辑 收藏

erlang mnesia 数据库基本查询

Mnesia是一个分布式数据库管理系统,适合于电信和其它需要持续运行和具备软实时特性的Erlang应用,越来越受关注和使用,但是目前Mnesia资料却不多,很多都只有官方的用户指南。下面的内容将着重说明 如何做 Mnesia 数据库查询。
  示例中表结构的定义:
  %% 账号表结构
  -record( y_account,{ id, account, password }).
  %% 资料表结构
  -record( y_info, { id, nickname, birthday, sex }).
  1、Select 查询
  查询全部记录
%%===============================================
%%  select * from y_account
%%===============================================
%% 使用 mnesia:select
F = fun() ->
MatchHead = #y_account{ _ = '_' },
Guard = [],
Result = ['$_'],
mnesia:select(y_account, [{MatchHead, Guard, Result}])
end,
mnesia:transaction(F).
%% 使用 qlc
F = fun() ->
Q = qlc:q([E || E <- mnesia:table(y_account)]),
qlc:e(Q)
end,
mnesia:transaction(F).
  查询部分字段的记录
%%===============================================
%%  select id,account from y_account
%%===============================================
%% 使用 mnesia:select
F = fun() ->
MatchHead = #y_account{id = '$1', account = '$2', _ = '_' },
Guard = [],
Result = ['$$'],
mnesia:select(y_account, [{MatchHead, Guard, Result}])
end,
mnesia:transaction(F).
%% 使用 qlc
F = fun() ->
Q = qlc:q([[E#y_account.id, E#y_account.account] || E <- mnesia:table(y_account)]),
qlc:e(Q)
end,
mnesia:transaction(F).

 2、Insert / Update 操作
  mnesia是根据主键去更新记录的,如果主键不存在则插入
%%===============================================
%%    insert into y_account (id,account,password) values(5,"xiaohong","123")
%%     on duplicate key update account="xiaohong",password="123";
%%===============================================
%% 使用 mnesia:write
F = fun() ->
Acc = #y_account{id = 5, account="xiaohong", password="123"},
mnesia:write(Acc)
end,
mnesia:transaction(F).
  3、Where 查询
%%===============================================
%%    select account from y_account where id>5
%%===============================================
%% 使用 mnesia:select
F = fun() ->
MatchHead = #y_account{id = '$1', account = '$2', _ = '_' },
Guard = [{'>', '$1', 5}],
Result = ['$2'],
mnesia:select(y_account, [{MatchHead, Guard, Result}])
end,
mnesia:transaction(F).
%% 使用 qlc
F = fun() ->
Q = qlc:q([E#y_account.account || E <- mnesia:table(y_account), E#y_account.id>5]),
qlc:e(Q)
end,
mnesia:transaction(F).
  如果查找主键 key=X 的记录,还可以这样子查询:
%%===============================================
%%   select * from y_account where id=5
%%===============================================
F = fun() ->
mnesia:read({y_account,5})
end,
mnesia:transaction(F).
    如果查找非主键 field=X 的记录,可以如下查询:
%%===============================================
%%   select * from y_account where account='xiaomin'
%%===============================================
F = fun() ->
MatchHead = #y_account{ id = '_', account = "xiaomin", password = '_' },
Guard = [],
Result = ['$_'],
mnesia:select(y_account, [{MatchHead, Guard, Result}])
end,
mnesia:transaction(F).
  4、Order By 查询
%%===============================================
%%   select * from y_account order by id asc
%%===============================================
%% 使用 qlc
F = fun() ->
Q = qlc:q([E || E <- mnesia:table(y_account)]),
qlc:e(qlc:keysort(2, Q, [{order, ascending}]))
end,
mnesia:transaction(F).
%% 使用 qlc 的第二种写法
F = fun() ->
Q = qlc:q([E || E <- mnesia:table(y_account)]),
Order = fun(A, B) ->
B#y_account.id > A#y_account.id
end,
qlc:e(qlc:sort(Q, [{order, Order}]))
end,
mnesia:transaction(F).


  5、Join 关联表查询
%%===============================================
%%   select y_info.* from y_account join y_info on (y_account.id = y_info.id)
%%      where y_account.account = 'xiaomin'
%%===============================================
%% 使用 qlc
F = fun() ->
Q = qlc:q([Y || X <- mnesia:table(y_account),
X#y_account.account =:= "xiaomin",
Y <- mnesia:table(y_info),
X#y_account.id =:= Y#y_info.id
]),
qlc:e(Q)
end,
mnesia:transaction(F).
  6、Limit 查询
%%===============================================
%%   select * from y_account limit 2
%%===============================================
%% 使用 qlc
F = fun() ->
Q = qlc:q([E || E <- mnesia:table(y_account)]),
QC = qlc:cursor(Q),
qlc:next_answers(QC, 2)
end,
mnesia:transaction(F).
  注:使用qlc模块查询,需要在文件顶部声明“-include_lib("stdlib/include/qlc.hrl").”,否则编译时会产生“Warning: qlc:q/1 called, but "qlc.hrl" not included”的警告。

posted @ 2013-10-14 10:06 顺其自然EVO 阅读(2333) | 评论 (0)编辑 收藏

应用托管在SAE不登录也能通过 phpmyadmin 管理数据库

  需求:在SAE下开发,经常需要手动修改数据库数据,可是老是登录又太麻烦
  准备:假设当前我已经在SAE中有了一个应用: malinjie66.sinaapp.com
  步骤:
  1.下载 phpmyadmin, 版本是 phpMyAdmin-3.3.10.5-all-languages.7z
  2.在SAE应用中, 新建一个版本, 假设是 2, 那么现在把 phpmyadmin 的全部文件上传到该版本. (因为版本1要存放应用的代码, 而管理这个应用的数据库, 又必须是在该应用下, 所以最好的办法是, 新建一个版本啦!)
  3.复制 pma/libraries/config.default.php 的内容到 pma/config.inc.php , 如果不存在则新建之
  4.修改 config.inc.php 某些位置 , 修改后如下:
$cfg['Servers'][$i]['host'] = SAE_MYSQL_HOST_M;
$cfg['Servers'][$i]['port'] = SAE_MYSQL_PORT;
$cfg['Servers'][$i]['user'] = SAE_MYSQL_USER;
$cfg['Servers'][$i]['password'] = SAE_MYSQL_PASS;
$cfg['Servers'][$i]['only_db'] = 'app_malinjie66';  // 你的SAE项目的数据库名称
  5.访问 2.malinjie66.sinaapp.com , 你会发现要求输入数据库用户名和密码!(SAE设置的是常量, 我们当然不知道了!) 那么下一步我们就要打印出这两个常量 
SAE_MYSQL_USER 和 SAE_MYSQL_PASS , 但是为了安全起见, 最好在地址栏加一个密钥验证, 具体做法是: 在index.php 的最开头处写上这几行代码 :
if($_GET['k']=='s0h94huna43hf4jc8geb1tqxt5jn3bg5'){
echo '数据库登录信息:<br />';
echo SAE_MYSQL_USER.'  '.SAE_MYSQL_PASS;
echo '<br /><br />';
}
  附:
  访问以上地址可能报错——无法在发生错误时创建会话,请检查 PHP 或网站服务器日志,并正确配置 PHP 安装。
  解决办法:把地址栏参数k的值,改变下(增加或删掉一个字母),回车。再改回正确的k值,再回车就不报错了!郁闷。

posted @ 2013-10-14 10:05 顺其自然EVO 阅读(662) | 评论 (0)编辑 收藏

仅列出标题
共394页: First 上一页 196 197 198 199 200 201 202 203 204 下一页 Last 
<2024年11月>
272829303112
3456789
10111213141516
17181920212223
24252627282930
1234567

导航

统计

常用链接

留言簿(55)

随笔分类

随笔档案

文章分类

文章档案

搜索

最新评论

阅读排行榜

评论排行榜