<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>闫鹏 blog &#187; 程序员</title>
	<atom:link href="http://www.mirecle.com/category/programming/feed" rel="self" type="application/rss+xml" />
	<link>http://www.mirecle.com</link>
	<description>it,技术,经济生活,互联网</description>
	<lastBuildDate>Wed, 16 Mar 2011 06:39:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>php中数组与字符串</title>
		<link>http://www.mirecle.com/2011/03/16/php-array-with-string.html</link>
		<comments>http://www.mirecle.com/2011/03/16/php-array-with-string.html#comments</comments>
		<pubDate>Wed, 16 Mar 2011 06:35:50 +0000</pubDate>
		<dc:creator>闫鹏</dc:creator>
				<category><![CDATA[程序员]]></category>
		<category><![CDATA[软件测试]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.mirecle.com/?p=96189</guid>
		<description><![CDATA[因为php的语法要求不严格，字符串也可以当数组使用，这样就存在一个问题：当使用非数字作为key访问字符串中的内容时，就可能会带来一些不一致的情况，如下面的代码 $hello = "hello"; var_dump($hello['abc']); var_dump($hello['0']); var_dump($hello['1abc']); var_dump($hello['12abc']);﻿ 输出的结果就不说了，简单运行一下就可以知道，我想原因是由intval这个东东引起的，时间关系，没有去确认zend的代码，不过下面代码的运行结果页说明了一些问题 var_dump(intval('abc')); var_dump(intval('0')); var_dump(intval('1abc')); var_dump(intval('12abc')); 这个东东，对code review或者测试时候是一个很有杀伤力的bug，如果一个函数设计的返回值不好，有时候返回数组，有时候返回字符串，在使用之前，就一定要先判断返回结果是否为数组，否则就会在这个bug上杯具 本文永久链接:http://www.mirecle.com/2011/03/16/php-array-with-string.html [发表评论] 您可能会喜欢:php中getopt的缺陷及修复 php反射效果:基类访问子类数据 php中set names与mysql_set_charset


您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/05/17/php-and-repair-defects-in-the-getopt.html' rel='bookmark' title='Permanent Link: php中getopt的缺陷及修复'>php中getopt的缺陷及修复</a></li>
<li><a href='http://www.mirecle.com/2010/01/18/php-reflection-effect-the-base-class-to-access-sub-categories-of-data.html' rel='bookmark' title='Permanent Link: php反射效果:基类访问子类数据'>php反射效果:基类访问子类数据</a></li>
<li><a href='http://www.mirecle.com/2010/04/13/php-in-the-set-names-and-mysql_set_charset.html' rel='bookmark' title='Permanent Link: php中set names与mysql_set_charset'>php中set names与mysql_set_charset</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<p>因为php的语法要求不严格，字符串也可以当数组使用，这样就存在一个问题：当使用非数字作为key访问字符串中的内容时，就可能会带来一些不一致的情况，如下面的代码</p>
<pre class="brush:php">
$hello = "hello";
var_dump($hello['abc']);
var_dump($hello['0']);
var_dump($hello['1abc']);
var_dump($hello['12abc']);﻿
</pre>
<p>输出的结果就不说了，简单运行一下就可以知道，我想原因是由intval这个东东引起的，时间关系，没有去确认zend的代码，不过下面代码的运行结果页说明了一些问题</p>
<pre class="brush:php">
var_dump(intval('abc'));
var_dump(intval('0'));
var_dump(intval('1abc'));
var_dump(intval('12abc'));
</pre>
<p>这个东东，对code review或者测试时候是一个很有杀伤力的bug，如果一个函数设计的返回值不好，有时候返回数组，有时候返回字符串，在使用之前，就一定要先判断返回结果是否为数组，否则就会在这个bug上杯具</p>
本文永久链接:<a href="http://www.mirecle.com/2011/03/16/php-array-with-string.html">http://www.mirecle.com/2011/03/16/php-array-with-string.html</a>
<br/>
[<a href="http://www.mirecle.com/2011/03/16/php-array-with-string.html#respond">发表评论</a>]

<p>您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/05/17/php-and-repair-defects-in-the-getopt.html' rel='bookmark' title='Permanent Link: php中getopt的缺陷及修复'>php中getopt的缺陷及修复</a></li>
<li><a href='http://www.mirecle.com/2010/01/18/php-reflection-effect-the-base-class-to-access-sub-categories-of-data.html' rel='bookmark' title='Permanent Link: php反射效果:基类访问子类数据'>php反射效果:基类访问子类数据</a></li>
<li><a href='http://www.mirecle.com/2010/04/13/php-in-the-set-names-and-mysql_set_charset.html' rel='bookmark' title='Permanent Link: php中set names与mysql_set_charset'>php中set names与mysql_set_charset</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mirecle.com/2011/03/16/php-array-with-string.html/feed</wfw:commentRss>
		<slash:comments>20</slash:comments>
		</item>
		<item>
		<title>opentest的几个效率改进关注点</title>
		<link>http://www.mirecle.com/2010/10/22/opentest-imporve.html</link>
		<comments>http://www.mirecle.com/2010/10/22/opentest-imporve.html#comments</comments>
		<pubDate>Fri, 22 Oct 2010 10:13:57 +0000</pubDate>
		<dc:creator>闫鹏</dc:creator>
				<category><![CDATA[互联网]]></category>
		<category><![CDATA[程序员]]></category>
		<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.mirecle.com/?p=96172</guid>
		<description><![CDATA[软件测试既然是软件工程中的一部分，同样也会有遇到软件开发过程中的那些问题，总结这些问题加以分析，并解决或者缓解，会使团队的效率提高不少。 1.沟通 这里所说的问题，是指测试团队qa之间的沟通。就像《人月神话》里面谈到的问题一样，测试团队中成员之间的沟通，也是要消耗时间的，有时候还会存在信息丢失。比如工作的交接，模块A以前是甲测试的，现在要交接给乙。如果甲所做的工作没有形成足够详细的文档（通常文档都不会是足够详细的，尤其是在互联网企业），那么甲乙之间必定会消耗时间在沟通上面。不过这个东东是可以通过规范化文档来缓解的：比如测试用例的描述，可以用一些规范的格式；测试脚本的部署执行，可以使用一个测试框架来解决。 2.自动化 这个应该是个永恒不变的话题了，效率永远没有最好。对于测试工程师来说，使用自动化回归测试用例，能够在很大程度上提高效率。有的时候自动化也是没有好处的，比如一个系统，半年都不升级一次，要自动化回归，反而会更加消耗时间与经历。对于经常升级改动的系统，自动化的好处就不用说了，但是自动化的测试用例也是需要维护的，不维护的用例失效后反而浪费了创建用例的时间。 3.测试部署 现代软件系统通常都是很多子模块之间相互依赖的，而经常都是升级的这个模块，还会依赖于系统中另外的很多模块，这个问题在rd开发时候，遇到的问题可能更严重，经常遇到的情况就是环境中都是坏数据，连调困难。qa遇到的问题要比rd的简单很多，毕竟提测的东西都是rd调试过的，所以集成环境的问题是一个简单的问题，只要控制环境中的版本部署以及数据修改即可。但因为很多原因（比case的前置条件，避免损坏集成环境的数据等）会导致需要把模块不放在环境中测试，提供一些自动化部署的东东也能够节省很多时间。这个在有些大公司，是直接有软件支持测试的，也可以自己开发一个测试框架来解决问题 opentest在一定程度上解决或者缓解了上面三个问题，但是与此同时，也带来了一些问题，有些case的检查点越来越多，比如核心系统的，要检查1000项数据，这样的case，很明显，对于测试工程师的工作量需求是巨大的，不过幸好case的描述是标准化的，可以借助工具生成case，进一步提高效率。 本文永久链接:http://www.mirecle.com/2010/10/22/opentest-imporve.html [发表评论] 您可能会喜欢:opentest之路 怀念 软件测试-了解被测对象


您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/09/06/opentest-the-road.html' rel='bookmark' title='Permanent Link: opentest之路'>opentest之路</a></li>
<li><a href='http://www.mirecle.com/2010/07/23/miss.html' rel='bookmark' title='Permanent Link: 怀念'>怀念</a></li>
<li><a href='http://www.mirecle.com/2010/09/29/software-testing-learn-about-the-measured-object.html' rel='bookmark' title='Permanent Link: 软件测试-了解被测对象'>软件测试-了解被测对象</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<p>软件测试既然是软件工程中的一部分，同样也会有遇到软件开发过程中的那些问题，总结这些问题加以分析，并解决或者缓解，会使团队的效率提高不少。</p>
<p><strong>1.沟通</strong></p>
<p>这里所说的问题，是指测试团队qa之间的沟通。就像《人月神话》里面谈到的问题一样，测试团队中成员之间的沟通，也是要消耗时间的，有时候还会存在信息丢失。比如工作的交接，模块A以前是甲测试的，现在要交接给乙。如果甲所做的工作没有形成足够详细的文档（通常文档都不会是足够详细的，尤其是在互联网企业），那么甲乙之间必定会消耗时间在沟通上面。不过这个东东是可以通过规范化文档来缓解的：比如测试用例的描述，可以用一些规范的格式；测试脚本的部署执行，可以使用一个测试框架来解决。</p>
<p><strong>2.自动化</strong></p>
<p>这个应该是个永恒不变的话题了，效率永远没有最好。对于测试工程师来说，使用自动化回归测试用例，能够在很大程度上提高效率。有的时候自动化也是没有好处的，比如一个系统，半年都不升级一次，要自动化回归，反而会更加消耗时间与经历。对于经常升级改动的系统，自动化的好处就不用说了，但是自动化的测试用例也是需要维护的，不维护的用例失效后反而浪费了创建用例的时间。</p>
<p><strong>3.测试部署</strong></p>
<p>现代软件系统通常都是很多子模块之间相互依赖的，而经常都是升级的这个模块，还会依赖于系统中另外的很多模块，这个问题在rd开发时候，遇到的问题可能更严重，经常遇到的情况就是环境中都是坏数据，连调困难。qa遇到的问题要比rd的简单很多，毕竟提测的东西都是rd调试过的，所以集成环境的问题是一个简单的问题，只要控制环境中的版本部署以及数据修改即可。但因为很多原因（比case的前置条件，避免损坏集成环境的数据等）会导致需要把模块不放在环境中测试，提供一些自动化部署的东东也能够节省很多时间。这个在有些大公司，是直接有软件支持测试的，也可以自己开发一个测试框架来解决问题</p>
<p>opentest在一定程度上解决或者缓解了上面三个问题，但是与此同时，也带来了一些问题，有些case的检查点越来越多，比如核心系统的，要检查1000项数据，这样的case，很明显，对于测试工程师的工作量需求是巨大的，不过幸好case的描述是标准化的，可以借助工具生成case，进一步提高效率。</p>
本文永久链接:<a href="http://www.mirecle.com/2010/10/22/opentest-imporve.html">http://www.mirecle.com/2010/10/22/opentest-imporve.html</a>
<br/>
[<a href="http://www.mirecle.com/2010/10/22/opentest-imporve.html#respond">发表评论</a>]

<p>您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/09/06/opentest-the-road.html' rel='bookmark' title='Permanent Link: opentest之路'>opentest之路</a></li>
<li><a href='http://www.mirecle.com/2010/07/23/miss.html' rel='bookmark' title='Permanent Link: 怀念'>怀念</a></li>
<li><a href='http://www.mirecle.com/2010/09/29/software-testing-learn-about-the-measured-object.html' rel='bookmark' title='Permanent Link: 软件测试-了解被测对象'>软件测试-了解被测对象</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mirecle.com/2010/10/22/opentest-imporve.html/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>软件测试-了解被测对象</title>
		<link>http://www.mirecle.com/2010/09/29/software-testing-learn-about-the-measured-object.html</link>
		<comments>http://www.mirecle.com/2010/09/29/software-testing-learn-about-the-measured-object.html#comments</comments>
		<pubDate>Wed, 29 Sep 2010 07:09:59 +0000</pubDate>
		<dc:creator>闫鹏</dc:creator>
				<category><![CDATA[程序员]]></category>
		<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.mirecle.com/?p=96165</guid>
		<description><![CDATA[在软件测试之前，要先清楚的了解被测对象才行，通常情况下，我们都是用下面这样的环节进行： 1.了解系统架构。这个应该是前提条件，一个新同学入职到项目组后，肯定是要先了解现有系统才行，不了解现有系统，很难清楚团队中的设计风格与习惯。了解了系统架构，才能知道自己要测试的模块处在什么位置，为系统提供什么样的功能，系统对它有什么要求。清楚了这些，才能知道自己要做事情的针对性。 2.明确需求。需求一般是由pm提出的，一般会组织需求评审，在评审过程中，明确pm的当前需求，对未来可能的需求进行估计。明确需求后，就能知道现有系统需要做哪些改动，对大致的工作量与项目的时间有一个估计。有时候，需要改变或者拒绝需求，比如对于一个支付系统来说，如果pm提出的需求对账户安全有影响，就应该坚持原则，对此提出质疑，要求改变需求。 3.参与系统设计流程。这个时候一般是开发(rd)同学自己先设计一套或者多套方案，随后进行设计评审。评审过程中，qa同学也是要多多参与的，在把握需求的基础上，对设计提出一些建议与意见，与此同时，对测试方面的工作量也能进一步细化。有时候，采用好的建议可以同时节省开发与测试双发的工作。在此过程中，qa同学应该自己从rd的角度思考，不要被动接受rd的设计，可以想象成，如果需求摆在自己面前，自己会怎么做，这样才能充分理解设计，为自己的测试工作打下良好的铺垫。同时多了解系统内部，也有利于自身的职业发展。 4.case设计步骤。根据rd的设计文档，设计测试用例。在这个环节中，沟通与文档是两个重要内容，遇到不清楚的细节，一定要与rd沟通，不要自己猜，否则会造成杯具。如果rd没有文档，可以自己记录个邮件，避免忘记和rd反悔的现象。 5.提测。除了上面几步确认的内容，还要再确认一下rd有没有“顺手”做了其它地方的改动。如果有的话，一定要在送测流程单里面写清楚，同时qa也要与rd沟通清楚，避免出现漏测的情况。 本文永久链接:http://www.mirecle.com/2010/09/29/software-testing-learn-about-the-measured-object.html [发表评论] 您可能会喜欢:opentest的几个效率改进关注点 事情不是这么做的 冲动是魔鬼


您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/10/22/opentest-imporve.html' rel='bookmark' title='Permanent Link: opentest的几个效率改进关注点'>opentest的几个效率改进关注点</a></li>
<li><a href='http://www.mirecle.com/2010/08/10/do-not-do-it.html' rel='bookmark' title='Permanent Link: 事情不是这么做的'>事情不是这么做的</a></li>
<li><a href='http://www.mirecle.com/2009/10/10/impulse-is-the-devil.html' rel='bookmark' title='Permanent Link: 冲动是魔鬼'>冲动是魔鬼</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<p>在软件测试之前，要先清楚的了解被测对象才行，通常情况下，我们都是用下面这样的环节进行：</p>
<p>1.了解系统架构。这个应该是前提条件，一个新同学入职到项目组后，肯定是要先了解现有系统才行，不了解现有系统，很难清楚团队中的设计风格与习惯。了解了系统架构，才能知道自己要测试的模块处在什么位置，为系统提供什么样的功能，系统对它有什么要求。清楚了这些，才能知道自己要做事情的针对性。</p>
<p>2.明确需求。需求一般是由pm提出的，一般会组织需求评审，在评审过程中，明确pm的当前需求，对未来可能的需求进行估计。明确需求后，就能知道现有系统需要做哪些改动，对大致的工作量与项目的时间有一个估计。有时候，需要改变或者拒绝需求，比如对于一个支付系统来说，如果pm提出的需求对账户安全有影响，就应该坚持原则，对此提出质疑，要求改变需求。</p>
<p>3.参与系统设计流程。这个时候一般是开发(rd)同学自己先设计一套或者多套方案，随后进行设计评审。评审过程中，qa同学也是要多多参与的，在把握需求的基础上，对设计提出一些建议与意见，与此同时，对测试方面的工作量也能进一步细化。有时候，采用好的建议可以同时节省开发与测试双发的工作。在此过程中，qa同学应该自己从rd的角度思考，不要被动接受rd的设计，可以想象成，如果需求摆在自己面前，自己会怎么做，这样才能充分理解设计，为自己的测试工作打下良好的铺垫。同时多了解系统内部，也有利于自身的职业发展。</p>
<p>4.case设计步骤。根据rd的设计文档，设计测试用例。在这个环节中，沟通与文档是两个重要内容，遇到不清楚的细节，一定要与rd沟通，不要自己猜，否则会造成杯具。如果rd没有文档，可以自己记录个邮件，避免忘记和rd反悔的现象。</p>
<p>5.提测。除了上面几步确认的内容，还要再确认一下rd有没有“顺手”做了其它地方的改动。如果有的话，一定要在送测流程单里面写清楚，同时qa也要与rd沟通清楚，避免出现漏测的情况。</p>
本文永久链接:<a href="http://www.mirecle.com/2010/09/29/software-testing-learn-about-the-measured-object.html">http://www.mirecle.com/2010/09/29/software-testing-learn-about-the-measured-object.html</a>
<br/>
[<a href="http://www.mirecle.com/2010/09/29/software-testing-learn-about-the-measured-object.html#respond">发表评论</a>]

<p>您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/10/22/opentest-imporve.html' rel='bookmark' title='Permanent Link: opentest的几个效率改进关注点'>opentest的几个效率改进关注点</a></li>
<li><a href='http://www.mirecle.com/2010/08/10/do-not-do-it.html' rel='bookmark' title='Permanent Link: 事情不是这么做的'>事情不是这么做的</a></li>
<li><a href='http://www.mirecle.com/2009/10/10/impulse-is-the-devil.html' rel='bookmark' title='Permanent Link: 冲动是魔鬼'>冲动是魔鬼</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mirecle.com/2010/09/29/software-testing-learn-about-the-measured-object.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>opentest之路</title>
		<link>http://www.mirecle.com/2010/09/06/opentest-the-road.html</link>
		<comments>http://www.mirecle.com/2010/09/06/opentest-the-road.html#comments</comments>
		<pubDate>Mon, 06 Sep 2010 06:20:28 +0000</pubDate>
		<dc:creator>闫鹏</dc:creator>
				<category><![CDATA[程序员]]></category>
		<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.mirecle.com/?p=96156</guid>
		<description><![CDATA[opentest推出后，成为了大家测试server的主要测试框架，除了百付宝的那些老的没有升级的server，几乎所有server，部分脚本都已经是通过opentest来测试了，我们的case文件打成tar.gz的压缩包，现在也有200多兆了。opentest解决了case维护，部署，人员变更等问题，但没有考虑过提高测试用例编写效率的问题。随着核心系统越来越复杂，一次命令交互即一个case需要检查的内容可能有上千项，这对于编写case的qa同学来说，逐一编写case检查点，确实已经成为了负担。 没错，自动化测试是有代价的，多数情况下也会导致首次测试时消耗的时间变长，但提高case书写的效率还是很有必要的。opentest在这件事情上面，可以分为三步走： 1.校验数据的生成。在执行case的时候，帮助qa生成需要校验的数据，这样qa同学只需要将它cp到case文件中就可以了。但这样做是有一定风险的，生成的数据是根据核心系统结果来做的，如果过于自动化，出来的数据又错误，又不注意看，就会造成漏测，所以需要在里面内置一些校验规则，对于不满足规则的数据报错，避免出现漏测的情况 2.自动机生成case。对于“创建-支付-确认”这样一个简单的例子来说，支付的前提数据条件就是创建的结果，qa同学只需要画出自动机，由工具生成case文件，将case文件放在opentest中跑一下即可达到测试目的了。而opentest的case文件因为是格式化的，天然的支持这样case生成工具的编写。 3.结合fuzz测试。fuzz测试可以是框架的进一步发展，第二步能够保证关键的正常流程是ok的，使用fuzz测试，不用qa同学思考各种测试用例的情况，直接向被测模块发送各种可能的数据情况。其实fuzz测试是一个很有效的东东，可以测试出很多非常难以发现的问题。 这三步做完后，我想opentest也可以成为一个比较完善的测试框架了，能够在很大程度上提高测试效率。 本文永久链接:http://www.mirecle.com/2010/09/06/opentest-the-road.html [发表评论] 您可能会喜欢:opentest的几个效率改进关注点 Opentest测试框架 什么样的测试用例是好的


您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/10/22/opentest-imporve.html' rel='bookmark' title='Permanent Link: opentest的几个效率改进关注点'>opentest的几个效率改进关注点</a></li>
<li><a href='http://www.mirecle.com/2009/12/02/opentest-testing-framework.html' rel='bookmark' title='Permanent Link: Opentest测试框架'>Opentest测试框架</a></li>
<li><a href='http://www.mirecle.com/2010/08/23/what-is-a-good-test-case.html' rel='bookmark' title='Permanent Link: 什么样的测试用例是好的'>什么样的测试用例是好的</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<p>opentest推出后，成为了大家测试server的主要测试框架，除了百付宝的那些老的没有升级的server，几乎所有server，部分脚本都已经是通过opentest来测试了，我们的case文件打成tar.gz的压缩包，现在也有200多兆了。opentest解决了case维护，部署，人员变更等问题，但没有考虑过提高测试用例编写效率的问题。随着核心系统越来越复杂，一次命令交互即一个case需要检查的内容可能有上千项，这对于编写case的qa同学来说，逐一编写case检查点，确实已经成为了负担。</p>
<p>没错，自动化测试是有代价的，多数情况下也会导致首次测试时消耗的时间变长，但提高case书写的效率还是很有必要的。opentest在这件事情上面，可以分为三步走：</p>
<p>1.校验数据的生成。在执行case的时候，帮助qa生成需要校验的数据，这样qa同学只需要将它cp到case文件中就可以了。但这样做是有一定风险的，生成的数据是根据核心系统结果来做的，如果过于自动化，出来的数据又错误，又不注意看，就会造成漏测，所以需要在里面内置一些校验规则，对于不满足规则的数据报错，避免出现漏测的情况</p>
<p>2.自动机生成case。对于“创建-支付-确认”这样一个简单的例子来说，支付的前提数据条件就是创建的结果，qa同学只需要画出自动机，由工具生成case文件，将case文件放在opentest中跑一下即可达到测试目的了。而opentest的case文件因为是格式化的，天然的支持这样case生成工具的编写。</p>
<p>3.结合fuzz测试。fuzz测试可以是框架的进一步发展，第二步能够保证关键的正常流程是ok的，使用fuzz测试，不用qa同学思考各种测试用例的情况，直接向被测模块发送各种可能的数据情况。其实fuzz测试是一个很有效的东东，可以测试出很多非常难以发现的问题。</p>
<p>这三步做完后，我想opentest也可以成为一个比较完善的测试框架了，能够在很大程度上提高测试效率。</p>
本文永久链接:<a href="http://www.mirecle.com/2010/09/06/opentest-the-road.html">http://www.mirecle.com/2010/09/06/opentest-the-road.html</a>
<br/>
[<a href="http://www.mirecle.com/2010/09/06/opentest-the-road.html#respond">发表评论</a>]

<p>您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/10/22/opentest-imporve.html' rel='bookmark' title='Permanent Link: opentest的几个效率改进关注点'>opentest的几个效率改进关注点</a></li>
<li><a href='http://www.mirecle.com/2009/12/02/opentest-testing-framework.html' rel='bookmark' title='Permanent Link: Opentest测试框架'>Opentest测试框架</a></li>
<li><a href='http://www.mirecle.com/2010/08/23/what-is-a-good-test-case.html' rel='bookmark' title='Permanent Link: 什么样的测试用例是好的'>什么样的测试用例是好的</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mirecle.com/2010/09/06/opentest-the-road.html/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>软件测试工程师的职业素质</title>
		<link>http://www.mirecle.com/2010/08/30/professional-quality-software-test-engineer.html</link>
		<comments>http://www.mirecle.com/2010/08/30/professional-quality-software-test-engineer.html#comments</comments>
		<pubDate>Mon, 30 Aug 2010 06:17:29 +0000</pubDate>
		<dc:creator>闫鹏</dc:creator>
				<category><![CDATA[程序员]]></category>
		<category><![CDATA[职业生涯]]></category>
		<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.mirecle.com/?p=96154</guid>
		<description><![CDATA[记得以前面试过一个女孩，她认为软件测试就是点击网页，囧，作为一名软件测试工程师，我当时真是无地自容啊。相信很多人都把这个职业想象的非常简单，作为软件测试工程师的我，是有必要普及一下软件测试的童鞋都需要在哪些方面提高自己的。 1.分析能力。软件测试的核心其实应该就是设计测试用例了（具体啥样的用例设计，请参见《什么样的测试用例是好的》），而设计测试用例，就是依赖与分析能力了。这里我们不说那些常用的设计方法，从一个稍高的层面上来讲，可以说就是怎么将一个复杂的系统进行抽象，分析拆成几个不同的维度，结合维度可能出现的情况进行有选择的组合，以最小成本获取最大的收益。无法将一个复杂系统拆解成简单的维度，是没法做好用例设计的 2.编程语言。语言其实就像说话一样，只不过我们常说的英语日语之类是与人沟通，计算机语言就是与计算机进行沟通的。对于测试工程师来说，精通一门语言，熟悉其它几门语言是有必要的。对于不同语言编写的被测程序，是有不同特点的，如果对实现的语言不了解，无法进行白盒测试，没法看代码diff（结合代码diff做测试）来提高效率。对于特点不了解，可能也会导致自己漏掉部分内容。 3.设计能力。不要认为设计能力就是开发工程师的事情，拥有好的设计能力，就可以在设计评审的时候多提意见，促进开发工程师使用好的设计，不仅对开发有好处，对测试也是很有好处的。这样才能防患于未然，不仅自己的劳动力，也节省团队的劳动力。 4.对业务的理解。对业务的理解越充分，就越能够理解最终用户的需求，促进产品设计使用好的方式，促进产品成功。难道你想做一大堆不成功的项目么，那样是多么没有成就感的一件事啊。 5.自动化相关的考虑。随着项目越来越多，系统的测试项目也会积累的越来越多，每次有新功能了，难道要用手工来回归一下原有的case么。自动化测试是提高回归测试效率的唯一解决方案（如果你说还有解决方案就是不回归，我&#8230;），以高效率促进高质量，才是一个良性循环的发展方式啊。 嗯，以高效率促进高质量，我觉得很有很有道理。 本文永久链接:http://www.mirecle.com/2010/08/30/professional-quality-software-test-engineer.html [发表评论] 您可能会喜欢:opentest的几个效率改进关注点 opentest之路 结合代码diff做测试


您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/10/22/opentest-imporve.html' rel='bookmark' title='Permanent Link: opentest的几个效率改进关注点'>opentest的几个效率改进关注点</a></li>
<li><a href='http://www.mirecle.com/2010/09/06/opentest-the-road.html' rel='bookmark' title='Permanent Link: opentest之路'>opentest之路</a></li>
<li><a href='http://www.mirecle.com/2010/08/26/combination-of-code-to-do-tests-diff.html' rel='bookmark' title='Permanent Link: 结合代码diff做测试'>结合代码diff做测试</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<p>记得以前面试过一个女孩，她认为软件测试就是点击网页，囧，作为一名软件测试工程师，我当时真是无地自容啊。相信很多人都把这个职业想象的非常简单，作为软件测试工程师的我，是有必要普及一下软件测试的童鞋都需要在哪些方面提高自己的。</p>
<p>1.分析能力。软件测试的核心其实应该就是设计测试用例了（具体啥样的用例设计，请参见《<a href="http://www.mirecle.com/2010/08/23/what-is-a-good-test-case.html" target="_blank">什么样的测试用例是好的</a>》），而设计测试用例，就是依赖与分析能力了。这里我们不说那些常用的设计方法，从一个稍高的层面上来讲，可以说就是怎么将一个复杂的系统进行抽象，分析拆成几个不同的维度，结合维度可能出现的情况进行有选择的组合，以最小成本获取最大的收益。无法将一个复杂系统拆解成简单的维度，是没法做好用例设计的</p>
<p>2.编程语言。语言其实就像说话一样，只不过我们常说的英语日语之类是与人沟通，计算机语言就是与计算机进行沟通的。对于测试工程师来说，精通一门语言，熟悉其它几门语言是有必要的。对于不同语言编写的被测程序，是有不同特点的，如果对实现的语言不了解，无法进行白盒测试，没法看代码diff（<a href="http://www.mirecle.com/2010/08/26/combination-of-code-to-do-tests-diff.html" target="_blank">结合代码diff做测试</a>）来提高效率。对于特点不了解，可能也会导致自己漏掉部分内容。</p>
<p>3.设计能力。不要认为设计能力就是开发工程师的事情，拥有好的设计能力，就可以在设计评审的时候多提意见，促进开发工程师使用好的设计，不仅对开发有好处，对测试也是很有好处的。这样才能防患于未然，不仅自己的劳动力，也节省团队的劳动力。</p>
<p>4.对业务的理解。对业务的理解越充分，就越能够理解最终用户的需求，促进产品设计使用好的方式，促进产品成功。难道你想做一大堆不成功的项目么，那样是多么没有成就感的一件事啊。</p>
<p>5.自动化相关的考虑。随着项目越来越多，系统的测试项目也会积累的越来越多，每次有新功能了，难道要用手工来回归一下原有的case么。自动化测试是提高回归测试效率的唯一解决方案（如果你说还有解决方案就是不回归，我&#8230;），以高效率促进高质量，才是一个良性循环的发展方式啊。</p>
<p>嗯，以高效率促进高质量，我觉得很有很有道理。</p>
本文永久链接:<a href="http://www.mirecle.com/2010/08/30/professional-quality-software-test-engineer.html">http://www.mirecle.com/2010/08/30/professional-quality-software-test-engineer.html</a>
<br/>
[<a href="http://www.mirecle.com/2010/08/30/professional-quality-software-test-engineer.html#respond">发表评论</a>]

<p>您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/10/22/opentest-imporve.html' rel='bookmark' title='Permanent Link: opentest的几个效率改进关注点'>opentest的几个效率改进关注点</a></li>
<li><a href='http://www.mirecle.com/2010/09/06/opentest-the-road.html' rel='bookmark' title='Permanent Link: opentest之路'>opentest之路</a></li>
<li><a href='http://www.mirecle.com/2010/08/26/combination-of-code-to-do-tests-diff.html' rel='bookmark' title='Permanent Link: 结合代码diff做测试'>结合代码diff做测试</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mirecle.com/2010/08/30/professional-quality-software-test-engineer.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>结合代码diff做测试</title>
		<link>http://www.mirecle.com/2010/08/26/combination-of-code-to-do-tests-diff.html</link>
		<comments>http://www.mirecle.com/2010/08/26/combination-of-code-to-do-tests-diff.html#comments</comments>
		<pubDate>Thu, 26 Aug 2010 07:30:41 +0000</pubDate>
		<dc:creator>闫鹏</dc:creator>
				<category><![CDATA[程序员]]></category>
		<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.mirecle.com/?p=96152</guid>
		<description><![CDATA[代码diff与测试相结合，可以对测试起到较明显的促进作用，通常都是用在模块的功能升级使用。结合代码diff做测试，好处主要有下面几点： 1.提高旧有case回归的效率。从代码diff里面，可以看到旧有功能哪些地方没有任何改动，这样就可以增加信心，节省对旧有功能回归测试的工作量。当然，如果升级导致旧有功能的前置条件产生变化，还是需要注意的 2.明确case的重点。知道变动的内容，就可以根据修改的代码设置case，有针对性的测试。 3.辅助定位发现的问题。 4.直接发现bug或者代码设计上的问题。 5.测试人员的经验积累。经常看别人的代码diff，积累经验，就能加深自己对项目的理解，判断大致什么地方容易出现问题，提高职业素养。 diff少的时候，就可以直接发现问题了，这个非常有用，可以极大的提高效率。如果对被测对象的了解比较深入，通过查看diff即可知道新功能修改的是否到位，也可看出新增加的地方是否处理很山寨，不具备通用性等。另外比如实现细节上，看看申请的内存是否会溢出等也可以在这里处理。 有的时候，代码diff很多，看diff可以只关心重点内容： 1.if语句。新增或者修改的if标志着新旧功能点所走的不同逻辑分支。通过查看修改点的判断参数来设计case覆盖不同的分支。另外也要关注是否条件出现问题，程序走到错误分支的情况。 2.新增的函数。这种情况下，新增的函数通常都是为了满足新功能增加的部分逻辑，这时就设计case重点照顾一下新增的函数。 3.循环。比如修改了循环的条件，里面增加了break等也是属于流程分支改变的情况。 结合代码diff的作用很明显，但貌似总结这个的文章也很少，而实际用到的也是比较细小，零碎的东东，在这里先暂时列出一些，开启话题，逐渐补充吧。 本文永久链接:http://www.mirecle.com/2010/08/26/combination-of-code-to-do-tests-diff.html [发表评论] 您可能会喜欢:软件测试-了解被测对象 软件测试工程师的职业素质 难道神州真的不适合人类生存了?


您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/09/29/software-testing-learn-about-the-measured-object.html' rel='bookmark' title='Permanent Link: 软件测试-了解被测对象'>软件测试-了解被测对象</a></li>
<li><a href='http://www.mirecle.com/2010/08/30/professional-quality-software-test-engineer.html' rel='bookmark' title='Permanent Link: 软件测试工程师的职业素质'>软件测试工程师的职业素质</a></li>
<li><a href='http://www.mirecle.com/2009/11/30/is-divine-really-did-not-fit-for-human-survival-it.html' rel='bookmark' title='Permanent Link: 难道神州真的不适合人类生存了?'>难道神州真的不适合人类生存了?</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<p>代码diff与测试相结合，可以对测试起到较明显的促进作用，通常都是用在模块的功能升级使用。结合代码diff做测试，好处主要有下面几点：</p>
<p>1.提高旧有case回归的效率。从代码diff里面，可以看到旧有功能哪些地方没有任何改动，这样就可以增加信心，节省对旧有功能回归测试的工作量。当然，如果升级导致旧有功能的前置条件产生变化，还是需要注意的</p>
<p>2.明确case的重点。知道变动的内容，就可以根据修改的代码设置case，有针对性的测试。</p>
<p>3.辅助定位发现的问题。</p>
<p>4.直接发现bug或者代码设计上的问题。</p>
<p>5.测试人员的经验积累。经常看别人的代码diff，积累经验，就能加深自己对项目的理解，判断大致什么地方容易出现问题，提高职业素养。</p>
<p>diff少的时候，就可以直接发现问题了，这个非常有用，可以极大的提高效率。如果对被测对象的了解比较深入，通过查看diff即可知道新功能修改的是否到位，也可看出新增加的地方是否处理很山寨，不具备通用性等。另外比如实现细节上，看看申请的内存是否会溢出等也可以在这里处理。</p>
<p>有的时候，代码diff很多，看diff可以只关心重点内容：</p>
<p>1.if语句。新增或者修改的if标志着新旧功能点所走的不同逻辑分支。通过查看修改点的判断参数来设计case覆盖不同的分支。另外也要关注是否条件出现问题，程序走到错误分支的情况。</p>
<p>2.新增的函数。这种情况下，新增的函数通常都是为了满足新功能增加的部分逻辑，这时就设计case重点照顾一下新增的函数。</p>
<p>3.循环。比如修改了循环的条件，里面增加了break等也是属于流程分支改变的情况。</p>
<p>结合代码diff的作用很明显，但貌似总结这个的文章也很少，而实际用到的也是比较细小，零碎的东东，在这里先暂时列出一些，开启话题，逐渐补充吧。</p>
本文永久链接:<a href="http://www.mirecle.com/2010/08/26/combination-of-code-to-do-tests-diff.html">http://www.mirecle.com/2010/08/26/combination-of-code-to-do-tests-diff.html</a>
<br/>
[<a href="http://www.mirecle.com/2010/08/26/combination-of-code-to-do-tests-diff.html#respond">发表评论</a>]

<p>您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/09/29/software-testing-learn-about-the-measured-object.html' rel='bookmark' title='Permanent Link: 软件测试-了解被测对象'>软件测试-了解被测对象</a></li>
<li><a href='http://www.mirecle.com/2010/08/30/professional-quality-software-test-engineer.html' rel='bookmark' title='Permanent Link: 软件测试工程师的职业素质'>软件测试工程师的职业素质</a></li>
<li><a href='http://www.mirecle.com/2009/11/30/is-divine-really-did-not-fit-for-human-survival-it.html' rel='bookmark' title='Permanent Link: 难道神州真的不适合人类生存了?'>难道神州真的不适合人类生存了?</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mirecle.com/2010/08/26/combination-of-code-to-do-tests-diff.html/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>什么样的测试用例是好的</title>
		<link>http://www.mirecle.com/2010/08/23/what-is-a-good-test-case.html</link>
		<comments>http://www.mirecle.com/2010/08/23/what-is-a-good-test-case.html#comments</comments>
		<pubDate>Mon, 23 Aug 2010 08:59:14 +0000</pubDate>
		<dc:creator>闫鹏</dc:creator>
				<category><![CDATA[程序员]]></category>
		<category><![CDATA[软件测试]]></category>

		<guid isPermaLink="false">http://www.mirecle.com/?p=96145</guid>
		<description><![CDATA[作为测试人员，设计测试用例是干活的第二步（第一步当然是了解测试对象嘿嘿），这一步做的好与否，对后续工作起着决定作用，那么如何评价一个测试用例的好坏，或者说，设计的成功与否呢，本文大概讨论一下，抛砖引玉吧，记录在这里，看看是不是可以作为一次团队讨论的话题。 在此之前，我们需要明确测试工程师的工作原则：用最小的成本找出最多的问题。 1.用例覆盖程度 毫无疑问，这一点应该是最重要的，无需多说，覆盖率最大化是一套测试用例的最重要评价标准，如果漏测就杯具了。 2.用例是否已经达到工作量最小化 在满足用例覆盖程度最大化的前提下，应该尽量减小执行用例所需要的工作量。这些方面的方法有不少，如条件覆盖，分支覆盖，正交覆盖等方法。面对不同的测试对象，也有不同的方法来保证：对于网页背后的php逻辑，可以通过在网页上测试后，用一些工具比如xdebug来统计代码覆盖率；对于向外提供接口的server，采用的方式就是分析在外面暴露的接口设计用例，大致的通过接口参数来估计一下分支判断的情况。 3.用例的分类以及描述是否足够清晰 用例的分类，在这里是指相同类型的用例是否放在一起了。例如：接口类的用例，参数的取值范围是1-3，但是现在却传入4；数据类用例，状态机现在位于状态2，却要求状态跳转到无法到达的4；逻辑类用例，正常功能的产出等。将相同类型的用例放在一起，有助于理清思路，清楚了解用例设计是否完备。 用例的描述，是指描述的清晰程度是否能够形成文档。例如上面参数取值范围的例子，用例这样写：“传入错误的值”或者“传入非1-3的值”，明显没有写成“传入值4”有效。这与写程序一样，总是写闭区间的范围而不是开区间。 4.用例是否表明了测试目的 写明用例的测试目的，对文档的易于理解性和工作交接的好处不言而喻，现代软件工程不可能只有一个人在做事情，项目于人员的变动也是难免的。在过程中留下足够的信息，可以在后续工作提高很多效率。 5.测试用例的易于维护性 如果被测对象有所升级，测试用例的说明或者脚本是不是容易维护呢？例如在有状态机的情况下，测试用例之间是相互依赖的（即需要一定的执行顺序），这样被依赖的用例修改后，后端不需要同步根据修改。而如果用例之间没有相互依赖关系（如用例是自己造的数据，不是依赖于前端的产出），可能一旦有变化，就需要修改这两个。当然，这两种情况不能绝对的说哪种好，是需要看实际使用时候的情况进行取舍的。不过，通过一些系统性的工具支持，也会出现一种做法绝对性的好于另外一种的情况，情况很多，做法也有很多，在这里就不多说了。 说了这么多，其实这个第二步，还是严重依赖于第一步的，如果对测试对象的需求，实现等都不了解，设计用例也就无从谈起了。 本文永久链接:http://www.mirecle.com/2010/08/23/what-is-a-good-test-case.html [发表评论] 您可能会喜欢:opentest的几个效率改进关注点 opentest之路 软件测试工程师的职业素质


您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/10/22/opentest-imporve.html' rel='bookmark' title='Permanent Link: opentest的几个效率改进关注点'>opentest的几个效率改进关注点</a></li>
<li><a href='http://www.mirecle.com/2010/09/06/opentest-the-road.html' rel='bookmark' title='Permanent Link: opentest之路'>opentest之路</a></li>
<li><a href='http://www.mirecle.com/2010/08/30/professional-quality-software-test-engineer.html' rel='bookmark' title='Permanent Link: 软件测试工程师的职业素质'>软件测试工程师的职业素质</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<p>作为测试人员，设计测试用例是干活的第二步（第一步当然是了解测试对象嘿嘿），这一步做的好与否，对后续工作起着决定作用，那么如何评价一个测试用例的好坏，或者说，设计的成功与否呢，本文大概讨论一下，抛砖引玉吧，记录在这里，看看是不是可以作为一次团队讨论的话题。</p>
<p>在此之前，我们需要明确测试工程师的工作原则：用最小的成本找出最多的问题。</p>
<p><strong>1.用例覆盖程度</strong></p>
<p>毫无疑问，这一点应该是最重要的，无需多说，覆盖率最大化是一套测试用例的最重要评价标准，如果漏测就杯具了。</p>
<p><strong>2.用例是否已经达到工作量最小化</strong></p>
<p>在满足用例覆盖程度最大化的前提下，应该尽量减小执行用例所需要的工作量。这些方面的方法有不少，如条件覆盖，分支覆盖，正交覆盖等方法。面对不同的测试对象，也有不同的方法来保证：对于网页背后的php逻辑，可以通过在网页上测试后，用一些工具比如xdebug来统计代码覆盖率；对于向外提供接口的server，采用的方式就是分析在外面暴露的接口设计用例，大致的通过接口参数来估计一下分支判断的情况。</p>
<p><strong>3.用例的分类以及描述是否足够清晰</strong></p>
<p>用例的分类，在这里是指相同类型的用例是否放在一起了。例如：接口类的用例，参数的取值范围是1-3，但是现在却传入4；数据类用例，状态机现在位于状态2，却要求状态跳转到无法到达的4；逻辑类用例，正常功能的产出等。将相同类型的用例放在一起，有助于理清思路，清楚了解用例设计是否完备。</p>
<p>用例的描述，是指描述的清晰程度是否能够形成文档。例如上面参数取值范围的例子，用例这样写：“传入错误的值”或者“传入非1-3的值”，明显没有写成“传入值4”有效。这与写程序一样，总是写闭区间的范围而不是开区间。</p>
<p><strong>4.用例是否表明了测试目的</strong></p>
<p>写明用例的测试目的，对文档的易于理解性和工作交接的好处不言而喻，现代软件工程不可能只有一个人在做事情，项目于人员的变动也是难免的。在过程中留下足够的信息，可以在后续工作提高很多效率。</p>
<p><strong>5.测试用例的易于维护性</strong></p>
<p>如果被测对象有所升级，测试用例的说明或者脚本是不是容易维护呢？例如在有状态机的情况下，测试用例之间是相互依赖的（即需要一定的执行顺序），这样被依赖的用例修改后，后端不需要同步根据修改。而如果用例之间没有相互依赖关系（如用例是自己造的数据，不是依赖于前端的产出），可能一旦有变化，就需要修改这两个。当然，这两种情况不能绝对的说哪种好，是需要看实际使用时候的情况进行取舍的。不过，通过一些系统性的工具支持，也会出现一种做法绝对性的好于另外一种的情况，情况很多，做法也有很多，在这里就不多说了。</p>
<p>说了这么多，其实这个第二步，还是严重依赖于第一步的，如果对测试对象的需求，实现等都不了解，设计用例也就无从谈起了。</p>
本文永久链接:<a href="http://www.mirecle.com/2010/08/23/what-is-a-good-test-case.html">http://www.mirecle.com/2010/08/23/what-is-a-good-test-case.html</a>
<br/>
[<a href="http://www.mirecle.com/2010/08/23/what-is-a-good-test-case.html#respond">发表评论</a>]

<p>您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/10/22/opentest-imporve.html' rel='bookmark' title='Permanent Link: opentest的几个效率改进关注点'>opentest的几个效率改进关注点</a></li>
<li><a href='http://www.mirecle.com/2010/09/06/opentest-the-road.html' rel='bookmark' title='Permanent Link: opentest之路'>opentest之路</a></li>
<li><a href='http://www.mirecle.com/2010/08/30/professional-quality-software-test-engineer.html' rel='bookmark' title='Permanent Link: 软件测试工程师的职业素质'>软件测试工程师的职业素质</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mirecle.com/2010/08/23/what-is-a-good-test-case.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>sql运行简单封装</title>
		<link>http://www.mirecle.com/2010/07/23/sql-to-run-a-simple-package.html</link>
		<comments>http://www.mirecle.com/2010/07/23/sql-to-run-a-simple-package.html#comments</comments>
		<pubDate>Fri, 23 Jul 2010 09:06:39 +0000</pubDate>
		<dc:creator>闫鹏</dc:creator>
				<category><![CDATA[程序员]]></category>
		<category><![CDATA[代码库]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.mirecle.com/?p=96133</guid>
		<description><![CDATA[作为一个QA，我本来是很少写代码的，不过这段代码用的次数比较多，每次用的时候都改一些，比较烦，所以整理了一个通用的，作为个人代码库的第一块石头吧 升级于2010-7-26，修复bug class sql_runner{ private static $_arr_self = array(); private $_addr = false; private $_user = false; private $_passwd = false; private $_db_connection = false; static function get_instance($addr, $user, $passwd){ $key = $addr.'#'.$user.'#'.$passwd; if(false === array_key_exists($key, self::$_arr_self)){ sql_runner::$_arr_self[$key] = new sql_runner($addr, $user, $passwd); } return sql_runner::$_arr_self[$key]; } private function __construct($addr, $user, $passwd){ $this-&#62;_addr = $addr; [...]


您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/05/17/php-and-repair-defects-in-the-getopt.html' rel='bookmark' title='Permanent Link: php中getopt的缺陷及修复'>php中getopt的缺陷及修复</a></li>
<li><a href='http://www.mirecle.com/2010/01/18/php-reflection-effect-the-base-class-to-access-sub-categories-of-data.html' rel='bookmark' title='Permanent Link: php反射效果:基类访问子类数据'>php反射效果:基类访问子类数据</a></li>
<li><a href='http://www.mirecle.com/2010/04/21/reduce-the-use-of-the-dynamic-nature-of-language-switch.html' rel='bookmark' title='Permanent Link: 利用语言的动态特性减少switch'>利用语言的动态特性减少switch</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<p>作为一个QA，我本来是很少写代码的，不过这段代码用的次数比较多，每次用的时候都改一些，比较烦，所以整理了一个通用的，作为个人代码库的第一块石头吧<br />
升级于2010-7-26，修复bug</p>
<pre class="brush: php">class sql_runner{

	private static $_arr_self = array();

	private $_addr = false;
	private $_user = false;
	private $_passwd = false;
	private $_db_connection = false;

	static function get_instance($addr, $user, $passwd){
		$key = $addr.'#'.$user.'#'.$passwd;
		if(false === array_key_exists($key, self::$_arr_self)){
			sql_runner::$_arr_self[$key] = new sql_runner($addr, $user, $passwd);
		}

		return sql_runner::$_arr_self[$key];
	}

	private function __construct($addr, $user, $passwd){
		$this-&gt;_addr = $addr;
		$this-&gt;_user = $user;
		$this-&gt;_passwd = $passwd;
	}

	public function run_sql($sql){

		if(false === $this-&gt;_db_connection || !mysql_ping($this-&gt;_db_connection)){
			UB_LOG_DEBUG("connecting db $this-&gt;_addr, $this-&gt;_user");
			$this-&gt;_db_connection = mysql_connect($this-&gt;_addr, $this-&gt;_user, $this-&gt;_passwd);

			if(false === $this-&gt;_db_connection){
				UB_LOG_FATAL("connect db failed: ".mysql_error());
				return false;
			}else{
				mysql_set_charset('latin1', $this-&gt;_db_connection);
			}
		}

		$result = false;
		$result = mysql_query($sql, $this-&gt;_db_connection);
		if(false === $result){
			UB_LOG_FATAL("[$sql] execute failed:". mysql_error($this-&gt;_db_connection)."\n");
			return false;
		}

		$result_arr = array();
		if(is_resource($result)){
			while($row = mysql_fetch_assoc($result)){
				$result_arr[] = $row;
			}
			mysql_free_result($result);
		}

		UB_LOG_DEBUG("[$sql] execute succed, selected result:".print_r($result_arr, true));
		return $result_arr;
	}

}

/**for log functions*/
if(!function_exists('UB_LOG_DEBUG')){
	function UB_LOG_DEBUG($log){
		print($log);
	}
}
if(!function_exists('UB_LOG_FATAL')){
	function UB_LOG_FATAL($log){
		print($log);
	}
}
</pre>
本文永久链接:<a href="http://www.mirecle.com/2010/07/23/sql-to-run-a-simple-package.html">http://www.mirecle.com/2010/07/23/sql-to-run-a-simple-package.html</a>
<br/>
[<a href="http://www.mirecle.com/2010/07/23/sql-to-run-a-simple-package.html#respond">发表评论</a>]

<p>您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/05/17/php-and-repair-defects-in-the-getopt.html' rel='bookmark' title='Permanent Link: php中getopt的缺陷及修复'>php中getopt的缺陷及修复</a></li>
<li><a href='http://www.mirecle.com/2010/01/18/php-reflection-effect-the-base-class-to-access-sub-categories-of-data.html' rel='bookmark' title='Permanent Link: php反射效果:基类访问子类数据'>php反射效果:基类访问子类数据</a></li>
<li><a href='http://www.mirecle.com/2010/04/21/reduce-the-use-of-the-dynamic-nature-of-language-switch.html' rel='bookmark' title='Permanent Link: 利用语言的动态特性减少switch'>利用语言的动态特性减少switch</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mirecle.com/2010/07/23/sql-to-run-a-simple-package.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>sigterm sigint sigkill 区别</title>
		<link>http://www.mirecle.com/2010/05/20/sigterm-sigint-sigkill-difference.html</link>
		<comments>http://www.mirecle.com/2010/05/20/sigterm-sigint-sigkill-difference.html#comments</comments>
		<pubDate>Thu, 20 May 2010 12:02:03 +0000</pubDate>
		<dc:creator>闫鹏</dc:creator>
				<category><![CDATA[程序员]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.mirecle.com/?p=96096</guid>
		<description><![CDATA[我看网上应该有不少搜索这个区别的问题，但是回答的都不全面，其中sigterm与sigint尤其有一点区别比较重要，但大都没有提及，今天我就遇到了这个问题，纠结了20分钟才搞明白咋回事。 首先，对于说这几个信号都是终止程序运行的说法不太准确，因为程序收到信号后，如果不对信号处理，就会导致程序退出，但如果程序捕获信号进行处理，按照它的逻辑，它是不一定会退出的。 在这三个信号中，sigkill是不能被捕获的，程序收到这个信号后，一定会退出。这就是kill -9一定能保证将程序杀死的原因。 下面说一下sigterm与sigint的区别，其中有一点区别区别很多文章都没有提及，也是我写这篇blog的原因（如果人家都写了，我就不用写了呗） 信号 产生方式 对进程的影响 sigint 通过ctrl+c将会对当进程发送此信号 信号被当前进程树接收到，也就是说，不仅当前进程会收到信号，它的子进程也会收到 sigterm kill命令不加参数就是发送这个信号 只有当前进程收到信号，子进程不会收到。如果当前进程被kill了，那么它的子进程的父进程将会是init，也就是pid为1的进程 下面这两个代码片段就能够验证这种情况(注意使用pcntl的时候，一定要declare ticks，要不然会杯具的发现函数没有被调用，进程不退出，信号发过去没有作用。php手册竟然没有强调这一点)： 文件：loadhelper.php #为了pcntl能够截获信号 declare(ticks = 1); $arr_processes = array(); function terminate($signo){ echo "aaaaaaaaaaa\n"; } pcntl_signal(SIGTERM, "terminate", true); pcntl_signal(SIGINT, "terminate", true); foreach($argv as $key =&#62; $operation){ if(0 === $key){ continue; } $pipes = array(); $process = proc_open($operation, array(), &#38;$pipes); if(false === [...]


您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/07/23/sql-to-run-a-simple-package.html' rel='bookmark' title='Permanent Link: sql运行简单封装'>sql运行简单封装</a></li>
<li><a href='http://www.mirecle.com/2010/05/17/php-and-repair-defects-in-the-getopt.html' rel='bookmark' title='Permanent Link: php中getopt的缺陷及修复'>php中getopt的缺陷及修复</a></li>
<li><a href='http://www.mirecle.com/2010/02/02/file-grep-select-two-files-same-different-content.html' rel='bookmark' title='Permanent Link: 文件grep-选出两个文件中相同/不同的内容'>文件grep-选出两个文件中相同/不同的内容</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<p>我看网上应该有不少搜索这个区别的问题，但是回答的都不全面，其中sigterm与sigint尤其有一点区别比较重要，但大都没有提及，今天我就遇到了这个问题，纠结了20分钟才搞明白咋回事。</p>
<p>首先，对于说这几个信号都是终止程序运行的说法不太准确，因为程序收到信号后，如果不对信号处理，就会导致程序退出，但如果程序捕获信号进行处理，按照它的逻辑，它是不一定会退出的。</p>
<p>在这三个信号中，sigkill是不能被捕获的，程序收到这个信号后，一定会退出。这就是kill -9一定能保证将程序杀死的原因。</p>
<p>下面说一下sigterm与sigint的区别，其中有一点区别区别很多文章都没有提及，也是我写这篇blog的原因（如果人家都写了，我就不用写了呗）</p>
<table border="0">
<tbody>
<tr>
<td>信号</td>
<td>产生方式</td>
<td>对进程的影响</td>
</tr>
<tr>
<td>sigint</td>
<td>通过ctrl+c将会对当进程发送此信号</td>
<td>信号被当前进程树接收到，也就是说，不仅当前进程会收到信号，它的子进程也会收到</td>
</tr>
<tr>
<td>sigterm</td>
<td>kill命令不加参数就是发送这个信号</td>
<td>只有当前进程收到信号，子进程不会收到。如果当前进程被kill了，那么它的子进程的父进程将会是init，也就是pid为1的进程</td>
</tr>
</tbody>
</table>
<p>下面这两个代码片段就能够验证这种情况(注意使用pcntl的时候，一定要declare ticks，要不然会杯具的发现函数没有被调用，进程不退出，信号发过去没有作用。php手册竟然没有强调这一点)：</p>
<p>文件：loadhelper.php</p>
<pre class="brush:php">
#为了pcntl能够截获信号
declare(ticks = 1);

$arr_processes = array();

function terminate($signo){
    echo "aaaaaaaaaaa\n";
}

pcntl_signal(SIGTERM, "terminate", true);
pcntl_signal(SIGINT, "terminate", true);

foreach($argv as $key =&gt; $operation){

    if(0 === $key){
        continue;
    }   

    $pipes = array();
    $process = proc_open($operation, array(), &amp;$pipes);
    if(false === $process){
        exit(-1);
    }
    $arr_processes[] = $process;
}

while(true){
    sleep(100);
}
</pre>
<p>文件：child.php</p>
<pre class="brush:php">
declare(ticks=1);

pcntl_signal(SIGINT, "terminate");
pcntl_signal(SIGTERM, "terminate");

function terminate($signo){
    echo "test_child\n";
}

while(true){
    sleep(100);
}
</pre>
<p>使用命令php loadhelper.php “php test.php”可以启动这个测试。<br />
1.输入ctrl+c发送sigint可以看到，父进程与子进程的terminate都得到了执行，都有输出，但父进程不会退出，因为子进程还没有退出<br />
2.通过kill向父进程的pid发送sigterm，可以看到，只有父进程输出</p>
<p>遗留问题：</p>
<p>父进程（loadhelper）接受到一次信号后，如果在terminate函数中调用exit，它还是不能退出的，因为还有子进程没有退出。但是从此以后它就不能再接收信号了（子进程还是能够接收到sigint），可能是exit使进程进入了待回收状态，具体还 需要后续在分析一把。</p>
本文永久链接:<a href="http://www.mirecle.com/2010/05/20/sigterm-sigint-sigkill-difference.html">http://www.mirecle.com/2010/05/20/sigterm-sigint-sigkill-difference.html</a>
<br/>
[<a href="http://www.mirecle.com/2010/05/20/sigterm-sigint-sigkill-difference.html#respond">发表评论</a>]

<p>您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/07/23/sql-to-run-a-simple-package.html' rel='bookmark' title='Permanent Link: sql运行简单封装'>sql运行简单封装</a></li>
<li><a href='http://www.mirecle.com/2010/05/17/php-and-repair-defects-in-the-getopt.html' rel='bookmark' title='Permanent Link: php中getopt的缺陷及修复'>php中getopt的缺陷及修复</a></li>
<li><a href='http://www.mirecle.com/2010/02/02/file-grep-select-two-files-same-different-content.html' rel='bookmark' title='Permanent Link: 文件grep-选出两个文件中相同/不同的内容'>文件grep-选出两个文件中相同/不同的内容</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mirecle.com/2010/05/20/sigterm-sigint-sigkill-difference.html/feed</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>php中getopt的缺陷及修复</title>
		<link>http://www.mirecle.com/2010/05/17/php-and-repair-defects-in-the-getopt.html</link>
		<comments>http://www.mirecle.com/2010/05/17/php-and-repair-defects-in-the-getopt.html#comments</comments>
		<pubDate>Mon, 17 May 2010 07:55:49 +0000</pubDate>
		<dc:creator>闫鹏</dc:creator>
				<category><![CDATA[程序员]]></category>
		<category><![CDATA[代码库]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.mirecle.com/?p=96094</guid>
		<description><![CDATA[在这里，我不得不再一次感叹php语言库函数的山寨与不专业。getopt函数就是一个典型的例子，通常用的时候，大家可能觉得没有什么，但在某些情况 下，就真的让人很囧。一个简单的函数，稍微多花几分钟就弄得更好一些了，但这个语言有个随意的开端，就有个随意的实现啊。 在linux中，使用getopt时候，有两种情况： 1.取得的参数解析成字符串：“php test_arg.php -c abc”，这种情况c参数取得的结果就是abc这个字符串 2.取得的参数解析成数组：“php test_arg.php -c abc -c abc123”，这种情况c参数取得的结果就是包含abc与abc123的数组 但是遇到这种情况呢：“php test_arg.php -c abc*”？由于linux的shell已经帮程序做了输入参数的解析，这时候c参数得到的既不是abc*这个结果也不是一个数组，而是被shell展开成了很多文件名后的第一个。 可能getopt用的童鞋很少，但这种山寨的设计，实在太让人憋屈了，自己花个10分钟写一个就比它的要好，为了避免大家重复劳动，分享一个代码片段 function mygetopt(){ global $argv; $result = array(); $current_key = false; foreach($argv as $opt){ $matches = array(); if(1 === preg_match("/^-{1,2}(.*)$/", $opt, $matches)){ $current_key = $matches[1]; if(false === isset($result[$current_key])){ $result[$current_key] = false; } }else if (false !== $current_key){ if(false [...]


您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/01/18/php-reflection-effect-the-base-class-to-access-sub-categories-of-data.html' rel='bookmark' title='Permanent Link: php反射效果:基类访问子类数据'>php反射效果:基类访问子类数据</a></li>
<li><a href='http://www.mirecle.com/2010/07/23/sql-to-run-a-simple-package.html' rel='bookmark' title='Permanent Link: sql运行简单封装'>sql运行简单封装</a></li>
<li><a href='http://www.mirecle.com/2010/05/07/php-in-the-ampersand-on-the-abuse-of.html' rel='bookmark' title='Permanent Link: php中&#038;符号的滥用与它引发的bug'>php中&#038;符号的滥用与它引发的bug</a></li>
</ol>]]></description>
			<content:encoded><![CDATA[
<p>在这里，我不得不再一次感叹php语言库函数的山寨与不专业。getopt函数就是一个典型的例子，通常用的时候，大家可能觉得没有什么，但在某些情况 下，就真的让人很囧。一个简单的函数，稍微多花几分钟就弄得更好一些了，但这个语言有个随意的开端，就有个随意的实现啊。</p>
<p>在linux中，使用getopt时候，有两种情况：</p>
<p>1.取得的参数解析成字符串：“php test_arg.php -c abc”，这种情况c参数取得的结果就是abc这个字符串</p>
<p>2.取得的参数解析成数组：“php test_arg.php -c abc -c abc123”，这种情况c参数取得的结果就是包含abc与abc123的数组</p>
<p>但是遇到这种情况呢：“php test_arg.php -c abc*”？由于linux的shell已经帮程序做了输入参数的解析，这时候c参数得到的既不是abc*这个结果也不是一个数组，而是被shell展开成了很多文件名后的第一个。</p>
<p>可能getopt用的童鞋很少，但这种山寨的设计，实在太让人憋屈了，自己花个10分钟写一个就比它的要好，为了避免大家重复劳动，分享一个代码片段</p>
<pre class="brush:php">   function mygetopt(){
        global $argv;
        $result = array();

        $current_key = false;
        foreach($argv as $opt){

            $matches = array();
            if(1 === preg_match("/^-{1,2}(.*)$/", $opt, $matches)){
                $current_key = $matches[1];

                if(false === isset($result[$current_key])){
                    $result[$current_key] = false;
                }
            }else if (false !== $current_key){

                if(false === $result[$current_key]){
                    $result[$current_key] = $opt;
                }else{
                    if(false === is_array($result[$current_key])){
                        $result[$current_key] = array($result[$current_key]);
                    }
                    $result[$current_key][] = $opt;
                }
            }
        }   

        return $result;
    }
</pre>
<p>为了方便使用，将新版本的getopt函数设置为不接受任何参数，但是解析的结果可以输出所有的参数内容。因为php官方的getopt函数使用后，也无非是对输出的数组进行foreach之后进行switch，还不如方便点，直接解析所有呢。除了这一点，这个getopt函数的输出结果与php官方的完全一致</p>
<p>php官方getopt函数参考文档：<a href="http://cn.php.net/manual/en/function.getopt.php" target="_blank">http://cn.php.net/manual/en/function.getopt.php</a></p>
本文永久链接:<a href="http://www.mirecle.com/2010/05/17/php-and-repair-defects-in-the-getopt.html">http://www.mirecle.com/2010/05/17/php-and-repair-defects-in-the-getopt.html</a>
<br/>
[<a href="http://www.mirecle.com/2010/05/17/php-and-repair-defects-in-the-getopt.html#respond">发表评论</a>]

<p>您可能会喜欢:<ol><li><a href='http://www.mirecle.com/2010/01/18/php-reflection-effect-the-base-class-to-access-sub-categories-of-data.html' rel='bookmark' title='Permanent Link: php反射效果:基类访问子类数据'>php反射效果:基类访问子类数据</a></li>
<li><a href='http://www.mirecle.com/2010/07/23/sql-to-run-a-simple-package.html' rel='bookmark' title='Permanent Link: sql运行简单封装'>sql运行简单封装</a></li>
<li><a href='http://www.mirecle.com/2010/05/07/php-in-the-ampersand-on-the-abuse-of.html' rel='bookmark' title='Permanent Link: php中&#038;符号的滥用与它引发的bug'>php中&#038;符号的滥用与它引发的bug</a></li>
</ol></p>]]></content:encoded>
			<wfw:commentRss>http://www.mirecle.com/2010/05/17/php-and-repair-defects-in-the-getopt.html/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

