在项目中我们经常能遇到数据库有“一对多”的关系,比如下面两张表:
Student:

Class:

Class-Student就这样构成了一个简单的一对多关系。当然在实际的项目中,也可以再建立一张Relation表来保存他们之间的关系,在这里为了简单,就不做Relation表了。
现在在项目中,我需要将Class表中的数据list显示,当然也想显示选择了这门课的Student的StuName。也可以说是将一对多关系转换为一对一关系。我所期望的显示格式是这样的:

要做到这一点并不难,大体有两种思路:
1、在数据库中写一个函数
2、在程序中获取表Class与表Student所有数据,然后对比ClassID
那么,那种方法效率比较高呢?于是我写了下面的代码来进行一个简单的测试
View Code class Program { static void Main(string[] args) { Sql sql = new Sql(); Stopwatch time1 = new Stopwatch(); Stopwatch time2 = new Stopwatch(); for (int j = 0; j < 10; j++) { time2.Start(); for (int i = 0; i < 1000; i++) { string sql1 = "select ID,[StuName],[ClassID] FROM [Student]"; string sql2 = " SELECT ID,ClassName from Class"; List<string> item = new List<string>(); string bl=""; DataTable dt1 = sql.getData(sql1); DataTable dt2 = sql.getData(sql2); foreach (DataRow dtRow2 in dt2.Rows) { foreach (DataRow dtRow1 in dt1.Rows) { if (dtRow1["ClassID"].ToString() == dtRow2["ID"].ToString()) { bl+=dtRow1["StuName"].ToString()+","; } } item.Add(bl); bl = ""; } } time2.Stop(); Console.WriteLine(time2.Elapsed.ToString());
time1.Start(); for (int i = 0; i < 1000; i++) { string sql3 = "SELECT C.ID, C.ClassName, dbo.f_getStuNamesByClassID(C.ID)as stuName FROM Class C"; DataTable dt = sql.getData(sql3); } time1.Stop(); Console.WriteLine(time1.Elapsed.ToString()); float index = (float)time1.Elapsed.Ticks / (float)time2.Elapsed.Ticks; Console.WriteLine("效率比" + index.ToString()); Console.WriteLine("============================="); }
Console.ReadLine(); } } |
View Code class Sql { public DataTable getData(string sql) { SqlConnection conn = new SqlConnection(); conn.ConnectionString = "Data Source=.\\SQLEXPRESS;Initial Catalog=Test;User Id=sa;Password=1;"; SqlCommand comm = new SqlCommand(sql, conn); conn.Open(); SqlDataAdapter da = new SqlDataAdapter(comm); DataSet ds = new DataSet(); da.Fill(ds, "ds"); conn.Close(); return ds.Tables[0]; } }
|
View Code --根据课程ID,返回选此课程的学生的名字,以逗号隔开 ALTER function [dbo].[f_getStuNamesByClassID] (@ID int) RETURNS nvarchar(50) begin declare @Result nvarchar(50); declare @stuName nvarchar(50); Set @Result=''; declare cur cursor for ( SELECT S.StuName FROM Class C LEFT JOIN Student S ON C.ID=S.ClassID WHERE C.ID=@ID ) open cur; fetch next from cur into @stuName; while(@@fetch_status=0) begin set @Result=@Result+@stuName+','; fetch next from cur into @stuName; end; --去除最后多余的一个逗号 IF @Result <> '' SET @Result=SUBSTRING(@Result, 1, LEN(@Result)-1); ELSE SET @Result=NULL; return @Result; en |
测试结果如下:
00:00:00.5466790
00:00:00.7753704
效率比1.418329
=============================
00:00:01.0251996
00:00:01.5594629
效率比1.521131
=============================
00:00:01.5124349
00:00:02.3286227
效率比1.539652
=============================
00:00:01.9882458
00:00:03.1007960
效率比1.559564
=============================
00:00:02.4476305
00:00:03.8717636
效率比1.581842
=============================
00:00:02.9129007
00:00:04.6332828
效率比1.590608
=============================
00:00:03.4006140
00:00:05.3971930
效率比1.587123
=============================
00:00:03.8655281
00:00:06.2574500
效率比1.618783
=============================
00:00:04.4532249
00:00:07.0674710
效率比1.587046
=============================
00:00:04.9540083
00:00:07.8596999
效率比1.586533
=============================
分析一下测试结果,不难发现每一个一千次所用的时间基本符合一个等差数列。当然第一个一千次由于要初始化,所以显得慢一些。
总体来说,在程序中用处理一对多关系,比在数据库中用函数处理效率要高35%这样。
那么如果我们在Student表中再添加一行这样的数据:

测试结果如下:
00:00:00.5519228
00:00:00.8206084
效率比1.486817
=============================
00:00:01.0263686
00:00:01.5813210
效率比1.540695
=============================
00:00:01.4886327
00:00:02.3516000
效率比1.579705
=============================
00:00:01.9807901
00:00:03.1495472
效率比1.590046
=============================
00:00:02.4613411
00:00:03.9278171
效率比1.595804
=============================
00:00:02.9246678
00:00:04.6961790
效率比1.605714
=============================
00:00:03.3911521
00:00:05.5018374
效率比1.62241
=============================
00:00:03.8737490
00:00:06.2716150
效率比1.619004
=============================
00:00:04.4047347
00:00:07.1796579
效率比1.629986
=============================
00:00:04.8688508
00:00:07.9477787
效率比1.632372
=============================
发现添加数据之后,效率比进一步加大
环境:vs2008,sql 2005
总结:根据测试结果来说,对于大规模高并发的数据库操作(在这里是10次循环,每次1000次读取数据),我们应该尽可能的避免使用数据库函数,而应该将数据全部取出来,在程序中进行处理
写在最后的话:对于我的程序、代码、思路等等一切的一切有不同见解者,欢迎留言讨论。这是我的第一篇博客,希望大家多多支持,如有不足望海涵。
前言:
● 自动化测试不只是测试的自动化,应当是流程的自动化
● 自动化测试是一种软件开发交付过程
● 自动化测试成败在于自动化项目的质量与可维护性
自动化测试对于在黑盒与手工测试工作的大部分人来说,都会比较向往,因为自动化测试很有成就感; 对于直接在自动化测试行业工作的新人来说,会比较迷茫,因为这个较为新生的领域不像开发行业那么成熟;
其实,自动化测试和手工测试一样,是一种测试方法,只是你智力与思维转化的结果; 关键看你是否适合,心态是否正确。
同时,它的发展前景不亚于任何开发行业,你既可以接触专业的自动化测试技术,又可以掌握相关的开发技术,并且可以接触专业的测试专家。
自动化测试的范围
一般我们很难直接限定自动化测试的内容,但以我的理解,先从不适合的方面排除之,你可以试着看一下。
在混乱的项目流程中,不适合推广和试行自动化测试。 自动化测试也是一种项目交付过程。
如果被测项目流程不明确,过程责任不清,没有准确公平的数据度量,
● 开展了自动化测试效果难于评估,做也白搭
● 没有清晰的交付测试流程,自动化测试经常的变更成本,以及没有开发支撑的自动化只能从表面下手,导致维护成本过高。
● 自动化测试能够将流程工具化,这点体现的效果易于得到整体研发的认可与支撑,效果也是极显著的。
打个比方,本来是在公路上(不完善的流程)运行汽车,你非要改进效率跑火车(自动化),适得其反。
自动化测试的关键点之一,在于流程,流程在于人去完善,去改进。然而流程在年少时人的性格,在年长时也改变不了太多,我们自动化要符合流程去做,需要完善的我们去补充完善。而完善流程,不是一味的提要求,而是合理的惯力的要求,更多的时候应该建设平台来支撑流程,让人做到最简化。
一旦流程的完善,自动化随之正规化,可量化的自动化需求,项目成员明确自动化的成本与成果,以及相关自动化约束(例如某个自动化接口实现)。 自动化的成功自然随之而然。
所以,自动化测试不只是测试的自动化,而应当是整个流程的一种自动化与完善。
在实施自动化的时候,处理流程相关,最好遵寻:完成相关自动化项目显示效果 -> 要求改进流程 -> 实现流程过程的自动化
这样带来的项目压力较小,容易获得所需的资源。
自动化测试的过程
有了流程不代表我们肯定会成功,更何况一般需要我们通过自动化测试的成功来带动流程的推进。
自动化测试首先是一种软件开发与交付过程,无论最后的执行与维护是谁!
自动化测试与软件开发过程基本相同,也要经历: 需求->设计->编码->交付 四个核心过程。 与普通的开发过程不一样的是
● 自动化需求并不是实际的强制性需求,能够有弹性,最关键的是自动化项目所定下的效果,各利益相关者必须在自动化项目效果期望上达成一致。
● 一般自动化设计过程相对较为简单,如果有可伸缩好的框架,这个设计过程可以在很短时间搞定。
● 自动化的维护周期会比较长,所以设计高维护的自动化脚本是必然的。
在实际中,从手工测试过程中学习自动化的人,甚至有对版本管理工具如何管理代码不清楚,那么他去做自动化必然是失败的。
当项目经理对自动化效果期望很高时(这点可以理解,一般人对自动化期望都比较高),而你没有将实际的风险与效果评估展现与说服给他时,就算自动化再成功,这个项目依然得不到所得的效果。
我们在统计自动化成本时,往往发现执行维护阶段最终会超过自动化项目开发阶段。
我们应该怎么做自动化项目
看下我们的目标:
● 快速开发与交付
● 高可用维护
选择一门语言:
根据实际自动化需求,我们选择了ruby作为基础开发语言。 实际运用中,推荐使用ruby或python具备完备的模块管理与纯面向对象,,有助于建设高复用的框架与平台。
实现快速迭代:
每天日结,自动化代码要有完备的单元测试,这点通过ruby很容易实现,通过极简洁的单元测试框架让任何人都愿意做自动化代码的单元测试,这点很重要,因为你的代码再也没有人去手工测试了。
实现DRY与业务逻辑分离
DRY即Don't Repeat Yourself(不要重复自己), 永远不要让相同的逻辑代码复写两次。 一旦出现,将其分离封装,如果是公共代码(可能大多数项目会用),将其独立为gem包等形式。
业务逻辑分离,将用例业务层为独立,逻辑处理再次封装,MVC的思想作为参考点。
实际上,自动化项目更适合做敏捷模式的开发过程,如果自动化项目都没有“敏捷”, 你的被测项目又如何“敏捷” ?
我们应该关注什么?
除了自动化项目完成时间是重点外,我们要去关注:
1、质量问题
2、可维护性
质量关乎自动化项目的生命,
一旦自动化项目的经常跑失败,失败的原因经常是由于脚本引发,并且不收敛,那后果可想而知:
● 没有人再相信自动化的运行结果
● 没有人再愿意尝试不断的投入执行与分析一个无法发现有效bug的自动化测试项目中
● 没有人再愿意投入下一个自动化过程中
可维护性是指后续的产品变更引起的自动化脚本更新快捷方便,做的好的自动化是超前完成维护的,做的烂的自动化是无法维护的。
可维护性表现可在于1,修复一处代码即可完成相关所有逻辑的处理 2,便于增加新用例与复用代码。
我们谁也不愿意将自动化的脚步陷入不断的无限的维护分析的泥潭中。
总结
上面一些感悟,例子不多,但将我认为最重要的东西表达出来了,很多东西并不是死板的,呆滞的。
自动化领域更讲究创新思维。
能够将你所看到最繁琐,最无聊的事情通过自动化解决了,这就是做好自动化项目的最核心思想。
但自动化之路不是一朝半夕可以掌握,很多弯路也许你是必须要走过。 <异类>一个观点叫 1万小时规律, 你不去认真做一万小时的事情,你是不可能成为高手的。 (1万小时大概需要5-6年)
在这里共享一些心得,也与刚入门的兄弟姐妹们共勉之。 共同进步。
最后推荐一个最近文章<测试技术专家之路的成长>,我想自动化专家的发展也与此类同:http://www.51testing.com/html/09/n-247209.html
多实践,找出与自己公司合适的自动化发展之路,而不是好高鹜远,更不是以技术牛人自居,只有这样,才能脚踏实地,一步步走好适合自己的发展历程。任何行业不都这样吗?
相关链接:
走在自动化软件测试的道路上
埃及金字塔的神秘,不仅是因为它的规模宏伟、结构精密,而且它的兴起和演变至今只是一个传说,成为千古之谜。而软件测试,也感觉和金字塔有一种神秘的关系,为什么这样说呢?
金字塔中有神奇的黄金分割数Φ,其值是个无穷小数,若只取三位小数便是0.618。如用金字塔的高除以底边长,即1÷1.618 = 0.618。而金字塔许多特征数据,和13世纪数学家法布兰斯所提到的奇异数字的组合,有许多巧合之处。这些奇异数字的组合是1、1、2、3、5、8、13、21、34、55、89、144、233…它们任何两个连续的比率都接近0.618,如3/5、5/8、34/55、55/89、89/144等。而且金字塔有一个顶点、五个面、八个边,总数为十三个层面,这些特征数据也和上述奇异数字非常吻合。
首先,软件测试的出发点就是质量,软件测试的一切工作应该围绕质量而开展。质量是软件测试的中心,可以看做是金字塔的顶点,如图1-1所示。测试的其他部分就是支撑这个顶点的测试人员、测试资源、测试技术和测试流程。因此,构成软件测试的5个要素就是:质量、人员、技术、资源、流程。
这样,5个要素构成了5个面,每个面由3个要素构成,代表着软件测试的工作面。具体是怎样的工作面?请往下看,自然会越来越清楚。
在这金字塔构成中,还有每两个要素构成的8条边,每条边代表两个要素之间的关系,如何处理这些关系,也就决定着测试能否获得成功。基于要素、工作面、要素之间的关系,我们确定了13项软件测试原则、21个关键域。针对软件测试关键域,每个软件组织可以了解自己在这个领域的水平,持续进行改进。最后,列出目前所使用的各种软件测试方法,并将这些方法应用于软件测试实际工作之中。所以软件测试可概括为:

从1个中心到5个要素
质量(quality)是软件测试的中心,这是毋庸置疑的。测试是质量保证的重要手段之一,测试本身就是为质量服务的。测试能否通过,其检验的标准是用户的需求,也就是质量的标准。所以,在软件测试的5个要素中,质量是核心,其他4个要素要服务于质量,服从于质量。
如果要问,除了质量,还有什么是最重要的?那自然是测试人员。人是决定的因素,决定了技术和流程的执行。像软件开发这样的智力活动,要强调“以人为本”的管理文化,才能真正发挥每个人的潜力,以最有效的方法完成测试工作。
如果继续追问下去,在软件测试过程中,哪两样东西是我们必须关注的?答案应该是“测试覆盖率”和“效率(productivity)”。如何保证质量,一个重要的衡量方法就是测试的覆盖率,包括用户实际需求的覆盖率和代码覆盖率。在保证质量的前提下,确定任务的优先级,采取正确的策略和方法,包括自动化测试方法,以高效的方法完成测试。
一而再、再而三,关注了“测试覆盖率”和“效率”,拿什么来保证呢?这不外乎三个方面,就是测试人员、测试流程和测试的技术。就人员来说,要从招聘、培训和考核等各个环节来培育良好的团队文化,树立正确的工作态度,强化质量意识,提高团队的战斗力,构建卓越的测试团队。无论是采用敏捷的测试流程还是传统的测试流程,一定要结合具体的产品和技术特点,因地制宜,形成适合自己的、有效的测试流程。测试技术比较丰富,因而下面各章的讨论会很多,从客户端到服务器端,从黑盒测试到白盒测试,从静态测试到动态测试,全力构造一个完整的测试技术体系,使之满足测试工作的需要。这些内容,可以用图1-2形象地描述,使我们一目了然。
软件测试的金字塔体系可以基于上一节的描述进行扩充,得到如下结构,更接近于一串神秘的数字。

图1-2 软件测试核心、目标、基础等关系
最后,总结一下软件测试的5个要素。
● 质量:软件质量是软件测试的目标,也是软件测试工作的中心,一切从质量出发,也就是一切从客户需求出发。任何违背质量的东西都是问题,测试就是要找出这些问题。
● 人员:人是决定的因素,测试人员的态度、素质、能力决定着测试的效果,对测试产品的质量也有很大的影响。测试人员因素包括测试组织结构、角色和责任的定义。
● 技术:软件测试技术,包括方法、工具。
● 资源:主要是指测试环境中所需要的硬件设备、网络环境,甚至包括测试数据。另外一个重要因素就是测试时间,时间也是测试的资源,但测试人员不能看做资源,每个人的能力千差万别,不同的测试人员担任不同的角色,不能相互代替。这也是软件图书的经典之作——《人件》的作者反对将人作为资源对待的原因。
● 流程:从测试计划和测试用例的创建、评审到测试的执行、报告,设定每个阶段的进出标准。
5个工作面
基于软件测试金字塔的构成,我们好好研究其5个工作面,如图1-3所示。

