【实测】有奇效-用测试用例设计的路子去学习新知识点。

最近我在给学员上课的时候,使用了一种比较有趣的方案。这里给大家分享一下。名字我就暂时叫做:测试用例方式学习法

    主要核心是通过从一个简单的知识点定义去入手,用一个最简单的有效等价类用例来举例讲解,然后不去查看官网或者各种教程那样的话属于比较流水直线记忆,印象不深刻。所以我不断地使用测试的思维,去写各种情况的该知识点的使用方法,也就是用例,然后要求学员去猜运行结果(这里对错无所谓),然后把这些用例,一一当场演示,无论学员一开始想猜的预期答案是对还是错,是知道还是蒙的。当实际输出出现的时候,都会有一定印象,写错的同学印象则会更深刻。而这个方法本身就是在实例举例演示的基础上,发挥我们测试工程师的特长,用用例设计的思维去发散所有情况,然后再利用预期输出和实际输出的对比加深印象。不但讲的效率可以提高,大家吸收的情况也确实好转。实际上还有额外的更大好处,就是在发散思维用例的时候,可以写出几乎各种各样很绝绝子的用例出来,通过这些全面的用例,我们之后的面试被为难住的几率就会降低,而我们甚至可以从这些用例的结果去猜测和验证出这些知识点的一些内部实现和底层逻辑,彻底把黑盒测试发挥到极致。

    我们测试工程师从前用黑盒测试来工作,现在用黑盒测试来学习,没想到居然有奇效!

    下面我举例说明一下:

    步骤1:  亮出一个知识点,说我们要讲这个。

    比如:xpath的通配符  *   , 这个知识点太简单了吧?大家都会,但是通过今天这个文章,你会发现原来可以扯出这么多东西呀~ 

    说*代表 任何元素节点,这是大家百度上能搜到的有且只有的一句话。大家是不是觉得看了这句话就算学会了这个知识点了?那你就错了。我接下来的问题,你在不亲自实践的情况下,几乎没有能完全百分百答对的可能。(当然有大佬可以答出来了。我这里先故作悬念,激将学生来认真听这个烂大街的知识点而已。)

<div id="wqrf">  <a>目标1</a>  <button>目标2</button></div><p>目标3</p>

    我们来做个有效等价类用例xpath:  //div[@id="wqrf"]/* 

    用这个find_elements(By.xpath,"") 的语法来获取,那结果是拿到了哪些元素?

    大家一定会说: 目标1 和 目标2  也就是那个a 和 button

    这个结果很简单,一目了然,大家都回答正确。

    然后我继续提问:那我们现在开始研究其他用例了,刚刚是 * 作为目标元素排在了xpath表达式的末尾,那我现在如果给移动到 中间呢?xml变成了这样:

<div id="wqrf">  <a>目标1</a>  <button>目标2</button>  <div>    <a>目标4</a>  </div></div><p>目标3</p>

xpath表达式为://div[@id="wqrf"]/*/a

此时的输出应该是哪些元素呢?

这时你的心里是不是有了答案了?写出来吧。是报错?还是其他答案?

然后演示的实际结果为:目标4  

这里我们可以试着给通配符* 下一个定义,对错我们之后验证:*可以作为目标节点,也可以作为中间节点。

但是问题随之而来,*作为中间节点,它能代表几层呢?刚刚有的同学写的答案是:目标1,目标2,目标4 。可能认为*是可以0层或1层的?但是很显然,答案是不能代表0层的。也证明了*是可以代表1层中间节点的。那*能不能代表多层节点呢?这个用例上是看不出来的。我们继续往下写用例:

<div id="wqrf">  <a>目标1</a>  <button>目标2</button>  <div>    <a>目标4</a>    <div>      <a>目标5</a>    </div>  </div></div><p>目标3</p>

还是刚刚的xpath: //div[@id="wqrf"]/*/a 

这里我们开始思考,如果*作为中间层,可以代表多层,那么答案是:目标4,目标5。如果*不能代表多层,那么答案就只有 :目标4

然后实践得知,只有目标4,那就给*再加一个定义:它只能代表一个层级。

那么我们用下面的用例来验证我们的这个想法是否正确:

把xpath改成: //div[@id="wqrf"]/*/*/a  ,注意,这里有俩个*

如果我们刚刚猜测是正确的,那么执行结果就是:目标5  如果真是这样,我们还可以得出一个新的结论,那就是 *可以再xpath中写多个。

运行后的结果很显然,就是:目标5,这证明我们的想法是正确的。大家思路深刻多了吧。

然后我们继续拓展用例,如果* 放在最前会怎样?

还是这个xml: 

<div id="wqrf">  <a>目标1</a>  <button>目标2</button>  <div>    <a>目标4</a>    <div>      <a>目标5</a>    </div>  </div></div><p>目标3</p>

   xpath 改成://*/a

大家猜测好自己的答案后,咱们实际执行。

执行结果为:目标1,目标4,目标5。

