成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

【全棧React】第25天: 使用Enzyme做更好的測(cè)試

baukh789 / 1006人閱讀

摘要:昨天我們使用了庫(kù)來(lái)編寫我們對(duì)組件的第一個(gè)測(cè)試。是由團(tuán)隊(duì)發(fā)布和維護(hù)的測(cè)試實(shí)用程序庫(kù)它提供了一個(gè)更好的高級(jí)的來(lái)處理測(cè)試中的組件。我們將使用導(dǎo)出的函數(shù)來(lái)裝載我們的組件。相反我們必須使用提供的方法。

本文轉(zhuǎn)載自:眾成翻譯
譯者:iOSDevLog
鏈接:http://www.zcfy.cc/article/3806
原文:https://www.fullstackreact.com/30-days-of-react/day-25/

今天,我們將看看一個(gè)由Airbnb所維護(hù)的開源庫(kù),名為Enzyme,使得測(cè)試變得簡(jiǎn)單易用。

昨天我們使用了react-addons-test-utils 庫(kù)來(lái)編寫我們對(duì)Timeline 組件的第一個(gè)測(cè)試。但是, 此庫(kù)是相當(dāng)?shù)图?jí)的, 使用起來(lái)可能有點(diǎn)麻煩。Enzyme是由 AirBnb 團(tuán)隊(duì)發(fā)布和維護(hù)的測(cè)試實(shí)用程序庫(kù), 它提供了一個(gè)更好的、高級(jí)的 API 來(lái)處理測(cè)試中的React組件。

我們?cè)跍y(cè)試我們的 組件:

使用Enzyme

我們將使用Enzyme, 使這些測(cè)試更容易寫和更可讀。

昨天, 我們寫了我們的第一個(gè)測(cè)試如下:

import React from "react";
import TestUtils from "react-addons-test-utils";

import Timeline from "../Timeline";

describe("Timeline", () => {

  it("wraps content in a div with .notificationsFrame class", () => {
    const wrapper = TestUtils.renderIntoDocument();
    TestUtils
      .findRenderedDOMComponentWithClass(wrapper, "notificationsFrame");
  });

})

雖然這是可行的, 但它不是世界上最容易閱讀的測(cè)試。當(dāng)用Enzyme我們重寫它時(shí)讓我們看看這個(gè)測(cè)試的樣子。

我們可以只測(cè)試組件的輸出, 而不是用Enzyme來(lái)測(cè)試完整的組件樹。將不渲染任何組件的子級(jí)。這稱為 渲染。

Enzyme使淺渲染超容易。我們將使用Enzyme導(dǎo)出的shallow 函數(shù)來(lái)裝載我們的組件。

讓我們更新src/components/Timeline/__tests__/Timeline-test.js 文件, 包括從 enzyme導(dǎo)入shallow 函數(shù):

import React from "react";
import { shallow } from "enzyme";

describe("Timeline", () => {
  it("wraps content in a div with .notificationsFrame class", () => {
    // our tests
  });
})

react-addons-test-utils也支持淺渲染。事實(shí)上, Enzyme素只是包裝這個(gè)函數(shù)。雖然昨天我們沒有使用淺渲染, 但如果我們使用它看起來(lái)像這樣:

> const renderer = ReactTestUtils.createRenderer();
> renderer.render()
> const result = renderer.getRenderOutput(); 
>

現(xiàn)在, 為了渲染我們的組件, 我們可以使用shallow 方法并將結(jié)果存儲(chǔ)在一個(gè)變量中。然后, 我們將為在其虛擬 dom 中渲染的不同的React元素 (HTML 或子組件) 查詢 渲染的組件。

整個(gè)斷言包括兩行:

import React from "react";
import { shallow, mount } from "enzyme";

import Timeline from "../Timeline";

describe("Timeline", () => {
  let wrapper;

  it("wraps content in a div with .notificationsFrame class", () => {
    wrapper = shallow();
    expect(wrapper.find(".notificationsFrame").length).toEqual(1);
  });

  it("has a title of Timeline", () => {
    wrapper = mount()
    expect(wrapper.find(".title").text()).toBe("Timeline")
  })

  describe("search button", () => {
    let search;
    beforeEach(() => wrapper = mount())
    beforeEach(() => search = wrapper.find("input.searchInput"))

    it("starts out hidden", () => {  
      expect(search.hasClass("active")).toBeFalsy()
    })
    it("becomes visible after being clicked on", () => {
      const icon = wrapper.find(".searchIcon")
      icon.simulate("click")
      expect(search.hasClass("active")).toBeTruthy()
    })
  })

  describe("status updates", () => {
    it("has 4 status updates at minimum", () => {
      wrapper = shallow()
      expect(
        wrapper.find("ActivityItem").length
      ).toBeGreaterThan(3)
    })
  })

})

