日历
| |||||||||
| 日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
| 1 | 2 | 3 | 4 | 5 | 6 | ||||
| 7 | 8 | 9 | 10 | 11 | 12 | 13 | |||
| 14 | 15 | 16 | 17 | 18 | 19 | 20 | |||
| 21 | 22 | 23 | 24 | 25 | 26 | 27 | |||
| 28 | 29 | 30 | 31 | ||||||
搜索标题
最新来客
统计信息
- 访问量: 924
- 日志数: 15
- 建立时间: 2008-08-20
- 更新时间: 2008-11-17
我的最新日志
-
从 Jmeter输出数据导出excel表格
2008-11-17
时间匆忙,脚本未仔细测试
require 'rexml/document'
require 'win32ole'
include REXML$input_file_name = ""
$output_file_name = ""
$column_names = ["Sample number", "Response Time", "Latency Time", "Time Start", "Status", "URL", "Return Code", "Return Msg", "Thread Number", "Date Type", "Bytes"]def print_usage
puts "Usage: JmeterExtractor [JMeterResultFile] [ExcelFile]"
enddef check_input_file
if File.exist? $input_file_name
puts "input file "+ $input_file_name+" found"
else
puts "input file"+ $input_file_name+ " not found"
exit
end
enddef check_output_file
if File.exist? $output_file_name
puts "input file "+ $output_file_name+" found"
else
puts "input file"+ $output_file_name+ " not found"
exit
end
enddef init_excel
# -4100 is the value for the Excel constant xl3DColumn.
$ChartTypeVal = -4100;
# Creates OLE object to Excel
$excel = WIN32OLE.new("excel.application")
$excel.Visible = true
$excel.WorkBooks.Open($output_file_name)
worksheet = $excel.WorkSheets.Add();
worksheet.Activate
worksheet.name = Time.new.to_i.to_s
# $excel.WorkSheets("testResults").Activate
enddef close_excel
$excel.ActiveWorkbook.Close(1)
$excel.Quit()
enddef get_start_time time
usec = time % 1000
sec = time/1000
Time.at(sec).to_s + " " + usec.to_s + "ms"
enddef get_status s
if (s.eql? "true")
"success"
else
"fail"
end
enddef print_excel_title
$column_names.each_index do |i|
$excel.Cells(1, i+1).value = $column_names[i]
end
endarg_len = ARGV.length
#puts arg_len
case arg_len
when 0
$input_file_name = "C:/tool/jakarta-jmeter-2.3.1/workspace/1"
$output_file_name = "C:/tool/jakarta-jmeter-2.3.1/workspace/result.xls"
when 1
$input_file_name = ARGV[0];
$output_file_name = "C:/tool/jakarta-jmeter-2.3.1/workspace/result.xls"
when 2
$input_file_name = ARGV[0];
$output_file_name = ARGV[1];
else
end
#puts $input_file_name
#puts $output_file_name
check_input_file
check_output_file
init_excel
input_file = File.new($input_file_name);
doc = Document.new(input_file)
$element_index = 0
doc.elements.each("//httpSample") do |e|
$element_index += 1
print e.attributes["t"]
print " "
print e.attributes["lt"]
print " "
print e.attributes["ts"]
print " "
print e.attributes["s"]
print " "
print e.attributes["lb"]
print " "
print e.attributes["rc"]
print " "
print e.attributes["rm"]
print " "
print e.attributes["tn"]
print " "
print e.attributes["dt"]
print " "
print e.attributes["by"]
puts
STDOUT.flush
print_excel_title
$excel.Cells($element_index+1, 1).value = $element_index
$excel.Cells($element_index+1, 2).value = e.attributes["t"]
$excel.Cells($element_index+1, 3).value = e.attributes["lt"]
$excel.Cells($element_index+1, 4).value = get_start_time(e.attributes["ts"].to_i)
$excel.Cells($element_index+1, 5).value = get_status(e.attributes["s"])
$excel.Cells($element_index+1, 6).value = e.attributes["lb"]
$excel.Cells($element_index+1, 7).value = e.attributes["rc"]
$excel.Cells($element_index+1, 8).value = e.attributes["rm"]
$excel.Cells($element_index+1, 9).value = e.attributes["tn"]
$excel.Cells($element_index+1, 10).value = e.attributes["dt"]
$excel.Cells($element_index+1, 11).value = e.attributes["by"]
endclose_excel
-
jar内的类如何读取jar内的配置文件
2008-11-17
以xml为例:
JarFile jarFile = new JarFile(getClass().getProtectionDomain().getCodeSource().getLocation().getFile().toString());
JarEntry entry = jarFile.getJarEntry(internalConfigPath);
document = saxReader.read(jarFile.getInputStream(entry));
jarFile.close(); -
TestNG 标签小结
2008-10-16
@Configuration 这个标签只在早期版本使用,已被弃用
@BeforeSuite 测试套件前执行,测试套件在testng.xml中定义
@AfterSuite 测试套件后执行,测试套件在testng.xml中定义
@BeforeTest 整个测试开始前执行
@AfterTest 整个测试结束后执行
@BeforeGroups 属于指定的组的第一个测试方法执行前发生
@AfterGroups 属于指定的组的最后一个测试方法执行后发生
@BeforeClass 当前测试类执行前发生
@AfterClass 当前测试类执行后发生
@BeforeMethod 每个测试方法执行前发生
@AfterMethod 每个测试方法执行后发生参数:
alwaysRun 对于before类的方法来说该参数为真表示不管该方法属于哪个组都会执行;对于before类的方法来说该参数为真表示上一个测试方法无论失败或跳过都不影响这个方法的执行
dependsOnGroups 等某些组的方法执行完后执行
dependsOnMethods 等某些方法执行完后执行
enabled 为真时激活
groups 从属的组
inheritGroups 继承定义在类的级别的组
@DataProvider 数据源,标记的方法必须返回Object[][]类型。每个Object[]可以是一个参数列表。
参数:
Name 数据源名称
//This method will provide data to any test method that declares that its Data Provider
//is named "test1"
@DataProvider(name = "test1")
public Object[][] createData1() {
return new Object[][] {
{ "Cedric", new Integer(36) },
{ "Anne", new Integer(37)},
};
}
//This test method declares that its data should be supplied by the Data Provider
//named "test1"
@Test(dataProvider = "test1")
public void verifyData1(String n1, Integer n2) {
System.out.println(n1 + " " + n2);
}public static class StaticProvider {
@DataProvider(name = "create")
public static Object[][] createData() {
return new Object[][] {
new Object[] { new Integer(42) }
}
}
}
public class MyTest {
@Test(dataProvider = "create", dataProviderClass = StaticProvider.class)
public void test(Integer n) {
// ...
}
}@Factory 标记工厂方法,产生测试类,返回Object[]类型
public class WebTestFactory {
@Factory
public Object[] createInstances() {
Object[] result = new Object[10];
for (int i = 0; i < 10; i++) {
result[i] = new WebTest(i * 10);
return result;
}
}and the new test class is now:
public class WebTest {
private int m_numberOfTimes;
public WebTest(int numberOfTimes) {
m_numberOfTimes = numberOfTimes;
}
@Test
public void testServer() {
for (int i = 0; i < m_numberOfTimes; i++) {
// access the web page
}
}
}@Parameters 描述如何向测试方法传递参数
参数:
value 一组变量来填满该方法的参数
@Parameters({ "first-name" })
@Test
public void testSingleString(String firstName) {@Parameters("db")
@Test
public void testNonExistentParameter(@Optional("mysql") String db)@Test 测试方法或测试类
参数:
alwaysRun 所依赖的方法即便失败了也会执行
dataProvider 指定数据源名称
dataProviderClass 从指定类找数据源,不指定则从当前类或父类中找
dependsOnGroups 依赖的组
@Test(groups = { "init" })
public void serverStartedOk() {}
@Test(groups = { "init" })
public void initEnvironment() {}
@Test(dependsOnGroups = { "init.* })
public void method1() {}dependsOnMethods 依赖的方法
@Test
public void serverStartedOk() {}
@Test(dependsOnMethods = { "serverStartedOk" })
public void method1() {}descrīption 方法的描述
enabled 是否有效
expectedExceptions 期望抛出的异常,如果无异常或不同的异常抛出该测试失败
groups 所属的组
@Test(groups = { "functest", "checkintest" })
invocationCount 该方法调用的次数
@Test(threadPoolSize = 3, invocationCount = 10, timeOut = 10000)
public void testServer() {invocationTimeOut 该测试方法的最大执行时间总时间,是多次调用的累加
successPercentage 期望的成功比例
sequential 仅对类一级的标记有效,为真时表示该类中所有方法顺序执行。
timeOut 整个测试的最大执行总时间
threadPoolSize 线程池大小。该测试方法按invocationCount的值启动多线程
-
Web Service 性能测试, soapUI还是Jmeter?
2008-9-17
经常有人问我web service的性能测试是用JMeter好还是SoapUI好。说句实话这两款都是非常优秀的开源Web Service性能测试工具,简单地说哪个更好真不太容易。影响Web Service性能测试的因素太多到底谁的结果更准确一些很多时候并不主要取决于测试工具。在soapUI官方网站上有一个文章比较了这两款工具,我将要点抽出来加以分析希望能反映它们的特点。
JMeter在整个负载测试的优越性是毋庸置疑的,它覆盖了常见的各种测试类型,如HTTP, JDBC, JMS 和SOAP。单就Web Service测试,作者做了一个简单的实验,但并没有涉及太多的细节。
试验准备:本地Web Service,运行于JBoss 4.0.3SP1,每个简单请求在4种不同负载下执行5000次,分别是1线程,5线程,10线程和25线程。在SoapUI中为简单起见均使用简单负载策略,并且五执行延时。要分别记录关闭连接和非关闭连接方式的数据。关闭连接方式是指每次请求完毕后关闭连接。反之则是让连接仍然保持打开以等待下个请求,显然会省去很多额外开销。在JMeter中也可以做类似配置,如线程数为1,循环次数5000或线程数25,循环200次。
环境:WinXP SP2, Pentium M 1.8 1 G RAM, JRE 1.5.0_06.
结果:
Threads
jmeter
soapUI
soapUI (*)
soapUI cmdline
soapUI cmdline (*)
1
8 ms, 105 TPS
6.78 ms, 147 TPS
10.7 ms, 94 TPS
5.75 ms, 174 TPS
10 ms, 99 TPS
5
43 ms, 110 TPS
38.7 ms, 128 TPS
23.7 ms, 211 TPS
30.4 ms, 164 TPS
24 ms, 210 TPS
10
86 ms, 112 TPS
82 ms, 122 TPS
46.5 ms, 215 TPS
61 ms, 164 TPS
38 ms, 262 TPS
25
214 ms, 114 TPS
204 ms, 123 TPS
124 ms, 202 TPS
159 ms, 157 TPS
95 ms, 263 TPS
其中带*的是非关闭连接模式下测试的结果。从结果中看出Jmeter的测试值均较SoapUI偏大,但与UI连接关闭模式下执行结果相差无几。实验未给出JMeter命令行下的测试结果。但从经验来讲,命令行执行方式避免了测试工具本身带来的巨大资源消耗,更接近真实值。soapUI在命令行连接不关闭模式下TPS随线程的增加在初期有明显上升的。
从计时机制来看,JMeter 用的是System.currentTimeMillis(),而soapUI用的是更为精确的System.nanoTime().
综上所述(文中没有点明,但这是显而易见的),soapUI在单纯的Web Service 测试时有明显的优势,当要综合其他测试时可以组合使用多种工具。
当然这是soapUI自己做的实验,难免有王婆卖瓜之嫌,有兴趣的朋友可以自己设计实验来测试一下。
-
oracle 系统表摘要
2008-9-01
dba组的表需要以dba权限访问
dba_users 用户
dba_data_files 数据文件
dba_tablespaces 表空间
dba_free_space 空闲表空间
dba_objects 数据库所有对象
dba_tables 所有表
dba_extents
user_tab_columns 所有列
dba_indexes 索引
dba_ind_columns 索引列
user_indexes
user_ind_columns
dba_sequences 序列
dba_views
all_views 视图
dba_clusters 簇
dba_snapshots 快照
dba_trigers 触发器
user_source
user_errors
user_constraints 约束
user_jobs 作业
dba_jobs
user_jobs_running
-
好书学习:极限编程释疑--拥抱变更 3
2008-8-25
第二章 一个典型的开发场景
本章作者用一段开发人员之间的对话来阐述了几个在极限编程和敏捷开发中极为重要的概念:
1。Pair Programming,结对编程,有助于提高效率和减少错误,这个模式经常听说,但好像在国内很少看到
2。测试驱动开发,先写测试,由于还没有代码实现,测试肯定 fail, 然后加少量代码,再写测试,再做实现,如此循环,直到你无法想到新的测试,现有的测试也都通过了,这个模块才算完成了。好处是不会写多余无用的代码,也不容易漏掉有用的代码,显著的问题会很早被发现。开发人员在进入到下个模块的开发时对已完成的部分有充足的信心。
3。结对编程并不只做实现和测试,其实设计也是在这个过程中演化成熟的。这是一种典型的“小设计”模式。
4。持续集成。新功能一完成立即与老功能集成并测试。 -
好书学习:极限编程释疑--拥抱变更 2
2008-8-25
第一章:风险,最根本的问题
软件开发面临以下问题:
1。延期
2。过度延期造成项目取消
3。没用多久就因为费用或质量问题被取代
4。缺陷太多无人问津
5。不能满足业务需求
6。业务需求出现变更
7。很多费大劲做的软件功能没有最终实现商业利益
8。人员变更,项目人员感到厌烦而离开
极限编程解决以上问题:
1。极限编程采用短迭代周期,任务划分成1-3天的粒度,功能划分优先级,一旦延期损失的只是最次要的方面。
2。快速的迭代和版本发布使问题及早暴露,迅速调整,不至于问题恶化到项目中止
3。极限编程用一整套测试来保证系统有一个质量基线,那么后来的变更也不至于严重损坏该系统。(即便出了问题,还可以退回到原有系统)
4。在极限编程中测试贯穿始终,从单元测试到系统测试,保证了低缺陷率
5。客户是团队的一部分。由于客户是对需求最熟悉的人,他们的参与和持续反馈保证了建造的系统不会脱离实际的业务需求
6。在短迭代周期的模式下,只需要做少量工作既可应对需求变更。对很多极限编程的工程师来说几乎感觉不到变更的困扰
7。坚持最大商业价值的功能先实现
8。每个成员可以对工作量作预估,并持续提高估计的能力,避免由于估计不足造成的强制加班;也鼓励组织内部沟通,消除“孤独感”。新成员循序渐进地融入项目。
要解决以上问题要求所有的人,包括开发人员,项目经理和客户对极限编程的新准则认可和接受,并在实践中贯彻始终。 -
好书学习:极限编程释疑--拥抱变更 1
2008-8-25
作者背景:
Kent Beck,在俄勒冈大学获得计算机科学硕士学位。极限编程的创始人,是敏捷开发17个最初申明人之一,倡导了测试驱动开发,和Eric Gamma共同创建了JUnit单元测试框架,1999年和2003年两度获得Jolt奖。
著作列表:
书:
* Smalltalk Best Practice Patterns. Prentice Hall, 1996. ISBN 0-13-476904-X.
* Kent Beck's Guide to Better Smalltalk : A Sorted Collection. Cambridge University Press, 1998. ISBN 0-521-64437-2.
* Extreme Programming Explained: Embrace Change. Addison-Wesley, 2000. ISBN 0-201-61641-6. Second edition 2005 with Cynthia Andres. ISBN 0-321-27865-8. (Jolt productvity award 1999 [2])
* Planning Extreme Programming. With Martin Fowler. Addison-Wesley, 2000. ISBN 0-201-71091-9.
* Test-Driven Development: By Example. Addison-Wesley, 2002. ISBN 0-321-14653-0. (Jolt productvity award 2003 [3])
* Contributing to Eclipse: Principles, Patterns, and Plugins. With Erich Gamma. Addison-Wesley, 2003. ISBN 0-321-20575-8.
* JUnit Pocket Guide. O'Reilly, 2004. ISBN 0-596-00743-4.
* Implementation Patterns. Addison-Wesley, 2008. ISBN 0-321-41309-1.
论文:
* Using Pattern Languages for Object-Oriented Programs. With Ward Cunningham. OOPSLA'87.
* A Laboratory For Teaching Object-Oriented Thinking. With Ward Cunningham. OOPSLA'89.
* Simple Smalltalk Testing: With Patterns. Origins of xUnit frameworks. -
如何用Ruby连接SQL Server 2005
2008-8-25
require 'win32ole'
connection = WIN32OLE.new('ADODB.Connection')
connection.open("Provider=SQLOLEDB.1;User ID=sa;password=xxxx;Data Source=localhost,1433;Initial Catalog=mydb")
最重要的一点是即使默认端口1433也要加上,不然会报错:
sql.rb:27:in `method_missing': open (WIN32OLERuntimeError)
OLE error code:80004005 in Microsoft OLE DB Provider for SQL Server
[DBNETLIB][ConnectionOpen (Invalid Instance()).]Invalid connection.
HRESULT error code:0x80020009
Exception occurred. from sql.rb:27:in `open'
from sql.rb:63 -
Sql server 2005 express 的数据导出
2008-8-21
Microsoft Sql Server Management Studio Express在独立安装下只提供表结构的查询导出,要备份数据就只能备份整个数据库。在测试中有时我们需要向开发提供测试数据以供缺陷重现,庞大的数据库备份文件就不太方便了。数据转换向导DTSWizzard提供了这个功能。这个工具在MS SQL Server 2005 Express Toolkit 包中。事实上当完整安装Toolkit时Management Studio也同时装上了。下面是Toolkit SP2 英文版的官方下载地址:
http://www.microsoft.com/downloads/details.aspx?FamilyID=E8AD606A-0960-4EFD-8BD7-B21370C7BE2B&displaylang=en
要注意的是在安装前要将原先安装的Management Studio 卸载干净,否则可能会导致安装失败。