这个结果我们可以看出什么?*如果放在前面的时候,恰好还和相对路径// 合作。那么它们俩就几乎可以定位到这个页面的任何一个a标签。有的同学会问,那假如写到最外层的a,没有父级了,也会定位到么?比如下面这个xml:

<div id="wqrf">  <a>目标1</a></div><a>目标2</a>

在 xpath 中://*/a

的结果依然是:目标1 目标2  ,也就是所有a。那为何目标2也会上榜呢?

答案很简单,并不是我们之前的推断有误,只是在实际页面中的html源码 相对于这个例子xml来说,是一定有最外层的<html>和<body>的,所以a标签自然都是写在body中,那么就一定会获取到,学习就是这样,不能总被眼前的一个demo而局限住,要时刻关联到实际场景才行。

然后我们继续发散用例,那假如*放在开头,并且也同时是末尾呢?

也就是这样的特殊写法://*

这个情况下的结果是什么?如果我是面试官,我会要求你写出来真实的结果,不过我猜测大部分人都会丢分。xml如下:

注意这个xml 是一个非常完整的xml。然后面试官给你的selenium python代码如下:xpath就是 //*   (前面有会自动打开该页面的前置代码)

    大家可以写答案了,写完后,如果你写的不对,那么就要刹心,好好重学一遍xpath喽~ 

公布一下执行结果:

好,在这里我们可以看出,这种写法 //* 是获取页面内几乎所有标签元素(不包含Doctype哦)

那么我们之后如果再继续扩展用例,把* 放在过滤器的属性中呢?

也就是xpath :   //*[@*]  ,如果你按部就班的学xpath,那么这个[@]一定明白是一个过滤器而已。

这样的写法下,还是上面这个html,你还能完整正确的写出答案么?

执行结果如下:

//*[@*]  就是选取一切带有任意属性的元素。html有lang,meta有charset,link有rel和href, div有id,a有href。 

那我假如就是面试官,我现在再提高难度!

xml如下:

<div id="wqrf">  <a>目标1</a>  <button>目标2</button></div><p>目标3</p>

xpath为: '//div[@id="wqrf"]/button | //div[@id="wqrf"]/*' 

这是一个多语句的复合xpath,并且都有*,有*那就会增加很多额外的不确定因素了,题的难度就提高了。中间的 | 其实就是或的意思。那此时的结果应该是什么?一定要写正确的顺序哦。

我这里先给大家提出俩个问题,大家带着问题去写出预期答案吧。

1. 多个xpath语句的筛选结果中有重复的元素怎么办?是出俩次还是写一次?

2. 一个元素如果本身在html中是最上位置,但是在xpath复合语句中是只第二段的结果,那它在最终结果列表中的位置还是第一个么?

我公布下正确结果:目标1  a,目标2 button

从这个结果中,我们可以看出上面俩个问题的答案:

同时中标了俩段xpath的button,只出现了一次。  一个元素如果html中是最上面的,那么结果就一定是第一个,不会因为是第二段xpath导致它在最终结果的位置靠后。

知道了这点后,我们可以试着再去推断xpath的搜索原理和一些事实:

原理1:xpath的搜索就是在html 中 由上至下,一个元素一个元素的拿出来看是不是复合xpath表达式,符合就塞到最终结果列表中,所以最上面的元素中了的话就一定在结果中是第一个。

原理2:xpath的复合表达式(复合语句) 中,是没有进行拆开成俩段或多段,然后单独搜索,再把结果汇总到一起的。而是本身就支持这种复合写法,能直接判断一个元素是否符合 这个复合语句,并没有拆开。这样的话,从上到下的搜索只需一遍即可,而不是多遍。

事实3:这种复合表达式写法,并非selenium自创,而是xpath本身就支持的。如果是自创,那么底层原理一定是拆开单独筛查然后汇总。

发挥4:如果我让你现在重新封装一套自动化框架,你就可以以此为新亮点,设计出各种更加符合人为习惯的超复合xpath等语句,甚至多种定位元素方式的混合表达式,然后底层是拆开筛选,汇总结果。虽然意义不大,但是从如此简单的一个 通配符* ,就能扯出这么多东西来看,整个自动化框架能发挥的空间简直是太大了,祝你好运。

拓展5:之前举的用例例子都是有效的,那无效的呢?或者我们也不知道是否可以成功的例子呢?比如 //***** 这种,运行结果会怎样呢?是报错么?如果报错,请猜测报错语句是什么?通过这些用例,我们又能得到什么新的思考呢?

好了,就举例到这里了,事实上,在我的selenium课程中,每一个知识点都比今天讲的要细致的多,可以说这样学完一遍的学员,那实力已经不是今非昔比可以形容的了,不谦虚点说:难逢敌手。对我来说呢,这也算是把老东西深耕和普及一次吧,希望大家轻喷。

我的号:qingwanjianhua

猜你喜欢

转载自blog.csdn.net/qq_22795513/article/details/128810072