一甲易学 發表於 2021-3-26 17:44:00

前端开发:基于cypress的自动化实践

<p>作为一个伪开发,在一个平台项目中负责前端的开发工作,开发框架为vue,本文我会站在前端开发的角度介绍,我是如何使用cypress的。</p>
<ul class="contains-task-list">
<li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"><label> 如何在vue中使用cypress</label></li>
<li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"><label> 如何运行cypress</label></li>
<li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"><label> 如何编写测试用例</label></li>
<li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"><label> 如何解决测试数据的问题</label></li>
<li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"><label> 遇到的元素定位的问题</label></li>
<li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"><label> 如何看待cypress</label></li>
<li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"><label> cypress是否为最佳工具</label></li>
<li class="task-list-item"><input class="task-list-item-checkbox" checked="" disabled="" type="checkbox"><label> 测试怎么办?</label></li>
</ul>
<h2 id="如何在vue中使用cypress">如何在vue中使用cypress</h2>
<p>vue提供了<code>vue-cli</code> 可以快速的创建vue项目。</p>
<pre><code class="language-shell">vue create hello-world
</code></pre>
<p>在选择安装项里面选择: <code>E2E testing</code> -&gt; <code>cypress</code>。</p>
<p><img src="https://img2020.cnblogs.com/blog/311516/202103/311516-20210326174015969-978890058.png" alt="" loading="lazy"></p>
<h2 id="如何运行测试">如何运行测试</h2>
<ol>
<li>通过命令启动</li>
</ol>
<pre><code class="language-shell">&gt; npm run test:e2e
</code></pre>
<ol>
<li>开启cyprss 管理窗口</li>
</ol>
<p><img src="https://img2020.cnblogs.com/blog/311516/202103/311516-20210326174045022-883622990.png" alt="" loading="lazy"></p>
<ol start="2">
<li>点击<code>Run all specs</code> 或 某个测试文件运行</li>
</ol>
<p><img src="https://img2020.cnblogs.com/blog/311516/202103/311516-20210326174108214-1523264532.png" alt="" loading="lazy"></p>
<p>这里以<code>项目管理</code> 模块为例,运行5条用例只需要14s,速度还是非常快的。</p>
<h2 id="如何编写测试用例">如何编写测试用例</h2>
<p>站在前端开发的角度上编写UI自动化用例,总体感受还是非常方便的!</p>
<p>首先,为所有要操作的元素设置统一的属性。</p>
<pre><code class="language-html">&lt;el-button cy-data="create-project" type="primary" @click="showCreate"&gt;创建&lt;/el-button&gt;
...
&lt;el-button cy-data="edit-project" type="text" size="small" @click="showEdit(scope.row)"&gt;编辑&lt;/el-button&gt;
&lt;el-button cy-data="delete-project" type="text" size="small" @click="deleteProject(scope.row)"&gt;删除&lt;/el-button&gt;
...
</code></pre>
<p>不建议占用HTML提供的的 <code>id</code>、<code>name</code>、<code>class</code>... 这些属性,他们一般都会有指定的用途,比如,<code>class</code> 是用来引用css样式的。 那么通过<code>cy-data=xxxx</code>即可以避免冲突,又更加统一和规范。</p>
<p>接下来,就是编写 cypress 自动化代码了</p>
<pre><code class="language-js">describe('项目管理', () =&gt; {
it('添加项目', () =&gt; {
    cy.visit('/#/project')
    cy.get('', { timeout: 3000 }).click()
    cy.wait(1000)
    cy.get('', { timeout: 3000 }).type('项目名称')
    cy.get('', { timeout: 3000 }).type('项目备注信息')
    cy.get('', { timeout: 3000 }).click()// 保存项目
});
// ...
})
</code></pre>
<h2 id="如何解决测试数据的问题">如何解决测试数据的问题</h2>
<p>我们编写自动化测试用例,不管是接口还是UI都会面临测试数据的问题。比如,我要测试登录,得先去创建一个用户数据,我要测试搜索,先去创建一批可以搜索的数据。</p>
<p>为此,我们不得不在自动化里面 使用<code>setUp/treaDown</code>这些fixture去写大量的前置或后置动作,来完成这些准备工作。站在测试的角度,这无疑让我们的测试用例变得复杂,然后,也很容易因为测试数据造成自动化用例的失败。</p>
<p>那么,站在前端开发是如何解决的?在此之前我们要先了解一下开发过程:</p>
<p>在项目开发过程中。前端为了更顺利的完成开发工作,不能等到后端开发好了接口,再手写前端功能,所以,会和后端定义好接口之后,通过mock来模拟接口数据,--<strong>面向mock开发</strong>。</p>
<p>那么在面向mock开发的过程中,避免不了,前后端需要调整接口参数的情况,比如,前端需要增加一个字段,或后端说需要把数据结构调整一下。</p>
<p>我们使用YAPI平台进行接口的定义,他可以根据定义随机的生成mock数据,数据的每个字段都可以随机生成,例如,<code>name</code>,<code>email</code>, <code>datatime</code> 等。</p>
<p><img src="https://img2020.cnblogs.com/blog/311516/202103/311516-20210326174150797-788338898.png" alt="" loading="lazy"></p>
<p>你可以直接通过下面的链接来访问mock接口:</p>
<p>https://yapi.baidu.com/mock/40650/api/v1/projects/list</p>
<p>如何vue项目当中配置不同的环境?你需要去学习vue开发...</p>
<h2 id="遇到的元素定位问题">遇到的元素定位问题</h2>
<p>然而,为每个元素添加定位方式,有时并不是我们想象的那么简单。</p>
<p>如果你是使用过前端UI(例如 element-ui)库就会发现,并不是所有的页面元素都是通过HTML纯手写的。 例如,下面的弹窗。</p>
<p><img src="https://img2020.cnblogs.com/blog/311516/202103/311516-20210326174213901-1856486646.png" alt="" loading="lazy"></p>
<p>通过 element-UI的实现方式是这样子的。</p>
<pre><code class="language-js">&lt;template&gt;
&lt;el-button type="text" @click="open"&gt;点击打开 Message Box&lt;/el-button&gt;
&lt;/template&gt;

