马上行动 - Action Now
===========================================================
I Care About Software
===========================================================

I Care About Software

I believe that the software I help to create defines me as a professional, and speaks volumes about my commitment to software development.

· I care that the software I help to create is useful and usable

· I care that the software I help to create is simple and elegant

· I care that the software I help to create is reliable and robust

· I care that the software I help to create is responsive and scalable

· I care that the software I help to create can be extended and maintained

· I care that the software I help to create can be safely reused

· I care that the software I help to create is economical

· I care that the software I help to create is ready when it's needed

· I care that the people I work with also care about software as passionately as I do

As someone who cares passionately about software, I will:

· Look for ways to achieve higher value with greater economy in my work

· Champion those practices which lead to higher value with greater economy in the wider software development community

· Enthusiastically contribute to software development research, knowledge-sharing and debate with others who care as passionately as I do

· Defend against demonstrably poor practices, be they born out of ignorance or the special interests of people and organisations who evidently do not care about software as passionately as I do

· Offer moral and practical support to those who care as much as I do to help them do the right thing.

htthttp://www.icareaboutsoftware.org/


nmtcolin 发表于:2008.05.23 09:06 ::分类: ( IT ) ::阅读:(8950次) :: 评论 (0)
===========================================================
Oracle - Tables/Indexes
===========================================================

Here are some scripts related to Tables/Indexes .

Tabs w/ Questionable Inds