我們可以使用yarn test命令 (或 npm test 命令) 一樣的方式運(yùn)行測(cè)試:

yarn test

我們的測(cè)試通過, 并且更易于閱讀和維護(hù)。

讓我們繼續(xù)寫斷言, 從我們昨天開始的假設(shè)列表中抽取。我們將首先構(gòu)建我們的測(cè)試套件的其余部分, 寫出我們的describeit 塊。我們將填寫的規(guī)格與斷言后:

import React from "react";
import { shallow } from "enzyme";

import Timeline from "../Timeline";

describe("Timeline", () => {
  let wrapper;

  it("wraps content in a div with .notificationsFrame class", () => {
    wrapper = shallow();
    expect(wrapper.find(".notificationsFrame").length).toEqual(1);
  });

  it("has a title of Timeline")

  describe("search button", () => {
    it("starts out hidden")
    it("becomes visible after being clicked on")
  })

  describe("status updates", () => {
    it("has 4 status updates at minimum")
  })

})

如果我們遵循測(cè)試驅(qū)動(dòng)開發(fā) (簡(jiǎn)稱 TDD), 我們將首先編寫這些假設(shè), 然后構(gòu)建組件以通過這些測(cè)試。

讓我們填寫這些測(cè)試, 以便它們通過我們現(xiàn)有的Timeline 組件。

我們的標(biāo)題測(cè)試比較簡(jiǎn)單。我們將查找標(biāo)題元素并確認(rèn)標(biāo)題為Timeline。

我們希望標(biāo)題可以在 .title類下使用。因此, 要在規(guī)范中使用 .title 類, 我們只需使用Enzyme所暴露的find 函數(shù)即可獲取組件。

因?yàn)槲覀兊?b>Header組件是 Timeline 組件的子組件, 所以不能使用shallow() 方法。相反, 我們必須使用Enzyme提供的 mount() 方法。

Shallow? Mount?

shallow() 渲染函數(shù)只渲染我們專門測(cè)試的組件, 它不會(huì)渲染子元素。相反, 我們將不得不mount() 組件, 因?yàn)樽咏M件Header 不可用的 jsdom, 否則。

我們將在本文的末尾看到更多的Enzyme函數(shù)。

現(xiàn)在讓我們填寫標(biāo)題描述:

import React from "react";
import { shallow, mount } from "enzyme";

import Timeline from "../Timeline";

describe("Timeline", () => {
  let wrapper;

  it("wraps content in a div with .notificationsFrame class", () => {
    wrapper = shallow();
    expect(wrapper.find(".notificationsFrame").length).toEqual(1);
  });

  it("has a title of Timeline", () => {
    wrapper = mount() // notice the `mount`
    expect(wrapper.find(".title").text()).toBe("Timeline")
  })
})

運(yùn)行我們的測(cè)試, 我們將看到這兩個(gè)期望通過:

接下來(lái), 讓我們更新我們的搜索按鈕測(cè)試。我們?cè)谶@里有兩個(gè)測(cè)試, 其中一個(gè)要求我們測(cè)試一個(gè)交互。Enzyme為處理相互作用提供了一個(gè)非常干凈的界面。讓我們來(lái)看看如何根據(jù)搜索圖標(biāo)編寫測(cè)試。

同樣, 由于我們?cè)跁r(shí)間軸中對(duì)子元素進(jìn)行測(cè)試, 因此我們必須mount() 元素。因?yàn)槲覀円谝粋€(gè)嵌套的describe()塊中編寫兩個(gè)測(cè)試, 所以我們可以在幫助器之前編寫一個(gè)新的 mount() 來(lái)為每個(gè)測(cè)試重新創(chuàng)建, 這樣它們是純的。

此外, 我們還將使用 input.searchInput 元素進(jìn)行兩個(gè)測(cè)試, 因此, 讓我們?cè)谇懊娴膸椭髦袨樵撛鼐帉?b>.find() 。

describe("Timeline", () => {
  let wrapper;
  // ...
  describe("search button", () => {
    let search;
    beforeEach(() => wrapper = mount())
    beforeEach(() => search = wrapper.find("input.searchInput"))
    // ...
  })
})

若要測(cè)試是否隱藏了搜索輸入, 我們只需要知道是否應(yīng)用了active 類。Enzyme為我們提供了一種使用 hasClass() 方法檢測(cè)組件是否有類的方法。讓我們填寫第一個(gè)測(cè)試, 期望搜索輸入沒有活動(dòng)類:

describe("Timeline", () => {
  let wrapper;
  // ...
  describe("search button", () => {
    let search;
    beforeEach(() => wrapper = mount())
    beforeEach(() => search = wrapper.find("input.searchInput"))

    it("starts out hidden", () => {  
      expect(search.hasClass("active")).toBeFalsy()
    })
    it("becomes visible after being clicked on")
    // ...
  })
})

關(guān)于第二個(gè)測(cè)試的棘手部分是, 我們需要點(diǎn)擊圖標(biāo)元素。在我們看如何做到這一點(diǎn)之前, 讓我們先找到它。我們可以在包裝上的目標(biāo)通過它的 .searchIcon 類定位到它。

it("becomes visible after being clicked on", () => {
  const icon = wrapper.find(".searchIcon")
})

現(xiàn)在, 我們有了圖標(biāo), 我們想模擬一個(gè)點(diǎn)擊元素。回想一下, onClick() 方法實(shí)際上只是瀏覽器事件的門面。即, 單擊一個(gè)元素只是一個(gè)通過組件冒泡的事件。而不是控制鼠標(biāo)或調(diào)用元素上的click , 我們將模擬發(fā)生在它上的事件。對(duì)我們來(lái)說, 這將是click 事件。

我們將在icon 上使用simulate() 方法來(lái)創(chuàng)建此事件:

it("becomes visible after being clicked on", () => {
  const icon = wrapper.find(".searchIcon")
  icon.simulate("click")
})

現(xiàn)在我們可以設(shè)定一個(gè)search 組件具有active 類的期望。

it("becomes visible after being clicked on", () => {
  const icon = wrapper.find(".searchIcon")
  icon.simulate("click")
  expect(search.hasClass("active")).toBeTruthy()
})

我們對(duì)Timeline 組件的最后期望是至少有四狀態(tài)更新。當(dāng)我們將這些元素放置在Timeline 組件上時(shí), 我們可以 "淺" 渲染組件。此外, 由于每個(gè)元素都是自定義組件, 因此我們可以搜索"ActivityItem"類型的特定組件的列表。

describe("status updates", () => {
  it("has 4 status updates at minimum", () => {
    wrapper = shallow()
    // ... 
  })
})

現(xiàn)在, 我們可以測(cè)試ActivityItem 組件列表的長(zhǎng)度。我們將設(shè)定我們的期望, 如果長(zhǎng)度至少是4的名單。

describe("status updates", () => {
  it("has 4 status updates at minimum", () => {
    wrapper = shallow()
    expect(
      wrapper.find("ActivityItem").length
    ).toBeGreaterThan(3)
  })
})

我們現(xiàn)在的整個(gè)測(cè)試套件如下所示:

import React from "react";
import { shallow, mount } from "enzyme";

import Timeline from "../Timeline";

describe("Timeline", () => {
  let wrapper;

  it("wraps content in a div with .notificationsFrame class", () => {
    wrapper = shallow();
    expect(wrapper.find(".notificationsFrame").length).toEqual(1);
  });

  it("has a title of Timeline", () => {
    wrapper = mount()
    expect(wrapper.find(".title").text()).toBe("Timeline")
  })

  describe("search button", () => {
    let search;
    beforeEach(() => wrapper = mount())
    beforeEach(() => search = wrapper.find("input.searchInput"))

    it("starts out hidden", () => {  
      expect(search.hasClass("active")).toBeFalsy()
    })
    it("becomes visible after being clicked on", () => {
      const icon = wrapper.find(".searchIcon")
      icon.simulate("click")
      expect(search.hasClass("active")).toBeTruthy()
    })
  })

  describe("status updates", () => {
    it("has 4 status updates at minimum", () => {
      wrapper = shallow()
      expect(
        wrapper.find("ActivityItem").length
      ).toBeGreaterThan(3)
    })
  })

})
[](#whats-the-deal-with-find)find()處理什么?

在我們結(jié)束今天之前, 我們應(yīng)該看看一個(gè)Enzyme"渲染的界面 (在我們的測(cè)試中, wrapper 的對(duì)象)。Enzyme文檔 太棒了, 所以我們要保持這個(gè)簡(jiǎn)短。

基本上, 當(dāng)我們使用find() 函數(shù)時(shí), 我們會(huì)將它傳遞給一個(gè)選擇器, 它將返回一個(gè)ShallowWrapper 實(shí)例來(lái)包裝找到的節(jié)點(diǎn)。find() 函數(shù)可以取字符串、函數(shù)或?qū)ο蟆?/p>

當(dāng)我們將字符串傳遞給find()函數(shù)時(shí), 我們可以傳遞 CSS 選擇器或組件的 _顯示名稱_。例如:

wrapper.find("div.link");
wrapper.find("Link")

我們還可以將它傳遞給組件構(gòu)造函數(shù), 例如:

