Cypress 的条件测试
條件測試用下列的編程范式可以清晰表示出來:
If X, then Y, else Z
如今,現代 JavaScript 應用程序是高度動態和可變的。 它們的狀態和 DOM 在一段時間內不斷變化。
條件測試的問題在于它只能在狀態穩定后才能使用。 在現代應用程序中,知道狀態何時穩定通常是不可能的。
對人類而言——如果從現在起 10 毫秒或 100 毫秒發生變化,我們甚至可能不會注意到這種變化并假設狀態總是相同的。
對于機器人來說——即使是 10 毫秒也代表著數十億+ 的時鐘周期。 時間尺度的差異令人難以置信。
人也有直覺。 如果您單擊一個按鈕并看到一個加載微調器,您將假定狀態處于不斷變化中,并會自動等待它完成。
機器人沒有直覺——它會完全按照編程的方式去做。
為了說明這一點,讓我們舉一個簡單的例子來嘗試有條件地測試不穩定狀態。
The DOM is unstable
下面是我們的應用代碼,在隨機的時間間隔內,將新創建的 button 元素添加 active CSS 類。
// your app code// random amount of time const random = Math.random() * 100// create a <button> element const btn = document.createElement('button')// attach it to the body document.body.appendChild(btn)setTimeout(() => {// add the class active after an indeterminate amount of timebtn.setAttribute('class', 'active') }, random)看下面的測試代碼:
// your cypress test code it('does something different based on the class of the button', () => {// RERUN THIS TEST OVER AND OVER AGAIN// AND IT WILL SOMETIMES BE TRUE, AND// SOMETIMES BE FALSE.cy.get('button').then(($btn) => {if ($btn.hasClass('active')) {// do something if it's active} else {// do something else}}) })我們會隨機進入 if 和 else 分支。
Server side rendering
如果 web 應用的源代碼在服務器端渲染,并且不存在隨后通過 JavaScript 異步修改 DOM 的可能性,這種應用是極佳的進行條件測試的備選。
load 事件發生之后,DOM 不會再發生變化,這意味著其已經達到了一個穩定的狀態(a stable state of truth).
Client side rendering
對于現代 Web 應用來說,當 load 事件發生時,屏幕上通常什么都還沒有渲染。JavaScript 在此時會動態加載內容,并執行渲染。
這種情況下,不可能依靠 DOM 進行條件測試,除非我們有 100% 的把握,找到某個時間點,該時間點到達時,所有的異步渲染都已經結束,并且也不存在 pending network requests, setTimeouts, intervals, postMessage, or async/await code. 所有的 web 開發者都明白這是一件不可能的事情。
即使我們的應用里使用了 Zone.js, 也沒辦法捕捉到所有的異步編程點。
A/B campaign
使用 url 參數,顯式告訴服務器我們期望返回的數據內容:
// tell your back end server which campaign you want sent // so you can deterministically know what it is ahead of time cy.visit('https://app.com?campaign=A')...cy.visit('https://app.com?campaign=B')...cy.visit('https://app.com?campaign=C')It is crucial that you understand how your application works else you will write flaky tests.
看下面這段代碼:
// app code $('button').on('click', (e) => {// do something synchronously randomlyif (Math.random() < 0.5) {// append an input$('<input />').appendTo($('body'))} else {// or append a textarea$('<textarea />').appendTo($('body'))} })應用程序會隨機的在 body 里插入 input 或者 textarea.
我們可以使用如下代碼進行條件測試:
// click the button causing the new // elements to appear cy.get('button').click() cy.get('body').then(($body) => {// synchronously query from body// to find which element was createdif ($body.find('input').length) {// input was found, do something else herereturn 'input'}// else assume it was textareareturn 'textarea'}).then((selector) => {// selector is a string that represents// the selector we could use to find itcy.get(selector).type(`found the element by selector ${selector}`)})在應用達到一個穩定的狀態前,我們應采取措施,阻止 Cypress 進一步執行命令。
總結
以上是生活随笔為你收集整理的Cypress 的条件测试的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: React 精要面试题讲解(一) 单向数
- 下一篇: 论文阅读:Siam-RPN