TABLES WITH QUESTIONABLE INDEX(ES) NOTES:

  • Owner - Owner of the table
  • Table Name - Name of the table
  • Column - Name of the column in question

  • The above query shows all tables that have more than one index with the same leading column. These indexes can cause queries to use an inappropriate indexes; in other words, Oracle will use the index that was created most recently if two indexes are of equal ranking. This can cause different indexes to be used from one environment to the next (e.g., from DEV to TEST to PROD).
  • The information does not automatically indicate that an index is incorrect; however, you may need to justify the existence of each of the indexes above.

    select 	TABLE_OWNER,
    	TABLE_NAME,
    	COLUMN_NAME
    from  	dba_ind_columns 
    where  	COLUMN_POSITION=1
    and  	TABLE_OWNER not in ('SYS','SYSTEM')
    group  	by TABLE_OWNER, TABLE_NAME, COLUMN_NAME
    having  count(*) > 1 
    
    

    Tabs With More Than 5 Inds

    TABLES WITH MORE THAN 5 INDEXES NOTES:

  • Owner - Owner of the table
  • Table Name - Name of the table
  • Index Count - Number of indexes

    select 	OWNER,
    	TABLE_NAME,
    	COUNT(*) index_count
    from  	dba_indexes 
    where  	OWNER not in ('SYS','SYSTEM')
    group  	by OWNER, TABLE_NAME 
    having  COUNT(*) > 5 
    order 	by COUNT(*) desc, OWNER, TABLE_NAME
    
    

    Tables With No Indexes

    TABLES WITHOUT INDEXES NOTES:

  • Owner - Owner of the table
  • Table Name - Name of the table

    select 	OWNER,
    	TABLE_NAME
    from 
    (
    select 	OWNER, 
    	TABLE_NAME 
    from 	dba_tables
    minus
    select 	TABLE_OWNER, 
    	TABLE_NAME 
    from 	dba_indexes
    )
    orasnap_noindex
    where	OWNER not in ('SYS','SYSTEM')
    order 	by OWNER,TABLE_NAME
    
    

    Tables With No PK

    NO PRIMARY KEY NOTES:

  • Table Owner - Owner of the table
  • Table Name - Name of the table

    select  OWNER,
    	TABLE_NAME
    from    dba_tables dt
    where   not exists (
            select  'TRUE'
            from    dba_constraints dc
            where   dc.TABLE_NAME = dt.TABLE_NAME
            and     dc.CONSTRAINT_TYPE='P')
    and 	OWNER not in ('SYS','SYSTEM')
    order	by OWNER, TABLE_NAME
    
    

    Disabled Constraints

    DISABLED CONSTRAINT NOTES:

  • Owner - Owner of the table
  • Table Name - Name of the table
  • Constraint Name - Name of the constraint
  • Constraint Type - Type of constraint
  • Status - Current status of the constraint

    select  OWNER,
            TABLE_NAME,
            CONSTRAINT_NAME,
            decode(CONSTRAINT_TYPE, 'C','Check',
                                    'P','Primary Key',
                                    'U','Unique',
                                    'R','Foreign Key',
                                    'V','With Check Option') type,
            STATUS 
    from 	dba_constraints
    where 	STATUS = 'DISABLED'
    order 	by OWNER, TABLE_NAME, CONSTRAINT_NAME
    
    

    FK Constraints

    FOREIGN KEY CONSTRAINTS NOTES:

  • Table Owner - Owner of the table
  • Table Name - Name of the table
  • Constraint Name - Name of the constraint
  • Column Name - Name of the column
  • Referenced Table - Name of the referenced table
  • Reference Column - Name of the referenced column
  • Position - Position of the column

    select 	c.OWNER,
    	c.TABLE_NAME,
    	c.CONSTRAINT_NAME,
    	cc.COLUMN_NAME,
    	r.TABLE_NAME,
    	rc.COLUMN_NAME,
    	cc.POSITION
    from 	dba_constraints c, 
    	dba_constraints r, 
    	dba_cons_columns cc, 
    	dba_cons_columns rc
    where 	c.CONSTRAINT_TYPE = 'R'
    and 	c.OWNER not in ('SYS','SYSTEM')
    and 	c.R_OWNER = r.OWNER
    and 	c.R_CONSTRAINT_NAME = r.CONSTRAINT_NAME
    and 	c.CONSTRAINT_NAME = cc.CONSTRAINT_NAME
    and 	c.OWNER = cc.OWNER
    and 	r.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
    and 	r.OWNER = rc.OWNER
    and 	cc.POSITION = rc.POSITION
    order 	by c.OWNER, c.TABLE_NAME, c.CONSTRAINT_NAME, cc.POSITION
    
    

    FK Index Problems

    FK CONSTRAINTS WITHOUT INDEX ON CHILD TABLE NOTES:

  • Owner - Owner of the table
  • Constraint Name - Name of the constraint
  • Column Name - Name of the column
  • Position - Position of the index
  • Problem - Nature of the problem

  • It is highly recommended that an index be created if the Foreign Key column is used in joining, or often used in a WHERE clause. Otherwise a table level lock will be placed on the parent table.

    select 	acc.OWNER,
    	acc.CONSTRAINT_NAME,
    	acc.COLUMN_NAME,
    	acc.POSITION,
    	'No Index' Problem
    from   	dba_cons_columns acc, 
    	dba_constraints ac
    where  	ac.CONSTRAINT_NAME = acc.CONSTRAINT_NAME
    and   	ac.CONSTRAINT_TYPE = 'R'
    and     acc.OWNER not in ('SYS','SYSTEM')
    and     not exists (
            select  'TRUE' 
            from    dba_ind_columns b
            where   b.TABLE_OWNER = acc.OWNER
            and     b.TABLE_NAME = acc.TABLE_NAME
            and     b.COLUMN_NAME = acc.COLUMN_NAME
            and     b.COLUMN_POSITION = acc.POSITION)
    order   by acc.OWNER, acc.CONSTRAINT_NAME, acc.COLUMN_NAME, acc.POSITION
    
    

    Inconsistent Column Names

    INCONSISTENT COLUMN DATATYPE NOTES:

  • Owner - Owner of the table
  • Column - Name of the column
  • Table Name - Name of the table
  • Datatype - Datatype of the column

    select 	OWNER,
    	COLUMN_NAME,
    	TABLE_NAME,
    	decode(DATA_TYPE, 'NUMBER', DATA_PRECISION, DATA_LENGTH) datatype
    from 	dba_tab_columns 
    where  	(COLUMN_NAME, OWNER) in
    		(select	COLUMN_NAME, 
    			OWNER
    	 	 from 	dba_tab_columns
    	 	 group	by COLUMN_NAME, OWNER
    	  	 having	min(decode(DATA_TYPE, 'NUMBER', DATA_PRECISION, DATA_LENGTH)) <
    		 	max(decode(DATA_TYPE, 'NUMBER', DATA_PRECISION, DATA_LENGTH)) )
    and 	OWNER not in ('SYS', 'SYSTEM')
    order	by COLUMN_NAME,DATA_TYPE 
    
    

    Object Extent Warning

    TABLES THAT CANNOT EXTEND NOTES:

  • Owner - Owner of the object
  • Object Name - Name of the object
  • Object Type - Type of object
  • Tablespace - Name of the tablespace
  • Next Extent - Size of next extent (bytes)

    select 	OWNER,
    	SEGMENT_NAME,
    	SEGMENT_TYPE,
    	TABLESPACE_NAME,
    	NEXT_EXTENT
    from (
    	select 	seg.OWNER, 
    		seg.SEGMENT_NAME,
    			seg.SEGMENT_TYPE, 
    		seg.TABLESPACE_NAME,
    			t.NEXT_EXTENT
    	from 	dba_segments seg,
    			dba_tables t
    	where 	(seg.SEGMENT_TYPE = 'TABLE'
    	and  	 seg.SEGMENT_NAME = t.TABLE_NAME
    	and  	 seg.owner = t.OWNER
    	and    NOT EXISTS (
    			select 	TABLESPACE_NAME
    				from 	dba_free_space free
    				where 	free.TABLESPACE_NAME = t.TABLESPACE_NAME
    				and 	BYTES >= t.NEXT_EXTENT))
    	union
    	select 	seg.OWNER, 
    		seg.SEGMENT_NAME,
    			seg.SEGMENT_TYPE, 
    		seg.TABLESPACE_NAME,
    			c.NEXT_EXTENT
    	from 	dba_segments seg,
    			dba_clusters c 
    	where  	(seg.SEGMENT_TYPE = 'CLUSTER'
    	and    	 seg.SEGMENT_NAME = c.CLUSTER_NAME
    	and    	 seg.OWNER = c.OWNER
    	and    	NOT EXISTS (
    			select 	TABLESPACE_NAME
    			from 	dba_free_space free
    			where 	free.TABLESPACE_NAME = c.TABLESPACE_NAME
    			and 	BYTES >= c.NEXT_EXTENT))
    	union
    	select 	seg.OWNER, 
    		seg.SEGMENT_NAME,
    			seg.SEGMENT_TYPE, 
    		seg.TABLESPACE_NAME,
    			i.NEXT_EXTENT
    	from 	dba_segments seg,
    			dba_indexes  i
    	where  	(seg.SEGMENT_TYPE = 'INDEX'
    	and    	 seg.SEGMENT_NAME = i.INDEX_NAME
    	and    	 seg.OWNER        = i.OWNER
    	and    	 NOT EXISTS (
    			select 	TABLESPACE_NAME
    					from 	dba_free_space free
    					where 	free.TABLESPACE_NAME = i.TABLESPACE_NAME
    			and 	BYTES >= i.NEXT_EXTENT))
    	union
    	select 	seg.OWNER, 
    		seg.SEGMENT_NAME,
    			seg.SEGMENT_TYPE, 
    		seg.TABLESPACE_NAME,
    			r.NEXT_EXTENT
    	from 	dba_segments seg,
    			dba_rollback_segs r
    	where  	(seg.SEGMENT_TYPE = 'ROLLBACK'
    	and    	 seg.SEGMENT_NAME = r.SEGMENT_NAME
    	and    	 seg.OWNER        = r.OWNER
    	and    	 NOT EXISTS (
    			select	TABLESPACE_NAME
    					from 	dba_free_space free
    					where 	free.TABLESPACE_NAME = r.TABLESPACE_NAME
                    and 	BYTES >= r.NEXT_EXTENT))
    )
    orasnap_objext_warn
    order 	by OWNER,SEGMENT_NAME
    
    

    Segment Fragmentation

    OBJECTS WITH MORE THAN 50% OF MAXEXTENTS NOTES:

  • Owner - Owner of the object
  • Tablespace Name - Name of the tablespace
  • Segment Name - Name of the segment
  • Segment Type - Type of segment
  • Size - Size of the object (bytes)
  • Extents - Current number of extents
  • Max Extents - Maximum extents for the segment
  • Percentage - Percentage of extents in use

  • As of v7.3.4, you can set MAXEXTENTS=UNLIMITED to avoid ORA-01631: max # extents (%s) reached in table $s.%s.
  • To calculate the MAXEXTENTS value on versions < 7.3.4 use the following equation: DBBLOCKSIZE / 16 - 7
  • Here are the MAXEXTENTS for common blocksizes: 1K=57, 2K=121, 4K=249, 8K=505, and 16K=1017
  • Multiple extents in and of themselves aren't bad. However, if you also have chained rows, this can hurt performance.

    select 	OWNER,
    	TABLESPACE_NAME,
    	SEGMENT_NAME,
    	SEGMENT_TYPE,
    	BYTES,
    	EXTENTS,
    	MAX_EXTENTS,
    	(EXTENTS/MAX_EXTENTS)*100 percentage
    from 	dba_segments
    where 	SEGMENT_TYPE in ('TABLE','INDEX')
    and 	EXTENTS > MAX_EXTENTS/2
    order 	by (EXTENTS/MAX_EXTENTS) desc
    
    

    Extents reaching maximum

    TABLES AND EXTENTS WITHIN 3 EXTENTS OF MAXIMUM :

  • Owner - Owner of the segment
  • Segment Name - Name of the segment

    select owner "Owner",
           segment_name "Segment Name",
           segment_type "Type",
           tablespace_name "Tablespace",
           extents "Ext",
           max_extents "Max"
    from dba_segments
    where ((max_extents - extents) <= 3) 
    and owner not in ('SYS','SYSTEM')
    order by owner, segment_name
    
    

    Analyzed Tables

    ANALYZED TABLE NOTES:

  • Owner - Owner of the table
  • Analyzed - Number of analyzed tables
  • Not Analyzed - Number of tables that have not be analyzed
  • Total - Total number of tables owned by user

  • The ANALYZE statement allows you to validate and compute statistics for an index, table, or cluster. These statistics are used by the cost-based optimizer when it calculates the most efficient plan for retrieval. In addition to its role in statement optimization, ANALYZE also helps in validating object structures and in managing space in your system. You can choose the following operations: COMPUTER, ESTIMATE, and DELETE. Early version of Oracle7 produced unpredicatable results when the ESTIMATE operation was used. It is best to compute your statistics.
  • A COMPUTE will cause a table-level lock to be placed on the table during the operation.

    select	OWNER,
    	sum(decode(nvl(NUM_ROWS,9999), 9999,0,1)) analyzed,
    	sum(decode(nvl(NUM_ROWS,9999), 9999,1,0)) not_analyzed,
    	count(TABLE_NAME) total
    from 	dba_tables
    where 	OWNER not in ('SYS', 'SYSTEM')
    group 	by OWNER
    
    

    Recently Analyzed Tables

    LAST ANALYZED TABLE NOTES:

  • Owner - Owner of the table
  • Table Name - Name of the table
  • Last Analyzed - Last analyzed date/time

    select 	OWNER,
    	TABLE_NAME,
    	to_char(LAST_ANALYZED,'MM/DD/YYYY HH24:MI:SS') last_analyzed
    from 	dba_tab_columns
    where 	OWNER not in ('SYS','SYSTEM')
    and 	LAST_ANALYZED is not null
    and	COLUMN_ID=1
    and 	(SYSDATE-LAST_ANALYZED) < 30
    order	by (SYSDATE-LAST_ANALYZED)
    
    

    Cached Tables

    CACHED TABLE NOTES:

  • Owner - Owner of the table
  • Table Name - Name of the table
  • Cache - Cached?

  • Oracle 7.1+ provides a mechanism for caching table in the buffer cache. Caching tables will speed up data access and improve performance by finding the data in memory and avoiding disk reads.

    select 	OWNER,
    	TABLE_NAME,
    	CACHE
    from dba_tables
    where OWNER not in ('SYS','SYSTEM')
    and CACHE like '%Y'
    order by OWNER,TABLE_NAME
    
    

  • nmtcolin 发表于:2008.05.06 15:35 ::分类: ( IT ) ::阅读:(2645次) :: 评论 (0)
    ===========================================================
    Oracle - Hit/Miss Ratios
    ===========================================================

    Here are some scripts related to Hit/Miss Ratios .

    Buffer Hit Ratio

    BUFFER HIT RATIO NOTES:

  • Consistent Gets - The number of accesses made to the block buffer to retrieve data in a consistent mode.
  • DB Blk Gets - The number of blocks accessed via single block gets (i.e. not through the consistent get mechanism).
  • Physical Reads - The cumulative number of blocks read from disk.

  • Logical reads are the sum of consistent gets and db block gets.
  • The db block gets statistic value is incremented when a block is read for update and when segment header blocks are accessed.
  • Hit Ratio should be > 80%, else increase DB_BLOCK_BUFFERS in init.ora

    select 	sum(decode(NAME, 'consistent gets',VALUE, 0)) "Consistent Gets",
    	sum(decode(NAME, 'db block gets',VALUE, 0)) "DB Block Gets",
    	sum(decode(NAME, 'physical reads',VALUE, 0)) "Physical Reads",
    	round((sum(decode(name, 'consistent gets',value, 0)) + 
    	       sum(decode(name, 'db block gets',value, 0)) - 
    	       sum(decode(name, 'physical reads',value, 0))) / 
    	      (sum(decode(name, 'consistent gets',value, 0)) + 
    	       sum(decode(name, 'db block gets',value, 0))) * 100,2) "Hit Ratio"
    from   v$sysstat
    
    

    Data Dict Hit Ratio

    DATA DICTIONARY HIT RATIO NOTES:

  • Gets - Total number of requests for information on the data object.
  • Cache Misses - Number of data requests resulting in cache misses

  • Hit Ratio should be > 90%, else increase SHARED_POOL_SIZE in init.ora

    select 	sum(GETS),
    	sum(GETMISSES),
    	round((1 - (sum(GETMISSES) / sum(GETS))) * 100,2)
    from 	v$rowcache
    
    

    SQL Cache Hit Ratio

    SQL CACHE HIT RATIO NOTES:

  • Pins - The number of times a pin was requested for objects of this namespace.
  • Reloads - Any pin of an object that is not the first pin performed since the object handle was created, and which requires loading the object from disk.

  • Hit Ratio should be > 85%

    select 	sum(PINS) Pins,
    	sum(RELOADS) Reloads,
    	round((sum(PINS) - sum(RELOADS)) / sum(PINS) * 100,2) Hit_Ratio
    from 	v$librarycache
    
    

    Library Cache Miss Ratio

    LIBRARY CACHE MISS RATIO NOTES:

  • Executions - The number of times a pin was requested for objects of this namespace.
  • Cache Misses - Any pin of an object that is not the first pin performed since the object handle was created, and which requires loading the object from disk.

  • Hit Ratio should be < 1%, else increase SHARED_POOL_SIZE in init.ora

    select 	sum(PINS) Executions,
    	sum(RELOADS) cache_misses,
    	sum(RELOADS) / sum(PINS) miss_ratio
    from 	v$librarycache
    
    http://vsbabu.org/oracle/sect05.html

  • nmtcolin 发表于:2008.05.06 15:03 ::分类: ( Testing ) ::阅读:(137129次) :: 评论 (21)
    ===========================================================
    Weblogic 只允许能连接5个IP的解决办法
    ===========================================================

    Weblogic 只允许能连接5个IP的解决办法

    0. Weblogic试用版只允许连接5个不同IP, 尽管可重新启动weblogic server可以重新获取5个IP,
    对于开发测试环境来说, 对于开发测试来说很不方便, 也不可能购买Weblogic的licences.


    1. shell scripts & Java command
    local_port: 12345
    host: ydc062
    remote_port: 8080

    java -classpath ./Relay.jar Relay 12345 ydc062 8080

    2. 使用方法
    http://ydc062:8080(limit 5 ip)

    http://ydc062:12345(not limit forward to above access)


    3. Java source code

    /**
    * DataRelay.java
    */
    import java.io.InputStream;
    import java.io.OutputStream;

    public class DataRelay implements Runnable {
    private InputStream in;

    private OutputStream out;

    public void run() {
    byte abyte0[] = new byte[4096];
    try {
    do {
    int i = in.read(abyte0);
    if (i == 0)
    break;
    out.write(abyte0, 0, i);
    } while (true);
    try {
    in.close();
    } catch (Exception exception) {
    }
    try {
    out.close();
    } catch (Exception exception1) {
    }
    } catch (Exception exception2) {
    try {
    in.close();
    } catch (Exception exception3) {
    }
    try {
    out.close();
    } catch (Exception exception4) {
    }
    }
    }

    public DataRelay(InputStream inputstream, OutputStream outputstream) {
    in = inputstream;
    out = outputstream;
    }
    }


    /**
    * Relay.java
    */
    import java.io.*;
    import java.net.ServerSocket;
    import java.net.Socket;

    public class Relay implements Runnable {

    public int listenPort;

    public String relayHost;

    public int relayPort;

    public Relay() {
    }

    public Relay(int i, String s, int j) {
    listenPort = i;
    relayHost = s;
    relayPort = j;
    }

    public void run() {
    try {
    ServerSocket serversocket = new ServerSocket(listenPort);
    do {
    Socket socket = serversocket.accept();
    try {
    Socket socket1 = new Socket(relayHost, relayPort);
    startRelay(socket.getInputStream(), socket1
    .getOutputStream());
    startRelay(socket1.getInputStream(), socket
    .getOutputStream());
    } catch (Exception exception1) {
    exception1.printStackTrace();
    socket.close();
    }
    } while (true);
    } catch (Exception exception) {
    exception.printStackTrace();
    }
    }

    public void startRelay(InputStream inputstream, OutputStream outputstream)
    throws IOException {
    DataRelay datarelay = new DataRelay(inputstream, outputstream);
    Thread thread = new Thread(datarelay);
    thread.start();
    }

    public static void main(String args[]) {
    if (args.length < 3) {
    System.out.println("-------------------------------------------");
    System.out.println("Usage: ./Relay local_port host remote_port");
    System.out.println("-------------------------------------------");
    System.exit(0);
    }
    int i = 0;
    try {
    i = Integer.parseInt(args[0]);
    } catch (Exception exception) {
    System.out.println("Invalid local port: " + args[0]);
    System.exit(0);
    }
    int j = 0;
    try {
    j = Integer.parseInt(args[2]);
    } catch (Exception exception1) {
    System.out.println("Invalid remote port: " + args[2]);
    System.exit(0);
    }
    Relay relay = new Relay(i, args[1], j);
    relay.run();
    }

    }


    nmtcolin 发表于:2008.04.28 15:52 ::分类: ( IT ) ::阅读:(12536次) :: 评论 (0)
    ===========================================================
    如何评价测试人员的工作绩效?
    ===========================================================
    如何评价测试人员的工作绩效?

      随着国内软件测试行业的不断发展,软件测试工作更加深入、规范。其中对测试人员的绩效考核也越来越重要。目前,很多公司对测试人员的考核方面都不相同,有些公司仍然是以单纯的问题单数量来对测试人员进行评价,这样直接对测试人员工作方向产生误导,影响到测试人员工作的积极性和稳定性。因此,为了能够更好对测试过程进行管理,必须对测试人员有一个客观、全面的评价。下面是本人在工作中的一些体会希望能给大家带来一些启发:


      一、测试人员工作绩效评价的误区

      1、 仅从提交的问题单数量、测试执行用例数量来判断测试人员的好坏

      这种做法明显缺乏全面性。问题单的数量只是评估测试质量的一个方面,我们更需要看中实际的测试质量。这就需要考察问题单的质量、测试的难度、问题单的级别。

      例如:模块A很不稳定,潜在的问题数可能有100个,由测试人员甲负责测试,他一个月执行300个用例,提交50个问题单,发现30个有效问题,有10个严重问题;

      模块B比较稳定,潜在的问题数可能有20个,由测试人员乙负责测试,他一个月执行100个用例,提交20个问题单,发现18个有效问题,有8个严重问题;

      从上述测试执行结果来看,甲提交的问题单数量和执行用例数量都要远远高于乙,但是从测试的质量来看,模块B的遗留问题显然少于模块A,甲执行测试的充分性显然不如乙,从问题单质量来看,甲提交的问题单虽然很多,但近半数是非问题,做了无用功,还影响到开发人员对问题的定位所消耗的时间。

      因此,必须要走出用问题单数量、用例数量评价测试人员的误区。


      2、 对测试人员发现的问题的价值没有进行评估

      发现1个系统架构设计方面存在的缺陷和隐患,远比发现几个普通界面的显示问题要有价值的多。因此,在对测试人员进行评价时,必须区分不同问题的重要性和价值。

      3、 不重视测试文档的质量

      测试文档的质量往往是测试人员的测试水平的反映,只有对系统进行了充分的、深入测试的测试人员才能写出高质量测试报告,说明测试的全面性和测试过程的质量。

      4、 不重视测试人员的综合能力

      首先,必须考察测试人员的责任心,如果一个测试人员工作不符责任,随意敷衍,即使提交的问题单数量多,也不能证明他测试的质量高。其次,需要关心测试人员的工作积极性,积极工作的态度不仅能带来很高的测试质量,还能提高整个团队的积极向上的风气。还有,测试人员的沟通能力,如果一个测试人员和开发人员对问题沟通交流不畅,甚至经常引发争执,这显然会影响测试工作的效率。


      二、建议对测试人员进行综合性的全面评价

      评价方法如下:

      

      三、总结

      综上所述,必须本着以测试质量为重、对测试负责的角度对测试人员绩效进行客观评价,同时也提高测试人员的质量意识。通过合理的绩效评价,让测试人员以积极的心态投入的测试工作中,保证测试工作的顺利进行。

    转自http://se.csai.cn/ExpertColumn/No036.asp

     查看全文
    nmtcolin 发表于:2008.04.25 14:19 ::分类: ( Testing ) ::阅读:(751次) :: 评论 (0)
    ===========================================================
    关于中文简体繁体的相互转换!
    ===========================================================

    1. 利用 ResourceBundle Editor (http://eclipse-rbe.sourceforge.net)可以解决资源文件同步编辑.如下列英文,简体和繁体同时编辑.

    icsis_en.properties
    icsis_zh_CN.properties
    icsis_zh_TW.properties

    2. 有了简体资源文件可以用下列产生繁体资源文件.

    java -classpath .;libzhcode.jar zhcode -gb configpropssltnt_GB2312.xml configpropssltnt_Big5.xml


    native2ascii -encoding Big5 configpropssltnt_Big5.xml configpropssltnt_zh_HK.xml
    zhcode.jar download from the following link.http://www.mandarintools.com/download/zhcode.zip

    3. Big5、GB2312、Unicode、UTF8 等多种中文编码之间转换。

    官方网页为:
    http://www.mandarintools.com/javaconverter.html

    编码与解码工具:

    http://web.hku.hk/~jwilam/it/codewares.htm


    nmtcolin 发表于:2008.04.23 13:50 ::分类: ( IT ) ::阅读:(615次) :: 评论 (0)
    ===========================================================
    The value for the useBean class attribute SecurityOrgPages is invalid. in tomcat 5.5
    ===========================================================

    Aproject work fine in tomcat 4.1, but upgrade apache-tomcat-4.1.34/jdk 1.4 to apache-tomcat-5.5.25, jdk 1.5, ecounter the following error.

    type Exception report

    message

    description The server encountered an internal error () that prevented it from fulfilling this request.

    exception

    org.apache.jasper.JasperException: /jsp/security/securityOrgPages.jsp(4,0) The value for the useBean class attribute SecurityOrgPages is invalid.
    org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:40)
    org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:407)
    org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:148)
    org.apache.jasper.compiler.Generator$GenerateVisitor.visit(Generator.java:1175)
    org.apache.jasper.compiler.Node$UseBean.accept(Node.java:1117)
    org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2166)
    org.apache.jasper.compiler.Node$Visitor.visitBody(Node.java:2216)
    org.apache.jasper.compiler.Node$Visitor.visit(Node.java:2222)
    org.apache.jasper.compiler.Node$Root.accept(Node.java:457)
    org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2166)
    org.apache.jasper.compiler.Generator.generate(Generator.java:3322)
    org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:199)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:296)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:277)
    org.apache.jasper.compiler.Compiler.compile(Compiler.java:265)
    org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:564)
    org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:302)
    org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:329)
    org.apache.jasper.servlet.JspServlet.service(JspServlet.java:265)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
    com.newmodern.etm.security.servlet.SecurityOrgServlet.service(SecurityOrgServlet.java:367)
    javax.servlet.http.HttpServlet.service(HttpServlet.java:803)


    note The full stack trace of the root cause is available in the Apache Tomcat/5.5.25 logs.

    in jsp /jsp/security/securityOrgPages.jsp change below bean classs as absolute path ok, why??? but it work fine in tomcat 4.1.

    <%@ page import="com.xxxxxx.xxx.security.entity.*" %>
    <jsp:useBean id="etmSecurityOrgPages" class="SecurityOrgPages" scope="request"/>

    Solution:
    <jsp:useBean id="etmSecurityOrgPages" class="com.xxxxxx.xxx.security.entity.SecurityOrgPages" scope="request"/>


    nmtcolin 发表于:2008.04.16 17:02 ::分类: ( IT ) ::阅读:(1030次) :: 评论 (0)
    ===========================================================
    Coding your second Jakarta Struts Application
    ===========================================================

    Coding your second Jakarta Struts Application

    http://javaboutique.internet.com/tutorials/Struts2/

    Introduction

    Did the title of the article make you curious? If this is the second application then what was the first one? The answer is, the first application was presented in my previous article about Jakarta Struts, "Stepping through Jakarta Struts". Here I showed you:

    • how to download and install Struts
    • the directory structure of a Struts application
    • how to create the first pieces of a new application
    • the contents and purpose of the configuration files
    • how to build a simple Struts HTML page using taglibs
    • how to code an ActionForm class
    • how to code an Action class
    • and finally how to test your application

    The "application" that I used as the example was a simple HTML page containing a form with the common controls--text and textarea fields, radio buttons, a checkbox, a selection list (drop down), and a submit button. The submit button would simply submit the form to the page again, and despite the simplicity of the application, all of the main pieces of the Struts framework were being used.

    In this article I'll show you how to take one more step up the Struts ladder. This time we'll build a classic list-detail application with the well-known CRUD-actions: Create, Read, Update, and Delete.

    The DVD library application

    Reuse is a good thing, so I decided to take the specs for our second application from a previous article of mine, "Java and JDOM: the perfect couple". Here, a small web application that could manage a collection of DVDs was built. The DVD information is held in an XML file. The application consists of two pages, a DVD List page and a DVD Detail page. Here's the List page first:

    When you click on one of "Id"-hyperlinks you'll go to the Detail page:

    As you can see there are 7 functions in total to implement: list, detail, save, update, create, delete and cancel. The flow of the application is as follows:

    In the JDOM article, I used a very simple MVC-architecture using only jsp-pages (even for the controllers) and JavaBeans. The beans can be re-used in the Struts application, and also the html layout. To finish the Struts application we'll have to:

    • write the proper configuration files (struts-config.xml and ApplicationRessources.properties)
    • code ActionForm and Action classes for the 7 functions
    • write the two jsp-pages using Struts tags

    nmtcolin 发表于:2008.04.11 23:14 ::分类: ( IT ) ::阅读:(405次) :: 评论 (0)
    ===========================================================
    The Power of Three - Eclipse, Tomcat, and Struts
    ===========================================================

    Java(TM) Boutique - The Power of Three - Eclipse, Tomcat, and Struts

    Introduction

    As a programmer it's important to be productive, and as any other craftsman you need good tools to be productive. In this article I'll present a set of tools, which can really help you get your job done. What's more, they're all free, open source, and well documented. I've been using these tools in several real-life projects and have found that they often outdo expensive development tools. This is because they're simple to install, simple to use, reliable and have good performance.

    The names of the tools are Eclipse, Tomcat, and Struts.

    You've probably heard about all of them, and maybe you have used them in your work, but anyway: here's a short description of each:

    • Eclipse is an IDE from eclipse.org, which can be used for programming in Java and many other programming languages.
    • Tomcat is a J2EE web server from the Apache Jakarta project
    • Struts is a framework--also from Apache Jakarta--for building MVC-type servlet applications

    So, these tools are made for making web applications based on the servlet specification. They don't cover EJB's, since Tomcat is not an EJB-server, and standard Eclipse does not cover EJB's.

    Eclipse has a project type for Java development, but strangely enough not for Java web application development. A Java web application is characterized by a special directory structure (war-file structure), and a set of specialized files: jsp-files, XML configuration files, servlets, etc. To fill this gap, a very nice Eclipse plug-in from sysdeo.com is at hand. It not only gives us the web application project but also a way of managing the Tomcat server from within Eclipse. Below we'll see how to install and use this plug-in.

    Struts gives you a way of building modular, de-coupled web applications. How Struts is included in Eclipse is another topic that'll be covered later in this article.

    How to debug Jsp, servlet etc.

    http://javaboutique.internet.com/tutorials/three/index.html

     查看全文
    nmtcolin 发表于:2008.04.11 23:01 ::分类: ( IT ) ::阅读:(399次) :: 评论 (0)
    ===========================================================
    Test Generation framework
    ===========================================================

    JUnit Factory
    An experimental test-generation service from AgitarLabs, the research

    division of Agitar Software. JUnit Factory is a 2008 Jolt Productivity

    Award Winner!

    http://www.junitfactory.com
    http://www.junitfactory.com/articles/


    Introducing Crap4J
    There is no fool-proof, 100% accurate and objective way to determine if a

    particular piece of code is crappy or not. However, our intuition – backed

    by research and empirical evidence – is that unnecessarily complex and

    convoluted code, written by someone else, is the code most likely to

    elicit the “This is crap!” response.

    http://www.junitfactory.com/articles/crap4j/


    CUTE / JCUTE (a Concolic Unit Testing Engine for C and Java) is a tool to

    systematically and automatically test sequential C programs (including

    pointers) and concurrent Java programs. CUTE combines concrete and

    symbolic execution in a way that avoids redundant test cases as well as

    false warnings. The tool also introduces a novel race-flipping technique

    to efficiently test and model-check concurrent programs with data inputs.

    http://osl.cs.uiuc.edu/~ksen/cute/?page=overview

    CubicTest
    http://boss.bekk.no/cubictest/

    Welcome to functional web testing with CubicTest!
    CubicTest is a graphical Eclipse plug-in for writing Selenium and Watir tests. It makes tests faster and easier to write, and provides abstractions to make tests more robust and reusable.

    CubicTest's test editor is centered around pages/states and transitions between these pages/states. The model is intuitive for both Ajax and traditional web applications and supports most user interaction types.

    CubicTest featres an innovative test recorder and test runner based on Selenium RC which are fully integrated with the graphical test editor. Tests can also be run standalone from Maven 2.

    Selenium
    http://selenium.openqa.org/

    Selenium is a test tool for web applications. Selenium tests run directly in a browser, just like real users do. It runs in Internet Explorer, Mozilla and Firefox on Windows, Linux, and Macintosh, Safari on the Mac. We have plans to target Safari on the iPhone in some months.

    The quickest way to learn Selenium is via a Firefox plugin called Selenium IDE. It is quite compelling for developing tests in and quickly trying out Selenium before choosing Selenium for your project.

    There are two modes of operation for Selenium - Core and Remote Control (RC). Remote Control mode also has a related capability called Selenium Grid that allows you to throw hardware at tests to make it all faster.


    nmtcolin 发表于:2008.03.25 14:55 ::分类: ( Testing ) ::阅读:(1068次) :: 评论 (7)
    ===========================================================
    LoadRunner监控Windows和Linux常见问题
    ===========================================================

    关于LR监视Windows和linux的说明

    一 windows

    1 监视连接前的准备工作

    首先保证被监视的windows系统开启以下二个服务Remote Procedure Call(RPC) 和Remote Registry Service 这里具体在那里开起服务就不说了)

    被监视的WINDOWS机器:右击我的电脑,选择管理->共享文件夹->共享 在这里面要有C$这个共享文件夹,(要是没有自己手动加)

    然后保证在安装LR的机器上使用运行.输入被监视机器IPC$ 然后输入管理员帐号和密码,如果能看到被监视机器的C盘了,就说明你得到了那台机器的管理员权限,可以使用LR去连接了

    说明: LR要连接WINDOWS机器进行监视貌似要有管理员帐号和密码才行,

    2 用LR监视windows的步骤

    (这里就不详细说明了,只要在窗口中右击鼠标选择Add Measurements就可以了)

    二 linux

    1 准备工作

    首先,监视Linux一定要有rstatd这个守护进程,有的Linux版本里也有可能是rpc.rstatd这里只是名字不同而已,功能是一样的

    一般来说LINUX需要下载一个包才有这个服务,包名字是rpc.rstatd-4.0.1.tar.gz. 这是一个源码,需要编译,

    下载并安装rstatd

    tar -ivh rpc.rstatd-4.0.1.tar.gz
    ./configure —配置
    make —编译
    make install —安装
    rpc.rstatd —启动rstatd进程

    配置rstatd 目标守护进程是xinetd,它的主配置文件是/etc/xinetd.conf 里面内容是

    只有基本信息
    # Simple configuration file for xinetd
    #
    # Some defaults, and include /etc/xinetd.d/

    defaults
    {
    instances = 60
    log_type = SYSLOG authpriv
    log_on_success = HOST PID
    log_on_failure = HOST
    cps = 25 30
    }

    includedir /etc/xinetd.d

    里面内容的意思在这里就不说了!网上有具体解释,

    我们这里需要修改的是/etc/xinetd.d/下的三个conf文件 rlogin ,rsh,rexec 这三个配置文件,

    打这三个文件里的disable = yes都改成 disable = no ( disabled 用在默认的 {} 中 禁止服务)

    或是把# default: off都设置成 on 这个的意思就是在xinetd启动的时候默认都启动上面的三个服务!

    (由于貌似用ps ax不能看到rlogin ,rsh ,rexec这三个进程是否开启,所以使用default: on,因为rstatd和xinetd这二个服务是否启动在ps ax里是看的到的)

    然后你在保证Linux机器上的进程里有rstatd和xinetd这二个服务就可以用LR去监视了

    几点小的技巧:

    检查是否启动: rsh server 监听和TCP 是514。
    [root@mg04 root]# netstat -an |grep 514
    tcp 0 0 0.0.0.0:514 0.0.0.0:* LISTEN
    如果能看到514在监听说明rsh服务器已经启动。

    检查是否启动: rstatd

    输入命令: rpcinfo -p

    如果能看到

    程序 版本 协议 端口

    *** **** udp 741 rstatd

    那就说明rstatd服务启动了,(当然这里也可以用ps ax代替)

    几点说明: 1) 在实际操作中有可能会碰到一些问题,这里还有一份网上的关于LR连接时候可能出错的情况,详细请见下面

    2) 网上也有人说在LR的资源窗口中右击鼠标出现的Add Measurements选项是暗淡的,我操作的时候没碰到,这里可能是LR没有完全安装的原因.

    3) 由于条件的限制,(没有UNIX环境)所以这次没有遇及UNIX的监控,但网上也有这方面的资料,说明的也比较清楚,在这里就不再重复了.

    4) 由于本人能力有限,只是把网上的内容归纳了一下,说的不对的地方请高人指点,我会更新内容.

    LoadRunner中服务器资源监控器疑难解答

    要监控服务器计算机上的资源,必须能够连接到该计算机。如果监控失败,并且 LoadRunner 找不到指定的服务器,请确认指定的服务器是否可用。在 Controller 或优化控制台计算机命令行中键入 ping <server_name>,执行“ping”操作。

    验证可以访问该计算机后,请查看下表中有关监控器疑难解答的其他提示。

    问题

    解决方案

    无法监控其他域中的 Windows 计算机,或者访问被拒绝

    要获得对远程计算机的管理权限,请在命令提示符下执行以下命令:

    %net use <计算机名>/用户:[<><远程计算机名>]

    提示输入密码时,输入远程计算机的密码。

    无法监控 NT/Win 2000 计算机(发出一条错误消息:未找到计算机名无法连接到主机

    要监控的 NT/Win 2000 计算机仅允许具有管理员权限的用户进行监控。要允许非管理员用户进行监控,必须授予用户对特定文件和注册表项的读取权限(Microsoft 技术说明编号 Q158438)。需要执行下列步骤:

    a. 使用浏览器或文件管理器,授予用户对下列项的读取权限:
    %windir%system32PERFCxxx.DAT

    %windir%system32PERFHxxx.DAT

    其中 xxx 是系统的基本语言 ID例如,英语的 ID 009。这些文件可能已丢失或损坏。如果对此有怀疑,请从安装 CD 中提取这些文件。

    b. 使用 REGEDT32,授予用户对下列项的读取权限:
    HKEY_LOCAL_MACHINESoftwareMicrosoftWindows NTCurrentVersionPerflib
    以及该项的所有子项。

    c. 使用 REGEDT32,至少授予用户对下列项的读取权限:
    HKEY_LOCAL_MACHINESystemCurrentControlSet ControlSecurePipeServerswinreg

    无法从 NT 计算机监控某些 Win 2000 计数器。

    Win 2000 计算机上运行 Controller 或优化控制台。

    某些 Windows 默认计数器生成错误

    删除有问题的计数器,并使用添加度量对话框添加相应计数器。

    无法从被监控的计算机上获得 SQL Server 6.5 版的性能计数器。

    这是 SQL Server 6.5 版的一个错误。解决方法为:在被监控的计算机上使用 regedt32,授予用户对以下注册表项的读取权限:

    HKEY_LOCAL_MACHINESOFTWAREMicrosoftMSSQLServerMSSQLServer

    Microsoft 技术说明编号 Q170394

    选定度量未显示在图中。

    确保已注册显示文件和 online.exe。要在不执行完全安装的情况下注册监控器的 dll,请运行 LoadRunnerbin 中的 set_mon.bat 批处理文件。

    监控 Windows 计算机时,图中不显示任何度量。

    检查内置的 Windows 性能监控器。如果该监控器不能正常工作,则可能是通信设置有问题。

    监控 UNIX 计算机时,图中不显示任何度量。

    确保 rstatd 正在 UNIX 计算机上运行(请参阅系统资源监控)。

    无法监控下列 Web 服务器之一:MS IISMS ASP ColdFusion

    请参阅上面的问题无法监控 Windows 计算机

    无法监控 WebLogic (JMX) 服务器

    打开 <LoadRunner 根文件夹>datmonitorsWebLogicMon.ini 文件,并搜索:
    [WebLogicMonitor]
    JVM=javaw.exe
    javaw.exe 更改为 java.exe。将打开一个包含跟踪信息的窗口。

    http://www.cntester.com/FocusPerformance/200711/1098.shtml


    nmtcolin 发表于:2008.03.23 21:31 ::分类: ( Testing ) ::阅读:(743次) :: 评论 (0)
    ===========================================================
    认识p-unit:一款开源的性能测试框架
    ===========================================================

    认识p-unit:一款开源的性能测试框架

    来源: AppFuse中文社区

    http://www.ibm.com/developerworks/cn/java/j-lo-punit/index.html

    p-unit 是一款开放源码的性能测试框架,和 JUnit 不同,JUnit 关注的是测试案例的正确性,而 p-unit 不仅关注测试案例的正确性,还收集测试案例的性能参数,默认情况下,p-unit 收集测试案例的时间和内存消耗情况,可以产生文件,图片,和 PDF 格式的报表。此外,p-unit 还支持参数化测试,多线程测试以及不同 Java 虚拟机性能之间的比较。
    p-unit 简介


    或许我们已经习惯了使用 JUnit 来写单元测试来保证代码质量(我也一直这么做),但可能经常碰到这样的问题:
    程序多线程下正确性如何?
    如何测试程序的性能?
    当有多个方案可以选择时,技术上如何比较不同方案的性能?

     对于问题 1,我们或许听天由命?或是凭借人工分析,或是根据用户反馈?很多软件单线程下的单元测试覆盖率相当高,从而保证了代码的健壮性。然而多线程测试时常被忽略,这并不代表多线程测试不重要,相反,修正一个用户报告的多线程 BUG 往往比单线程的要高出很多,因为测试案例经常不是 100% 可重现的。这更要求程序员在开发阶段充分的重视。目前多线程单元测试力度不够的一个重要原因是没有一个像 JUnit 那样易用的测试工具,另外重复写测试案例往往不被程序员接受。

     对于问题 2,一个成熟的关心性能的产品往往有一个性能测试平台。这个测试平台应该关注的是测试业务逻辑本身,而无需关心如何运行测试案例。你是否为写这样的测试平台痛苦过?以及花费时间在产生一些直观的报表上面?

     对于问题 3,我们往往写一个原型来比较不同产品之间的性能,如何比较执行速度和内存消耗?或是选择最适合你的虚拟机?

     p-unit 就是这么一款开源的性能测试软件,它能帮助你很好的解决上述问题。p-unit 可以:
    多线程支持:同一个测试案例可以单线程执行,也可以多线程执行,测试案例开发者只需写一套测试案例。
    参数化测试案例:很多测试案例,需要测试同一功能在不同数量级上的性能表现。
    不同虚拟机性能测试:只需指定虚拟机路径,即可测试同一个测试案例在不同虚拟机上的表现,报表上可以非常直观显示性能差别。
    事件机制构架:punit 是基于事件机制构架的,如果用户想定制报表,只需实现事件响应器,并注册该响应器到 punit 核心即可。


    多线程执行测试案例


     在了解如何多线程执行测试案例之前,我们先了解一下如何利用 p-unit 单线程执行测试案例。不同于 JUnit, p-unit 测试用例无需继承任何测试类或是实现接口,即可执行 test 开始的方法。尽管 JUnit 4 中加入了注释(Annotation) 的特性,但测试方法前缀为 "test" 仍然是测试者们的首选。因此如果你的 JUnit 测试案例遵循的是 test 命名规则,那么 p-uni t可以兼容运行 JUnit 测试案例。
    下面的代码清单 1 是一个最为普通的测试案例:

    CODE:


    public class SimpleTestClass {

    public void setUp() {
    SampleUtil.doSomething();
    }

    public void tearDown() {
    SampleUtil.doSomething();
    }

    public void testA() {
    System.out.println("testA");
    SampleUtil.doSomething();
    }

    public void testB() {
    SampleUtil.doSomething();
    }

    public void testC() {
    SampleUtil.doSomething();
    }

    }

    public class SampleUtil {
    private static Random _random = new Random();

    public static void consumeMemory(int length) {
    byte[] data = new byte[length];
    for(int i = 0, j = 0; i < data.length; ++i) {
    ++j;
    }
    }

    public static void consumeTime(int time) {
    ThreadUtil.sleepIgnoreInterruption(time);
    }

    public static void doSomething() {
    consumeTime(Math.abs(_random.nextInt()) % 500);
    consumeMemory(Math.abs(_random.nextInt()) % 100000);
    }
    }
     这是做为普通的测试案例,但是注意到这仅仅是一个测试案例,不包含其他任何逻辑,这也是 p-unit 追求的业务逻辑和测试运行环境分离的一个理念。同一个测试案例,用户可以选择不同的测试环境去运行,而不是绑定在某一个特定的测试软件工具上。现在我们来看 p-unit 是如何运行这个测试案例的。你只需要在 main 函数中写一行代码来运行它:

    清单 2. 单线程运行测试案例

    CODE:


    public static void main(String[] args) {
    new PUnitSoloRunner().run(SimpleTestClass.class);
    }
    清单 3. 单线程运行测试案例结果

    CODE:


    [solo] Started running samples.SimpleTestClass
    samples.SimpleTestClass
    testA
    testA() - [287.0ms]
    testB() - [27.0ms]
    testC() - [213.0ms]
    total: 3, failures:0 (GREEN) - 2025.0ms
     是否和想象中的一样?下面我们来看如何多线程执行这个测试案例。或许从上面的例子你已经猜到了,在 main 函数还是只需一句代码,只用把 PUnitSoloRunner 换成 PUnitConcurrentRunner 即可!

    清单 4. 多线程运行测试案例

    CODE:


    public static void main(String[] args) {
    new PUnitConcurrentRunner().run(SimpleTestClass.class);
    }
    清单 5. 多线程运行测试案例结果

    CODE:


    [concurrent] Started running samples.SimpleTestClass
    samples.SimpleTestClass
    testA
    testA
    testA
    testA
    testA
    testA
    testA
    testA
    testA
    testA
    testA() - [405.0ms]
    testB() - [469.0ms]
    testC() - [503.0ms]
    total: 3, failures:0 (GREEN) - 1447.0ms
     是否和想象中的一样?默认情况 p-unit 启动 10 个线程来执行,要指定不同的线程数,只需将线程数做为参数传入 PUnitConcurrentRunner 即可。p-unit 甚至支持不同的测试案例有不同的线程数,这要求测试案例实现 p-unit 中定义的 Concurrent 接口,该接口的定义为:

    清单 6. p-unit Concurrent 接口

    CODE:


    public interface Concurrent {
    public int concurrentCount();
    }
     该接口的意思,相信无需再多做解释了,返回该测试案例需要的线程数。

    最新回复

    quake at 2007-11-21 15:35:48
    参数化测试案例


     性能测试,不同于单元测试,经常要求测试不同数量级在同一个测试场景中的表现,JUnit 是一款非常优秀的单元测试工具,但没覆盖到这个方面。比如我们比较类库 Foo1 的方法 bar() 和类库 Foo2 的方法 bar() 哪个更符合自己的应用程序,我们需要测试该函数在应用程序可能的数量级的范围内的表现。有经验的开发者知道经常碰到在小数量级 A 更好大数量级 B 更好的局面,因此全面的测试对于代码的性能理解非常重要,能帮助开发者做出正确的决定。p-unit 支持将参数传给测试方法,测试案例需要实现 p-unit 的 parameterizable 接口,该接口的主要方法是返回一组参数列表,这组列表的参数将会一一传给测试方法。

    清单 7. p-unit 参数化测试案例

    CODE:


    public class ParamTestClass implements Parameterizable {
    public static void main(String[] args) {
    new PUnitSoloRunner().run(ParamTestClass.class);
    }

    public Parameter[] parameters() {
    return new Parameter[] { new ParameterImpl(10), new ParameterImpl(20) };
    }
    public void testA(ParameterImpl param) {
    SampleUtil.doSomething();
    }

    public void testB(ParameterImpl param) {
    SampleUtil.doSomething();
    }

    public void testC(ParameterImpl param) {
    SampleUtil.doSomething();
    }

    public void setUpAfterWatchers(Parameter param) throws Exception {
    }
    public void setUpBeforeWatchers(Parameter param) throws Exception {
    }
    public void tearDownAfterWatchers(Parameter param) throws Exception {
    }
    public void tearDownBeforeWatchers(Parameter param) throws Exception {
    }
    static class ParameterImpl implements Parameter {
    private int _count;
    ParameterImpl(int count) {
    _count = count;
    }
    public int count() {
    return _count;
    }

    public String toString() {
    return String.valueOf(_count);
    }
    }
    }
    上述代码的执行结果为:

    CODE:


    [solo] Started running samples.ParamTestClass
    samples.ParamTestClass
    testA(10) - [57936.0bytes,447.0ms]
    testA(20) - [33128.0bytes,61.0ms]
    testB(10) - [24832.0bytes,137.0ms]
    testB(20) - [0.0bytes,63.0ms]
    testC(10) - [83560.0bytes,468.0ms]
    testC(20) - [16528.0bytes,47.0ms]
    total: 6, failures:0 (GREEN) 1450.0ms
     从上述结果看出,每个方法被执行了 2 次,每次传入不同的参数。多线程运行参数化测试程序?相信读者已经明白怎么去实现了,只需将 PUnitSoloRunner 替换成 PUnitConcurrentRunner。
    quake at 2007-11-21 15:40:22
    运行环境测试案例

     随着 Java 开源,出现了更多的 Java 运行环境,除了 SUN 的参考实现外,BEA、IBM 均有自己的 Java 运行环境,更有如 Apache Harmony 的开源运行环境(尽管现在 Apache Harmony 尚不能称为 Java 运行环境)。运行环境测试案例,为运行环境开发者以及选择运行环境,都能提供一定的帮助。比如说下面的例子就是测试 java.util.ArrayListjava.util.Vector 在两个不同运行环境的表现。测试案例写法和普通的测试案例完全一样,我们只需告诉 p-unit 不同的运行环境的 Java 路径以及正确的 classpath,然后调用 runVMs 函数即可:

    清单 9. p-unit 运行环境测试案例

    CODE:


    public static void main(String[] args) {
    PUnitSoloRunner runner = new PUnitSoloRunner();
    runner.addPUnitEventListener(new OverviewReporter(new ImageRender()));
    runner.runVMs(ListTestClass.class, new VM[] { VMConfig.HARMONY, VMConfig.SUN });
    }
    public class VMConfig {
    private static String CLASSPATH = " -cp correct_classpath_including_all_jars_and_path";
    private static String HARMONY_PATH = "harmony_pathbinjava" + CLASSPATH;
    private static String SUN_PATH = "sun_pathbinjava" + CLASSPATH;
    public static VM HARMONY = new VM(HARMONY_PATH, "HARMONY");
    public static VM SUN = new VM(SUN_PATH, "SUN");
    }
    public class ListTestClass {

    private static final int LIST_COUNT = 100000;
    private static Object element = new Object();
    private Random indexGenerator = new Random();;

    public void testInsertArrayList() {
    ArrayList arrayList = new ArrayList(LIST_COUNT);
    insertSequence(arrayList);
    insertRandom(arrayList);
    }
    public void testInsertVector() {
    Vector vector = new Vector(LIST_COUNT);
    insertSequence(vector);
    insertRandom(vector);
    }
    public void insertSequence(List list) {
    for (int i = 0; i < LIST_COUNT; ++i) {
    list.add(element);
    }
    }
    public void insertRandom(List list) {
    for (int i = 0; i < LIST_COUNT; ++i) {
    list.add(indexGenerator .nextInt(LIST_COUNT),element);
    }
    }
    }
    上述代码的运行结果如下:


    20070604102119810.jpg



     从上图中可以很直观的看出,笔者使用的 HARMONY 版本在该测试案例中速度更快(左图),但内存消耗更多(右图)。下一节将讲述如何输出报表,但或许你已经注意到了,代码非常简单。

     从上面的实例中我们已经看到 p-unit 的输出结果的两种形式,控制台和报表图片。默认情况下,p-unit 将输出到控制台。p-unit 采用事件机制,在运行器的每个节点都会提供通知事件。所有的输出都是通过注册事件响应器来实现的。这也表明了结果输出和运行器完全隔离,用户也可以定制自己的报表。p-unit 有 4 种内建输出,分别为控制台、文件、图片报表以及 PDF 报表。上一节的例子中我们已经看到图片报表,其代码为:
    清单 10. 添加 p-unit 总体图片报表

    CODE:

    runner.addPUnitEventListener(new OverviewReporter(new ImageRender())); p-unit 内建的报表有分三种不同的粒度:总体级别(OverviewReporter),TestSutie 级别(TestSuiteReporter),以及测试案例类级别(TestClassReporter)。这三种级别都可以输出图片格式或是 PDF 格式,因此,总共有六种类型的输出。上述的代码就是输出总体级别的图片。由于事件监听器是互相独立的,因此你可以既选择输出图片又选择输出 PDF 文件,只需再添加事件监听器即可:
    清单 11. 添加多个 p-unit 事件监听器

    CODE:


    runner.addPUnitEventListener(new OverviewReporter(new ImageRender()));
    runner.addPUnitEventListener(new OverviewReporter(new PDFRender()));
    总结
     至此,你是否基本理解了 p-unit 的概念呢?简单,易用,关注多线程,关注性能,这就是 p-unit。此外 p-unit 还有很多很好的小特性,如 Alphabetical 接口来保证执行测试函数的先后顺序等。使用 p-unit,让你的代码更健壮!

    nmtcolin 发表于:2008.03.22 14:42 ::分类: ( Testing ) ::阅读:(246次) :: 评论 (0)
    ===========================================================
    QA and Testing Interview Questions
    ===========================================================

    When interviewing for a QA or Testing position, it's important to be honest.

    Hiring managers want to know what you know, what you can do, and what you are like. And nobody wants to hire a liar.

    As a hiring manager, I can tell if you are stretching the truth - particularly if you are just repeating simple definitions to complex concepts.

    If you are asked about QA or Testing terms that aren't familar to you, tell the interviewer that you haven't heard of those terms, then ask what they mean. Since terms in this field are very company-specific, you may already know the concept, but just haven't heard the term before.

    If you are asked about a tool that you haven't used before, tell the interviewer that you haven't used it. Sometimes, you can point out other, similar tools that you have used. Usually, if you are capable of learning one tool, you are capable of learning many. And if you are good enough otherwise, many companies will hire you and train you on their tool of choice.

    That said, some people posting at SQAForms.com (where I help moderate) constantly ask about interview questions. There, moderators are discouraged from answering such questions, and discourage others from doing so.

    Here are some links which may help those who find value in such things. I will not vouch for the accuracy of any of the answers, nor that any of the questions make sense.

    But if you asked for help with interview questions, I sincerely hope this gives you what you are seeking. Good luck on your interview!

    http://www.sqablogs.com/jstrazzere/908/QA+and+Testing+Interview+Questions+%28and+some+answers%29.html


    nmtcolin 发表于:2008.03.19 09:36 ::分类: ( Testing ) ::阅读:(665次) :: 评论 (0)
    ===========================================================
    测试资源收藏
    ===========================================================

    http://www.developertesting.com/
    Developer Testing, Discussions about Software Quality

    http://www.junitfactory.com/
    JUnit Factory is a 2008 Jolt Productivity Award Winner!

    http://chinasoftesting.googlepages.com/home
    测试之家(测试工具, 测试资料, 软件测试, 配置管理, 过程管理, 资料下载)

     查看全文
    nmtcolin 发表于:2008.03.18 09:24 ::分类: ( Testing ) ::阅读:(57246次) :: 评论 (0)
    ===========================================================
    WinRunner - As a GUI based load testing tool
    ===========================================================

    We use WinRunner as a load testing tool operating at the GUI layer as it allows us to record and playback user actions from a vast variety of user applications as if a real user had manually executed those actions. We use WinRunner in addition to LoadRunner when we want to record user experience response time. Visit mercuryinteractive.com/products/WinRunner/ for detailed information on WinRunner.

    http://www.loadtest.com.au/Technology/winrunner.htm

    The following diagram shows how a GUI layer testing tool, such as WinRunner, operates.


    nmtcolin 发表于:2008.03.11 09:35 ::分类: ( Testing ) ::阅读:(2134次) :: 评论 (1)
    自我介绍
    切换风格
    新闻聚合
    博客日历
    文章归档...
    最新发表...
    博客统计...
    Blog信息
    网站链接...