import { Link } from "react-router";
// ...
wrapper.find(Link)

最后, 我們還可以傳遞對(duì)象屬性選擇器對(duì)象, 它通過鍵和值來(lái)選擇元素。例如:

wrapper.find({to: "/login"});

返回值是一個(gè) ShallowWrapper, 它是一種ShallowWrapper類型 (我們可以渲染包裝和淺包裝)。這些 Wrapper 實(shí)例有一組功能, 我們可以使用這些函數(shù)來(lái)針對(duì)不同的子組件, 查看 propsstate,的方法, 以及渲染的組件的其他屬性, 如html()text()。更甚的是, 我們可以把這些調(diào)用串在一起。

組件為例。如果我們想找到基于所有可用鏈接的鏈接類的 HTML, 我們可以編寫這樣的測(cè)試:

// ...
it("displays a link tag with the Login text", () => {
  link = wrapper
        .find("Link")
        .find({to: "/login"})

  expect(link.html())
    .toBe("Login")
});

哦!今天有很多新的信息, 但是看看我們是如何快速地用Enzyme來(lái)編寫后續(xù)測(cè)試的。閱讀的速度要快得多, 而且更容易辨別實(shí)際發(fā)生的事情。

明天, 我們將繼續(xù)我們的測(cè)試旅程和通過集成測(cè)試測(cè)試我們的應(yīng)用。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/87161.html

相關(guān)文章

  • 全棧ReactReact 30教程索引

    摘要:今天我們將討論創(chuàng)建組件的最終方案,即無(wú)狀態(tài)函數(shù)的純組件。今天我們正在研究一種處理提出的復(fù)雜數(shù)據(jù)的方法,稱為體系結(jié)構(gòu)。第天部署介紹今天,我們將探討部署我們的應(yīng)用所涉及的不同部分,以便外界可以使用我們的應(yīng)用。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3758原文:https://www.fullstackreact.com/3...

    appetizerio 評(píng)論0 收藏0
  • 全棧React22: 測(cè)試簡(jiǎn)介

    摘要:我們將討論三種不同的軟件測(cè)試范例單元測(cè)試功能測(cè)試和集成測(cè)試。在中單元測(cè)試通常不需要瀏覽器可以快速運(yùn)行不需要寫入斷言本身通常是簡(jiǎn)單而簡(jiǎn)潔的。集成測(cè)試最后我們將研究的最后一種測(cè)試是集成測(cè)試。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3809原文:https://www.fullstackreact.com/30-days-of...

    qc1iu 評(píng)論0 收藏0
  • 全棧React23: 實(shí)現(xiàn)測(cè)試

    摘要:包包含由團(tuán)隊(duì)提供的測(cè)試實(shí)用程序。將在一個(gè)名為的目錄中自動(dòng)查找整個(gè)樹中的測(cè)試文件是的帶有下劃線。讓我們?yōu)闀r(shí)間軸組件創(chuàng)建第一個(gè)測(cè)試。其中之一是命令?,F(xiàn)在我們已經(jīng)編寫了第一個(gè)測(cè)試并確認(rèn)了我們的設(shè)置我們將在明天開始測(cè)試我們的時(shí)間軸組件。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3807原文:https://www.fullstac...

    airborne007 評(píng)論0 收藏0
  • 全棧React24: 測(cè)試應(yīng)用

    摘要:我們的第一個(gè)假設(shè)是非常簡(jiǎn)單的測(cè)試。我們正在測(cè)試以確保元素被包裝在類中。在我們編寫的每個(gè)測(cè)試中我們都需要將應(yīng)用呈現(xiàn)在工作測(cè)試文檔中。作為提醒我們可以使用命令或命令來(lái)運(yùn)行測(cè)試。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3804原文:https://www.fullstackreact.com/30-days-of-react/...

    ziwenxie 評(píng)論0 收藏0
  • 全棧React11: 純組件

    摘要:今天我們將討論創(chuàng)建組件的最終方案,即無(wú)狀態(tài)函數(shù)的純組件。為了獲得更多的性能和簡(jiǎn)單性,同樣允許我們使用正常的函數(shù)創(chuàng)建純粹的,無(wú)狀態(tài)的組件。在中,功能組件被稱為一個(gè)參數(shù)的類似于構(gòu)造函數(shù)類,它們是它所調(diào)用的,以及組件樹的當(dāng)前。 本文轉(zhuǎn)載自:眾成翻譯譯者:iOSDevLog鏈接:http://www.zcfy.cc/article/3819原文:https://www.fullstackrea...

    Cciradih 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

baukh789

|高級(jí)講師

TA的文章

閱讀更多
最新活動(dòng)
閱讀需要支付1元查看
<