&lt;script&gt;
export default {
    methods: {
      open() {
      this.$confirm('此操作将永久删除该文件, 是否继续?', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
      }).then(() =&gt; {
          this.$message({ type: 'success',message: '删除成功!' });
      }).catch(() =&gt; {
          this.$message({ type: 'info', message: '已取消删除' });         
      });
      }
    }
}
&lt;/script&gt;
</code></pre>
<p>弹窗完全通过 element-UI 渲染,我们无处给 <code>确定</code>、<code>取消</code> 等按钮加上定位专用属性。 这个时候,前端开发就没什么优势了,必须老老实实的去前端页面上定位元素,写复杂的css定位。</p>
<p>然而,就算我自定义了定位,有时候元素也不是唯一的。例如</p>
<p><img src="https://img2020.cnblogs.com/blog/311516/202103/311516-20210326174236734-1238286442.png" alt="" loading="lazy"></p>
<p>对于上面的列表,通过<code>自定义定位</code>得到的是一组元素。然而,如果只是一组元素的问题就就没必要单独拿出来说了,正如上图,列表中看到的是 4 个元素,通过定位方式得到的是8个元素,前4个是隐藏的,这和使用的 element-UI 库有关,因为数据是YAPI随机生成的,不能写死对第5个显示元素进行操作。 cypress 提供的 <code>force</code> 非常有用,他会强制对隐藏的元素进行操作。</p>
<pre><code class="language-js">cy.get('', { timeout: 3000 }).first().click({ force: true })
</code></pre>
<h2 id="如何看待cypress">如何看待cypress</h2>
<p><strong>前端开发视角</strong></p>
<p>作为一名前端开发,客观的说,使用cypress的过程并没有遇到太多阻力。我来总结一下。</p>
<ol>
<li>因为使用了yapi,不需要考虑测试数据的准备。</li>
<li>不需要写依赖步骤,主要是目前的业务功能也没有太长的操作过程。</li>
<li>大部分情况下可以自定义元素属性,在定位上不需要花费过多的时间,也不需要写太长的定位。</li>
<li>测试运行速度可以接受,28条用例运行耗时80秒左右。</li>
</ol>
<p><strong>测试视角</strong></p>
<p>作为一名自动化测试,如果让我使用cypress。</p>
<ol>
<li>为了验证数据的正确性,我不能要求开发使用 yapi 假数据,所以,还是要自己准备数据。</li>
<li>根据业务的情况,必须要的前置/后置动作不可避免。</li>
<li>虽然,说服开发统一自定义元素有点难,对来我说并不是不可办到!</li>
<li>cypress 做UI自动化确实比selenium要快一些,但是他相比selenium,不支持更多的浏览器,不支持Grid远程调用,甚至不能根据自己的熟练度选择语言。所以,cypress 优势并没有压倒性优势,具体还是要看需求。</li>
</ol>
<h2 id="cypress是否为最佳工具">cypress是否为最佳工具</h2>
<p>cypress是否为所有UI自动化的最佳工具?</p>
<p>在面向前端的开发框架<code>Vue/React</code>中 确实很好的整合cypress,使我们的使用更加方便。</p>
<p>在我接触到的偏后端的django Web框架中就很好的整合了Selenium,同样可以达到类似的效果。 我之前看过一本《Test-Driven Development with Python》 ,书中就很好的将基于Selenium的UI测试与Django开发很好的结合起来了。</p>
<p>所以,结论是结合你的开发框架去选择合适的 E2E 测试工具。</p>
<h2 id="测试怎么办">测试怎么办?</h2>
<p>一直以来,我们都天然的认为UI自动化测试就应该是测试来做的,并以能做UI自动化测试为高级目标!但从我上面的实践中,我们会发现其实开发来做UI自动化优势很明显。那么测试怎么办?我们只能老老实实的回去测功能了吗?当然不是。</p>
<ol>
<li>
<p>并不是每个开发都懂得编写UI自动化测试,虽然,这对他们来并不是特别难,我们完全在这方面成为“教练”,教开发如何编写UI自动化测试,如何设计更全面的测试用例。</p>
</li>
<li>
<p>并不是每个团队的开发都有时间编写UI自动化测试,也可能是他们不愿意写,那么我们为何不加入他们?以我前面介绍的方式,深度地参与到项目的自动化测试编写中。而不是现在这样,将项目开发和自动化测试完全割裂开分别进行。</p>
</li>
</ol>
<p>春节期间重读了《google测试之道》,有了新的感受,在测试开发能力足够的前提下,当团队的目标是提高产品的保证质量时,自动化测试到底由谁来做的问题变得不那么重要了。</p><br><br>
来源:https://www.cnblogs.com/fnng/p/14583259.html
頁: [1]
查看完整版本: 前端开发:基于cypress的自动化实践