图1-3 软件测试的5个基本工作面
● 质量-人员-技术:团队建设,包括人员的招聘、培训、考核等。
● 质量-人员-资源:成本管理,人员和软硬件资源都是测试的投入,但同时必须将人和软硬件资源区别对待,不要将人也作为软硬件资源那样处理,否则会带来较多的问题。
● 质量-技术-流程:技术和流程结合起来就是一种测试架构或测试框架,通过技术,将流程融入系统或工具中,流程的执行才能稳定、有效。技术通过框架固化,技术才能发挥最大效益。
● 质量-流程-资源:基础设施,构建测试环境,将测试建立在坚固、流程的基础设施之上。
● 人员-技术-流程-资源:项目管理,在一定的质量标准下,如何平衡这些要素、如何获得最大的生产力,就是软件测试项目管理的主要任务。
本文节选自《完美测试:软件测试系列最佳实践》一书,朱少民主编
LoadRunner的HTML与URL录制方式
2010年02月26日 星期五 15:46
在跟使用Loadrunner工具使用者交流的过程中,经常有人提到这个问题,基于HTML(HyperText Markup Language 超文本置标语言)模式录制与基于URL(Uniform Resource Locator的缩写,统一资源定位符,也被称为网页地址,是因特网上标准的资源的地址。)录制模式到底有什么不同?为什么通常情况下我们都会去选择使用URL模式去录制我们的业务脚本?所以在这里我把我知道的东西写出来跟同行分享和交流: HTML是一种高级别的录制模式,这种模式是基于“浏览器”或者说是“内容敏感”的。这种录制选项是让浏览器去决定在回放下载HTML资源,哪些页面资源(比如图片或者Flash内容)是需要被下载。 URL是一种低级别的录制模式,这种录制选项不允许浏览器去确定哪些页面资源(比如图片或者Flash内容)是需要下载的。每项资源在录制回话的过程中都被录制到脚本中。这种级别录制模式同时也会录制其他任何隐藏的对象,比如session ID(也就是会话ID)信息,包括发给服务端和从服务端收到的session ID信息。 脚本方面的不同,HTML级别录制模式将生成的是web_submit_form语句来提交终端用户可以看见或者修改的信息。当基于HTML模式在提交窗体时遇到错误,你可以选择URL模式去录制任何从服务端发送过来的请求和资源。而URL基本录制模式将生成的是web_submit_data语句,这些语句记录的是所有通过浏览器实际发送给服务端的信息。值得注意的是URL录制模式会录制那些HTML模式没有能录制到隐藏信息。通常情况下,隐藏信息里面会包含session ID信息。 写到这里,熟悉的人可能应该明白为什么在通常的情况下,我们选择URL模式去录制我们基于Web(HTTP/HTML)协议的脚本,概括的说就是现在的应用(或者说将来的应用)为了安全性,都会包含像session ID、token等动态信息。简单的说就是每一访问,服务端都会给客户端发送一个描述会话的session信息,而session ID使用的是动态的生成技术。如果要是脚本能够正常回放,通常需要把这个动态的信息保存下来,这个需要使用到correlation 技术(也就是关联技术)。在以后我会在我的博客里面继续写我对关联的理解(包括自动关联、手工关联、规则等实用技术)。 在Web(HTTP/HTML)录制中,有2种重要的录制模式。用户该选择那种录制模式呢? HTML-mode录制是缺省也是推荐的录制模式。它录制当前网页中的HTML动作。 在录制会话过程中不会录制所有的资源。在回放时,HTML-mode脚本积极地解析返回的信息来获得要下载的资源。 HTML-mode是亦称上下文敏感方式因为它只能在先前请求的结果的上下文之内执行。由于许多的HTTP 请求数据都是从内存中取出来的,所以语句必须在正确的前个请求之后执行。 HTML-mode录制的优点是: 1.资源从内存中取出且在回放时下载。因此,脚本比其他的录制方式更小且更容易阅读。 2.由于只有较少的硬编码脚本,因此只有较少的动态数值需要关联。 3.可以插入图片检查之类的语句以检查结果是否正确。 4.因为HTML模式回放时需要积极地解析返回的信息,因此它可能会比其他录制模式更加占用资源。然而,HTML模式record/replay有相当大的改善,使得差异最小化且微不足道。 URL-mode选项指导VuGen录制来自server的所有的请求和资源。它自动录制每一个HTTP资源为URL的步骤。这种录制模式甚至抓取非HTML应用程序,例如applets和非浏览器的应用程序。推荐使用这种录制方式录制以下情况: 1。录制非browser的应用程序 2。取得在下载或不下载哪些资源上更好的控制,既然你可以在脚本中修改。 3。当使用LR6.x时,录制使用applet和/或javascript的浏览器应用程序 由于URL-模式录制了所有的请求和资源,需要做更多的关联。脚本看起来也会相当的长。 ------------------------------------- 我发现用这两种模式录制Mercury的网页( http://www.mercury.com/),结果却有很大差别,HTML-based的response time是7.4秒左右,而URL-based的却达到22秒左右。根据MI上面的解释,估计是由于HTML-based模式的资源占用,从内存中读数据引起的。 在使用LoadRunner进行WEB脚本录制的时候,很多人不清楚URL-based 方式和 HTML-based方式的差别,以及何种情况下使用何种录制方式,这里给出一个简单的判断方法。 HTML-based 方式 HTML-based 方式对每个页面录制形成一条语句,对LoadRunner来说,在该模式下,访问一个页面,首先会与服务器之间建立一个连接获取页面的内容,然后从页面中分解得到其他的元素(component),然后建立几个连接分别获取相应的元素。 URL-based 方式 URL-based 方式将每条客户端发出的请求录制成一条语句,对LoadRunner来说,在该模式下,一条语句只建立一个到服务器的连接,LoadRunner提供了web_concurrent_start和web_concurrent_end函数模拟HTML-based的工作方式。 如何决定选择何种录制方式? 1、如果应用是WEB应用,首选是HTML-based方式; 2、如果应用是使用HTTP协议的非WEB应用,首选是URL-based方式; 3、如果WEB应用中使用了java applet程序,且applet程序与服务器之间存在通讯,选用URL-based方式; 4、如果WEB应用中使用的javascript、vbscript脚本与服务器之间存在通讯(调用了服务端组件),选用URL-based方式。 |
Jaslabs的Justin Silverton列出了十条有关优化
MySQL查询的语句,我不得不对此发表言论,因为这个清单非常非常糟糕。另外一个Mike也同样意识到了。所以在这个博客中,我要做两件事情,第一,指出为什么这个清单很糟糕,第二,列出我的清单,希望我的比较好些。继续看吧,无畏的读者们!
为什么那个清单很糟糕
1、他的力气没使对地方
我们要遵循的一个准则就是如果你要优化代码时,应该先找出瓶颈在哪。然而Silverton先生的力气没有用对地方。我认为60%的优化是基于清楚理解SQL和数据库基 础的。你需要知道join和子查询的区别,列索引,以及如何将数据规范化等等。另外的35%的优化是需要清楚数据库选择时的性能表现,例如 COUNT(*)可能很快也可能很慢,要看你选用什么数据库引擎。还有一些其他要考虑的因素,例如数据库在什么时候不用缓存,什么时候存在硬盘上而不存在 内存中,什么时候数据库创建临时表等等。剩下的5%就很少会有人碰到了,但Silverton先生恰好在这上面花了大量的时间。我从来就没用过 SQL_SAMLL_RESULT。
2、很好的问题,但是很糟糕的解决方法
Silverton先生提出了一些很好的问题。MySQL针对长度可变的列如TEXT或BLOB,将会使用动态行格式(dynamic row format),这意味着排序将在硬盘上进行。我们的方法不是要回避这些数据类型,而是将这些数据类型从原来的表中分离开,放入另外一个表中。下面的 schema可以说明这个想法:
- CREATE TABLE posts (
- id int UNSIGNED NOT NULL AUTO_INCREMENT,
- author_id int UNSIGNED NOT NULL,
- created timestamp NOT NULL,
- PRIMARY KEY(id)
- );
-
- CREATE TABLE posts_data (
- post_id int UNSIGNED NOT NULL.
- body text,
- PRIMARY KEY(post_id)
- );
|
3、有点匪夷所思……
他的许多建议都是让人非常吃惊的,譬如“移除不必要的括号”。你这样写SELECT * FROM posts WHERE (author_id = 5 AND published = 1),还是这样写SELECT * FROM posts WHERE author_id = 5 AND published = 1 ,都不重要。任何比较好的DBMS都会自动进行识别做出处理。这种细节就好像C语言中是i++快些还是++i快些。真的,如果你把精力都花在这上面了,那 就不用写代码了。
我的列表
看看我的列表是不是更好吧。我先从最普遍的开始。
1、建立基准,建立基准,建立基准!
如果需要做决定的话,我们需要数据说话。什么样的查询是最糟的?瓶颈在哪?我什么情况下会写出糟糕的查询?基准测试可以让你模拟高压情况,然后借助性能测评工具,可以让你发现数据库配置中的错误。这样的工具有supersmack, ab, SysBench。这些工具可以直接测试你的数据库(譬如supersmack),或者模拟网络流量(譬如ab)。
2、性能测试,性能测试,性能测试!
那么,当你能够建立一些高压情况之后,你需要找出配置中的错误。这就是性能测评工具可以帮你做的了。它可以帮你发现配置中的瓶颈,不论是在内存中,CPU中,网络中,硬盘I/O,或者是以上皆有。
你要做的第一件事就是开启慢查询日志(slow query log),装上mtop。这样你就能获取那些恶意的入侵者的信息了。有需要运行10秒的查询语句正在破坏你的应用程序吗?这些家伙会展示给你看他的查询语句是怎么写的。
在你发现那些很慢的查询语句后,你需要用MySQL自带的工具,如EXPLAIN,SHOW STATUS,SHOW PROCESSLIST。它们会告诉你资源都消耗在哪了,查询语句的缺陷在哪,譬如一个有三次join子查询的查询语句是否在内存中进行排序,还是在硬盘 上进行。当然你也应该使用测评工具如top,procinfo,vmstat等等获取更多系统性能信息。
3、减小你的schema 在你开始写查询语句之前,你需要设计schema。记住将一个表装入内存所需要的空间大概是行数*一行的大小。除非你觉得世界上的每个人都会在 你的网站注册2兆8000亿次的话,否则你不需要采用BITINT作为你的user_id。同样的,如果一个文本列是固定大小的话(譬如US邮编,通常 是”XXXXX-XXXX”的形式),采用VARCHAR的话会给每行增加多余的字节。
有些人对数据库规范化不以为意,他们说这样会形成相当复杂的schema。然而适当的规范化会减少化冗余数据。(适当的规范化)就意味着牺牲少 许性能,换取整体上更少的footprint,这种性能换取内存在计算机科学中是很常见的。最好的方法是IMO,就是开始先规范化,之后如果性能需要的 话,再反规范化。你的数据库将会更逻辑化,你也不用过早的进行优化。(译者注,这一段我不是很理解,可能翻译错了,欢迎纠正。)
4、拆分你的表
通常有些表只有一些列你是经常需要更新的。例如对于一个博客,你需要在许多不同地方显示标题(如最近的文章列表),只在某个特定页显示概要或者全文。水平垂直拆分是很有帮助的:
- CREATE TABLE posts_tags (
- relation_id int UNSIGNED NOT NULL AUTO_INCREMENT,
- post_id int UNSIGNED NOT NULL,
- tag_id int UNSIGNED NOT NULL,
- PRIMARY KEY(relation_id),
- UNIQUE INDEX(post_id, tag_id)
- );
|
artificial key完全是多余的,而且post-tag关系的数量将会受到整形数据的系统最大值的限制。
- CREATE TABLE posts_tags (
- post_id int UNSIGNED NOT NULL,
- tag_id int UNSIGNED NOT NULL,
- PRIMARY KEY(post_id, tag_id)
- );
|
6、学习索引
你选择的索引的好坏很重要,不好的话可能破坏数据库。对那些还没有在数据库学习很深入的人来说,索引可以看作是就是hash排序。例如如果我们 用查询语句SELECT * FROM users WHERE last_name = ‘Goldstein’,而last_name没有索引的话,那么DBMS将会查询每一行,看看是否等于“Goldstein”。索引通常是B- tree(还有其他的类型),可以加快比较的速度。
你需要给你要select,group,order,join的列加上索引。显然每个索引所需的空间正比于表的行数,所以越多的索引将会占用更 多的内存。而且写数据时,索引也会有影响,因为每次写数据时都会更新对应的索引。你需要取一个平衡点,取决每个系统和实施代码的需要。
7、SQL不是C
C是经典的过程语言,对于一个程序员来说,C语言也是个陷阱,使你错误的以为SQL也是一种过程语言(当然SQL也不是功能语言也不是面向对象的)。你不要想象对数据进行操作,而是要想象有一组数据,以及它们之间的关系。经常使用子查询时会出现错误的用法。
- SELECT a.id,
- (SELECT MAX(created)
- FROM posts
- WHERE author_id = a.id)
- AS latest_post
- FROM authors a
|
因为这个子查询是耦合的,子查询要使用外部查询的信息,我们应该使用join来代替。
- SELECT a.id, MAX(p.created) AS latest_post
- FROM authors a
- INNER JOIN posts p
- ON (a.id = p.author_id)
- GROUP BY a.id
|
8、理解你的引擎
MySQL有两种存储引擎:MyISAM和InnoDB。它们分别有自己的性能特点和考虑因素。总体来讲,MyISAM适合读数据很多的情况,InnoDB适合写数据很多的情况,但也有很多情况下正好相反。最大的区别是它们如何处理COUNT函数。
MyISAM缓存有表meta-data,如行数。这就意味着,COUNT(*)对于一个结构很好的查询是不需要消耗多少资源的。然后对于 InnoDB来说,就没有这种缓存。举个例子,我们要对一个查询来分页,假设你有这样一个语句SELECT * FROM users LIMIT 5,10,而运行SELECT COUNT(*) FROM users LIMIT 5,10 时,对于MyISAM很快完成,而对InnoDB就需要和第一个语句相同的时间。MySQL有个SQL_CALC_FOUND_ROWS选项,可以告诉 InnoDB运行查询语句时就计算行数,之后再从SELECT FOUND_ROWS()来获取。这是MySQL特有的。但使用InnoDB有时候是非常必要的,你可以获得一些功能(如行锁定,stord procedure等)。
9、MySQL特定的快捷键
MySQL提供了许多扩展,方便使用。譬如INSERT … SELECT, INSERT … ON DUPLICATE KEY UPDATE, 以及REPLACE。
我能用到它们时是毫不犹豫的,因为它们很方便,能在许多情况下发挥不错的效果。但是MySQL也有一些危险的关键字,应该少用。例如 INSERT DELAYED,它告诉MySQL不需要立即插入数据(例如在写日志的时候)。但问题是如果在很高数据量的情况下,插入可能会被无限期延迟,导致插入队列 爆满。你也可以使用MySQL的索引提示来指出哪些索引是需要使用的。MySQL大部分时间运行是不错的,但如果schema设计不好的话或语句写得不好 的话,MySQL的表现可能很糟糕。
10、到这里为止吧
最后,如果你关心MySQL性能优化的话,请阅读Peter Zaitsev的关于MySQL性能的博客,他写了许多关于数据库管理和优化的博客。
探索式
测试(Exploratory
Test)经常被简称为ET,由 Cem Kaner 1983年建立的测试概念,这几年随着
敏捷方法而大行其道。敏捷方法的迭代频率很快,每个迭代时间很短,自然想到如何减少文字
工作,避免写
测试用例,ET自然是一个很好的选择。ET简单理解为测试设计与执行同步进行。
不过,我们以前熟悉测试中的错误猜测法、Ad hoc测试等方法,不管Cem Kaner承认不承认,ET概念很有可能来源于这些先前的概念,在这些概念的基础上丰富它,试图给ET建立一个比较系统的体系,例如引入基于上下文驱动 (Context-driven)、基于session的测试等。想当初,我们用错误猜测法、Ad hoc测试方法时,一定也会考虑业务或功能的上下文关系,没有上下文还做什么测试?也会考虑某些场景,更多会考虑一些特别的场景,如人们常说的 corner case,right? 当然,ET和错误猜测法、Ad hoc测试是有区别的。
谈谈探索式测试与基于脚本的测试(Script-base Test 或 Scripted Testing,ST)之关系,不论是在传统测试流程还是在敏捷测试中, 这两者是相辅相成的,谁也不能代替谁,正如James Bach也谈到“Balancing Exploratory Testing with Scripted Testing,... two approaches to testing are fully compatible” 。而且在不同的场景有各自的优势,例如:
● 发现问题来看,探索式测试效率会更高些,甚至高得多;
● 测试乐趣看,也会优先选择探索式测试;
● 敏捷中新功能测试会选择探索式测试;
● 探索式测试不易实现自动化,所以自动化测试先需要脚本,然后执行;
● 归测试比较确定,需要不断运行,自然会选择基于脚本的测试(ST);
● 产品线来看,开发周期长,复用会大大提高效率,ST也具有很大优势。
所以,在一个项目中,经常是同时采用这两种方法——ST和ET,而且不同的组织环境或项目环境,随时间的投入是不一样的,这就是那两条神奇的曲线:

当初我没有在线上标ST和ET,就是因为每根线都可能是ET或ST,例如:
1、如果自动化测试水平低或没有自动化测试,就需要在前期有更多的ET,在发现产品问题的同时学习产品、更深地理解产品,并通过发现问题来完善测试用例。而为了降低产品质量风险,后期需要进行更系统的测试,特别是要完成大量回归测试、对产品质量有一个完整的评估,需要执行ST。由于自动化水平低,这时人力都投在ST上,就没有经历做ET,而且也不必要。
2、如果自动化水平高,前期需要开发脚本,ST的投入自然大。但自动化执行时,虽然会运行大量用例,但解放了生产力,测试人员有更多时间投入ET。

实际环境所处的场景会更多,不管怎样,先要清楚自己测试工作中有什么问题,然后采用合适的方法来解决问题。或者说,要清楚自己的目标,是让团队获得激情还是让公司处在稳定的不败之地、还是为了尽快发现Bug还是提高产品的质量,方法何时使用、如何使用、谁使用等都可能不同。即先问Why?What?然后才考虑How、Who、Where?
关于探索式测试和脚本测试还有许多东西可以谈,时间关系,今天就谈到这里。
出自:http://blog.csdn.net/kerryzhu/article/details/7489319
大纲: 自动化测试的现状
自动化测试的发展
1、包含的领域
2、发展的思路
3、观点: 自动化测试是一种软件开发交付过程
自动化测试成败在于自动化项目的质量与可维护性
自动化测试不只是测试的自动化,应当是流程的自动化
自动化的难点:
1、极强的定制性使得引入自动化成为难事
2、预言性的需求设计使得自动化需求变化极快,同时要求开发周期越短越好
3、软件流程往往成为自动化道路中的拌脚石
我在自动化测试的计划
未来的自动化测试在哪里?
引用
rubywindy说前面的路: 软件行业算得上是高科技行业,“零成本”缔造了N多帝国公司的神话。 这也从侧面说明软件业还不够“成熟”,因为在“传统”的眼里,很难出现一家独大的局面。 在软件业中,自动化测试要算是一个很小的分支了。 然而软件测试往往花费了50%以上的项目周期,而自动化测试正像传统的自动化流水线工厂一样,试图解决这个关键问题。 |
我在这个领域不长时间,算上入手开始到现在,大概有1年半有余。一直有一种想分享一些想法的冲动,然而总是感觉时机不成熟,毕竟这个领域在中国是新兴的,而我也是一种新入门的感觉,然而,测试领域的混乱状态与最近越来越清晰的思想使得我也借Ruby大会后的时间梳理一下我的想法。
自动化测试包含的理念是什么?
看了许多51testing上的文章贴子,很多人对此不清楚,我想简单几句表达下我的观点。
为什么出现自动化测试? 因为手工测试效率低下,回归成本高昂,许多在前期应当控制的代码质量由于手工测试介入过晚导致测试成本过高。 自动化测试的出现要求提高整体测试效率,极大降低回归成本,通过单元自动化,接口自动化,自动化代码检视,编译自动化构建,冒烟构建等立体动态的方案从而 可以尽早从测试手段控制版本开发质量,降低后续测试成本,并快速集成回归。
我想提供一个图看下变化过程:

这是一个传统的,也是我们一般人使用的软件开发模式,国外有个好听的名字: 瀑布开发模式(你坚着看,很形象吧?)
而自动化测试应当提供什么呢?
看下图:

我们今天不讨论敏捷,这里的自动化模式是基本不改变开发模式的方式下的开展过程。(我想大部分公司很难强推行大规模的开发模式转变:大部分原因被冠名风险与人)
这个图是以自动化云层(叫平台也行)依靠,提供全方面的自动化测试过程。
● 自动化测试的手段: 以自动化测试代码为依托,提高高可用的测试方案与立体的测试体系。
● 自动化测试的目的: 让软件测试无事可做!
解释下目的,充足的快速的立体多方位的自动化测试加之规范的开发流程,bug既在编码中与之前被发现,何来传统的测试工作?
也许较真的兄弟们会说,软件测试覆盖的面可多了,黑盒,模糊,场景,发散等,你怎么取代? 我说的测试工作是特指我们平时花费最长最无味的系统测试。
解释了自动化测试的所在的领域与基本理念后,下一个问题,
如何发展?
这里就我在工作过程中的一些思路谈一谈,我们知道自动化测试不具备通用性,明白这点很重要。我再解释下,假如你在华为的路由器测试,你会使用cli操作命令进行自动化,你的平台很可能依托在复杂的资源管理平台上。
而如果你在人人,你会使用selenium等UI工具进行自动化,你可能直接使用了selenium与hudson作集成自动化。
如果你是做企业金融的公司,你会使用flash测试工具,autoit,甚至商业化的RFT等
另外,自动化还有一个特点,投入成本高,产出可能很缓慢。 如果你在预算投入不足时,千万不要貌然启动自动化,不要对其报有任何幻想。
如果明白这两点,你们公司应该会成立专门的自动化团队了,并且逐步的形成自动化测试的框架与相关的自动化效果产出了。
最后我想重点谈谈技术在自动化测试发展中的作用。
● 问题一: 选择商业工具还是自主开发? 商业工具一般很强大,常见的如QTP,RFT,Robot,SilkTest等,并且带有脚本录制与快速回放。那我们直接选好了?
No,我的建议是不要去选,至少不要轻易的去选,并不是说你家有钱不让你去花,因为要知道,自动化测试不具备通用性,我们的产品很难说能适应测试工具,而是应该让工具去适应产品。
自主开发? No,我的建议也是No,世界上有一批优秀的程序员(测试员),他们开发了一批优秀的开发的自动化工具供我们使用,我们只需要动动手,整合一个框架出来就 ok了。 你会担心,谁帮我维护?有bug找谁? 你要记住,如果你的技术不足于达到维护这个自动化测试工具时,你的自动化测试基本也宣告失败了,那么,发现bug提交给相关社区,或者自己去修改并 push请求。达到技术共享的目的。
Java代码
少量推荐的开源项目: watir: http://watir.com/ Wiki社区: http://wiki.openqa.org/display/WTR/Project+Home 优秀的web自动化工具,采用ruby作为底层语言. API堪称完美. 维护速度很快 selenium: http://seleniumhq.org/ 当然,采用开源并不是成功的必然条件,你还要根据实际的产品需求逐步的形成适合的自动化测试解决方案而不仅仅是一个工具. 这个解决方案应该能适合绝大部分自动化需求,而且根据DRY原则,做到最简洁,最易用,最稳定. |
● 问题二: 先开发框架还是先作自动化项目? 有些人上来就想做一套框架搞自动化,生怕技术生锈了,实际上我的建议是:
先有自动化测试代码,形成简单的结果报告,代码复用规范,将自动化效果展示出来。
第二步摸清需求后,进而设计一套合适的框架,这里可充分利用开源的优势,一个技术好的人甚至花不超过1周可搞定一个框架。我们的ATT框架当时 仅花费了20*3人天完成。(一套关键字驱动框架,目前还没有开源) 另外一个单元级框架花费3天完成,具备脚本规范,日志输出,等作用。
第三步,设计框架要考虑可扩展性,要有预言性的设计在里面,比如ATT框架对外的接口是一个xmlrpc协议的接口,后来我们花了半年开发了平台管理项目,与ATT框架完美对接。
最后,从流程上对自动化云层进行整合,梳理各项流程点,把能够简化的流程步骤全部由云层处理。(就像乔布斯那样把iphone的开关都去掉了,因为实在对用户没有必要)
问题三:人,我的人应该具备什么样的能力?<自动化软件测试实施指南>这本书讲的很好。
我就简单总结下,
1、技术上不要求太精,但一定要广,并且对新技术具备很高的热情,我以后如果去面试,会第一个问题问,是否在业余时间开发过项目,如果用到了rails,erlang,云技术,甚至喜欢研究flex,敏捷,那么是我的首选。
2、创新思维,凡事不是第一感觉为否定,而是用研究来验证自己的想法是否可行,能否做到把不可能自动化的东西也自动化掉。
3、团队交流与协助,这点不用多说了。
4、改进意识,不甘于不断的重复工作,如果没有这点就没有自动化。
当然,这样的人有少量就够了。
最后就我的里程,作一个回顾,也会以上理论的东西作一个实质的归纳,就当听听故事吧
大学玩了一半学了一半,学业成绩称不上优秀,但也算不错。(至少没有挂课~)
毕业的时候,我直接投了深圳这边公司的简历,当时当然是一心投的开发职位,然而,对开发倒是一种不舒服的感觉,因为毕业设计的时候设计的那个邮件服务器始终存在一个bug,让我决定可以试试测试职位,最终通过了现在的公司的面试。( 主要是动手能力强, 嘿嘿)
随便说一下,当时腾讯来过,我去面准备不足(第一次面),直接被一面bs,我就暗下决心,你bs我,我就以后bs你,所以现在听有人进了腾讯,我就不由分说bs一番。(现在只是说说了,虽然心里知道它现在的霸主地位) 等我以后再真正bs你吧。
那时候,华为还没有过来,但早就听说华为的速度(无论面试还是offer)最慢,我是那种不喜欢条条框框的人,直接不等它了。
进了公司后,开始做测试,我的性格里只有两种事情划分,要么做好做么不做,开始的测试工作还是蛮有意思的,学习也真的很快,期间也收获了同事们 的认可,然而时间一长,测试的重复工作和无力的成就感使得我不得不重新考虑以后的计划,以后的几天,我向我导师反映了我的心态与计划,转岗or离开。 然而,在那时候我坚持了下来,半年后我们的测试主管确定成立自动化测试部,在10年4月的某一天,我全职投入自动化,从基本上是零一直到现在。
因为公司的自动化发展特殊性,我们的自动化投入基本上是:
投入自动化项目 -> review效果 -> 剥离框架 -> 投入自动化项目
目前效果产出比较明显,好几个版本ROI超过了2,直逼3。 在这里我建议投入的项目是:
基本功能bvt -> 易于实现的自动化功能 -> 提高部分模块自动化率, 期间不断优化框架与平台,整合出我们的自动化云端。
目前我们有5个人全职自动化,马上会有新人继续加入。
写在这里,这篇已经很长了,接下来就自动化实施的难点加以分析与说明。为自己留下些成长中途的记忆。
在前述的文章中对独立测试无用论做了“激烈”的回击,支持者有之,反对者有之,总之能引起大家的思考就好。这篇我打算写温和一点的内容,那就是,反向思考,为什么有些独立测试不招人待见?如果从独立测试工程师自身出发,我们应该如何避免做“庸俗”的测试工程师?以下是观点:
1、做发动机,不做拖油瓶。
当码农那年,刚开始进一项目,对面的核心开发就开始被一个测试大哥“骚扰”,此测试大哥言谈高调,目光如炬,最善发现类似页面俩空格只有一个,俩输入框不该在一行这类问题。
发现UI错误本身没错,确实现在好多页面的界面也够呛。但是,哥,咱们是在项目的前期啊,开发脑子里都是核心业务如何实现,三个表四百个字段怎么高效操作,你确定他们该停下来改UI吗?
UI是重要,UAT(客户验收测试)之前抽个几天就可以做出很大改进,不是吗?
团队利益的核心是什么?按时交付。而测试人员的价值是:项目高质量交付。那么团队利益和测试利益在根本上就可能冲突。这还怎么一块过?......其实也能过。男人的价值观和女人还不一样呢,那么多两口子不也一过一辈子。
所以,后来做测试经理和团队负责人时,在项目前期,都要求测试人员提高对这类UI、易用性缺陷的容忍度,这么做有两个好处:
第一, 开发和测试在前期不会因为这些问题争执不下,前提是,开发人员必须耐心的给核心测试讲清楚,现在重要的是什么。小问题不一定不重要,什么时候你准备把这些东西拾起来?
第二, 测试人员避免心理收到打击:为什么我辛苦测试出来的bug没人重视。在这种时候,耐心的把项目的情况解释清楚,测试人员一般都会接收团队价值。
不做拖油瓶测试,核心的要求就是:你得知道项目处于什么阶段,最大的风险是什么,该做什么不该做什么,不该做的什么时候捡起来做。
在最极端情况下,测试组的结论是“产品质量是狗屎,不能发布”,但是项目经理的要求是“一定要发布,除非从老子尸体上踩过去”,那怎么办?
三国中关羽失荆州被杀,刘备大怒准备伐吴,诸葛亮劝谏不可,刘备不听,最后果然刘备大败。
大概,项目经理有更高的诉求,测试所为,只能是把情况列出,含泪再拉一把:主公,我们还是准备准备在Release吧…Orz
现实就是这样,决策就有风险,测试就是提供决策支持,至于听不听,结局如何,只能让历史去评说了。
PS: 文中那位测试大哥,真心不适合做测试,适合去当公务员,当那个圈儿的人,最后他还真去事业单位了。
2、做谢耳朵,不做软耳朵。
以前面试测试工程师的时候,很喜欢问一个问题,如果你提的bug,开发人员激烈反对,你怎么办?
注意!这个问题没有标准答案。只是想通过测试人员的回答检验他们对于反对意见的处理方式。
软耳朵测试要不得:开发说这不是bug,这是特性,好吧那就是特性;开发说这是你用的方式不对,好吧那就是方式不对;开发说这是你点鼠标的姿势不对,好吧那就是姿势不对;开发说测试没技术含量,好吧那就是没技术含量;开发说不需要测试,好吧那就不需要测试!
拜托,拿着这样的测试人员写出来的报告,你晚上能放心的睡觉?
个人喜欢有点小强迫症的测试工程师:不能复现的一定想办法复现;开发不接受的一定要据理力争,真理是越辩越明。
看生活大爆炸吗?里面的谢耳朵最多人喜欢,他有时候够讨厌,但是他的观点很多时候也最有价值,不是吗。
3、不抱怨。
哥上大学的时候最讨厌的那种人就是:整天自言自语,如果运气好一点就去清华了~~喵的,有那功夫倒是退学去复读啊?
有些庸俗的测试工程师,整天把如下的话挂在嘴边:
唉,我的工作还真的是没有技术含量。
如果我运气好一点我就去做开发了。
我的工作好重复。
整天吐槽这些,你还不如放弃测试,去随便做个什么你认为可以解放你的职位。哪些你没有从事的职位就那么好?
你说工作充满重复,可你知道那些话剧大师的台词重复了多少遍?
你说开发有技术含量,可你知道get,set一千遍一点技术含量也没有吗?
我尊重那些即使大部分是重复,仍然兢兢业业不放过任何细节,自己寻找新意的工程师;尊重那些别人都在无所事事给淘宝做人肉压力测试时,自己默默在画bug鱼骨图的工程师;尊重那些真正热爱这个职业,维护这个职业的人。
有句话叫做,世间三件好:别人家的饭菜,别人家的媳妇,别人家的工作。
4、争论,不争吵。
我们的工作就是给人挑茬,正常人被找茬都会下意识的反应:md,老子才没有错。差别就是年轻开发会张嘴而出,成熟开发会在心里默念一遍然后给你一个职业的笑脸。所以开发和测试经常吵起来,所谓的小吵怡情,大吵伤身,一定要在可控范围。
如何要做到争论而不争吵,借用捷克政治家哈维尔的论坛讨论守则(个人不同意他的不少政见,但是支持几个观点)
《对话守则》: a. 对话的目的是寻求真理,不是为了斗争。 b、不做人身攻击。 c、保持主题。 d、辩论时要用证据。 e、有可能承认自己是错的。 f、要分清对话与只准自己讲话的区别。 g、对话要有记录。 h、尽量理解对方。
另外加一条,能在工程师级别解决的,就不要交给你的老板…
我觉得很多测试和开发之间的矛盾,实际上是沟通的方式不对。就开发人员来说,他们只是不太善于沟通,他们真的是一些单纯的好人?
因为写用例的习惯,一篇争取只有一个观点,但是“庸俗”测试者真的是一个大话题,这篇内容多一点,忍耐这看吧。后续对这个话题,我再补充。
PS:有一个工程师有天问,如果把开发和测试对等于工地上的职位,开发是码砖的,测试就是质检或者监理吗?我回答,错误,开发是码砖的,那测试就是那个抹泥的。开发测试是配合关系,绝不是管理关系。
在本篇文章中,我们将集中介绍一些方法,来帮助你在你的环境中使用并确保IIS7服务器和其应用程序的安全。
1、第一步,确保你的Web服务器是强化的OS操作系统。如果你使用的是Windows Server 2008 R2的操作系统,那么服务器核心安装版本会给你需要的——所有功能,但不能降低被攻击的风险。如果你正在使用常规版本的Windows Server,可以试着安装IIS,它只是作用于你目前所需要的装置。根据你的需要,也可以恢复或者安装更多你所需要的功能。注意,当你添加了,你不使用的装置时,这会使你受到的攻击范围扩大。
2、使用防火墙可以真正帮助你保护WEB服务器,尤其是面向互联网的服务器。防火墙能确保服务器只接收有效的有服务的封包。当外部袭击者试图对你的服务器进行恶意攻击时,防火墙就是你的第一道防线。使用入侵预防系统(IPS),可以进一步保障你的系统,尤其是IIS服务器。 如果你的系统不是很大,不需要装特定的硬件防火墙装置时,你也可以利用Windows Server 2008的综合防火墙同样可以获得较好的安全性。
3、用IIS7控制ip和域限制访问你WEB服务器的内容。 例如,你可以只授权组织内部域的访问。或者添加除合作伙伴以外,管理员家里的IP地址,老板或其他任何你希望可以访问的组织或者个人。
4、IIS7可让你更好的过滤需要处理的,需要过滤的信息。利用这一特点你可以对特定规则要求过滤,例如处理带有特定扩展名的文件,或者处理在URL中的特定短语。
5、当一个有效的包进入IIS处理时,同时也应该会有一个授权的人。IIS7允许你使用一个过程调用 URL授权。 特定的页面和/或Web服务器的网站,可以授权给不同的用户。默认情况下,用户应首先验证自己,并根据其验证身份,然后允许或不允许进入他们所要求的网页/网站。这与之前ISS版本不同,管理员可设置文件系统级别上的权限。使用URL授权IIS7的方式来支持更详细的授权用户。
6、确保你的IIS服务器的最佳方法之一是通过使用有证书的SSL通信在用户和Web服务器之间。如果服务器是公开使用的,你应该要从GoDaddy或Verisign这样的受信任的证书颁发机构颁发的证书。这个证书在任何浏览器上,在任何一台电脑上,都是可信任的,也是最容易的,但是使用SSL的缺点就是价格较高。如果IIS服务器只在你的组织内部使用,你可以使用自己的PKI证书发出的Web服务器,在你所处的环境。但是,内部用户访问时可能存在,在不同的电脑上没有安装证书的计算机访问会出现问题。如果你的IIS服务器只在测试环境中使用,那么你可以在ISS管理工具中,使用自签名的证书。在以前的ISS版本中没有集成这一功能,你必须从微软下载一个工具来创造自己的签名证书,而在IIS7中,这个过程就容易多了。
7、日志 是一个让你最有保障的方法。它可帮助你搜索攻击源或者一个服务器损坏的原因。从一开始就确保你的设置,并在危机关头协助你的监测工作。
8、如果你感觉你的IIS基础设施和所有的安全解决方案已经没有问题的话,那么就要进行测试了。使用测试工具微软会提供给你大师级的策略来确保你的测试是最好的方法。 做测试最常用的工具是SCW和SCM。下面就来介绍一下:安全配置向导(SCW)——这是根据你的服务器除IIS服务器之外,是否或者还扮演一些其他的角色,而有所不同。 测试结束后SCW会告诉你如何提高服务器安全性的报告和建议。安全合规管理器(SCM)-是微软给你的服务器做安全测试的工具。在与配置服务器的预定义模板进行对比后,通过改变使用策略来配置服务器。SCM使用更新过的数据库工具,要比SCW所使用的工具更复杂。从而确保你定期进行初始化安装服务器后能运行这些工具。
9、上面提到了有关IIS日志记录功能的作用,但日志最重要的作用是为你监视特定事件可能导致服务器或托管的应用程序中存在的问题。同样重要的是为你监控服务器本身的运行时间,可用性和性能问题。 也可以监控IIS服务器的一个SLA协议的对象,无论是内部(公司)或外部(客户端)的SLA要求。 理论上,这种监测可以由一个服务器管理员手动完成,但要更高效、更可靠的话可把这种工作,交给像Monitis的监测公司解决。
说到存储过程和触发器,其实在以前做机房收费系统的时候就接触到了。但是当时总感觉存储过程和触发器是比较高级的东西,这个系统不用这些东西也可以。于是就一直没有好好研究这块知识。现在看牛腩新闻发布系统,再一次涉及到了这个东东,这才发现,存储过程和触发器并没有想象的那么高深莫测。也许有人会说:那是你没有深入研究。是,我承认,但个人觉得目前我们还没有必要那么深入研究。我们要做的就是:用20%的努力,获得80%的知识。这样就基本上可以满足我们日常的需求了。下面就宏观上说一下存储过程和触发器。
什么是存储过程呢?官方是这样定义的,存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。
1、创建存储过程语句如下:
createprocedure 存储过程名 @[参数名] [类型],@[参数名][类型] as begin 自定义的功能 end |
2、调用存储过程
exec sp_name [参数名]
3、删除存储过程
drop proceduresp_name
其实,说白了,存储过程就是一类特殊的函数,只要我们给它合适的参数就可以直接调用,跟调用API函数差不多,唯一不同的就是API函数大部分是别人写的,而存储过程我们一般都是自己写。
注意:不能在一个存储过程中删除另一个存储过程,只能调用另一个存储过程。
那么什么是触发器呢?严格意思上说,触发器就是存储过程,只不过它的执行不是由程序调用,也不是手工启动,而是由事件来触发。
创建语句如下:
CREATE TRIGGER`<databaseName>`.`<triggerName>` < [ BEFORE |AFTER ] > < [ INSERT | UPDATE | DELETE ] > ON <tableName> FOR EACH ROW BEGIN --do something END | |
这时有人不解了,什么叫由事件来触发呢?其实这和botton按钮的点击事件一样,只不过触发器是由Insert、Update、Delete这些动作触发,而botton的点击事件是通过点击的动作来触发的。
那么存储过程有哪些优点呢?
1、速度快。
在运行存储过程前,数据库已对其进行了语法和句法分析,并给出了优化执行方案。也就是说,存储过程在调用前就已经编译好了,所以存储过程能以极快的速度执行。
2、存储过程可以重复使用,可减少数据库开发人员的工作量 。
3、保证数据的安全性。
通过存储过程可以使没有权限的用户在控制之下间接地存取数据库,从而保证数据的安全。
4、保证数据的完整性。
通过存储过程可以使相关的动作在一起发生,从而可以维护数据库的完整性。
既然存储过程有如此多的好处,那么我们做项目的时候是不是用的越多越好呢?答案肯定是NO。万事都有个度,存储过程也一样。如果在一个程序系统中大量的使用存储过程,那么必然会导致它的数据结构相当复杂,这样维护该系统将会是相当困难的一件事。
让我们合理使用触发器和存储过程,尽情享受他们带给我们的方便。