?{????it..." />
    1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Jest 單元測試快速上手指南

        共 6883字,需瀏覽 14分鐘

         ·

        2020-09-08 08:03

        原文鏈接: https://github.com/yinxin630/blog/issues/38

        Jest[1] 是一款簡單, 容易上手且功能十分強大的測試框架

        安裝

        yarn add -D jest

        使用

        創(chuàng)建 test 目錄, 添加 plus.spec.js 文件

        describe('example',?()?=>?{
        ????it('should?equal?2',?()?=>?{
        ????????expect(1?+?1).toBe(2);
        ????});
        });

        執(zhí)行 yarn jest 或者 yarn jest test/plus.spec.js 運行測試用例

        成功結果

        失敗結果

        輸出測試覆蓋率

        在根目錄創(chuàng)建 jest.config.js 配置文件

        module.exports?=?{
        ????collectCoverage:?true,
        };

        創(chuàng)建 plus.js 模塊

        module.exports?=?function?plus(a,?b)?{
        ????return?a?+?b;
        }

        修改測試用例使用模塊

        const?plus?=?require('../plus');

        describe('example',?()?=>?{
        ????it('should?equal?2',?()?=>?{
        ????????expect(plus(1,?1)).toBe(2);
        ????});
        });

        再次執(zhí)行測試, 輸出覆蓋率如下


        在瀏覽器中打開 coverage/lcov-report/index.html 可以瀏覽覆蓋率結果頁面


        忽略部分文件或者代碼行的覆蓋率

        修改 plus.ts 模塊, 添加更多分支

        export?default?function?plus(a:?number,?b:?number)?{
        ????if?(a?+?b?>?100)?{
        ????????return?0;
        ????}?else?if?(a?+?b?0)?{
        ????????return?0;
        ????}?else?{
        ????????return?a?+?b;
        ????}
        }

        重新執(zhí)行測試, 覆蓋率輸出結果


        你可以完善測試用例, 或者可能有些文件(譬如 config)和代碼分支并不需要測試, 可以將其在測試覆蓋率結果中排除, 參考如下配置

        1. 忽略目錄下所有文件

        jest.config.js 中添加

        collectCoverageFrom:?[
        ????'**/*.{ts,tsx}',
        ????'!**/node_modules/**',
        ????'!**/[directory?path]/**',
        ],

        ! 開頭的表示忽略與其匹配的文件

        1. 忽略單個文件

        在該文件頂部添加 /* istanbul ignore file */

        1. 忽略一個函數(shù), 一塊分支邏輯或者一行代碼

        在該函數(shù), 分支邏輯或者代碼行的上一行添加 /* istanbul ignore next */

        支持 Typescript

        執(zhí)行 yarn add -D typescript ts-jest @types/jest 安裝 typescript 和聲明 并在 jest.config.js 中添加 preset: 'ts-jest'

        plus.js 重命名為 plus.ts

        export?default?function?plus(a:?number,?b:?number)?{
        ????return?a?+?b;
        }

        同樣的, 將 plus.spec.js 重命名為 plus.spec.ts

        import?plus?from?'../plus'

        describe('example',?()?=>?{
        ????it('should?equal?2',?()?=>?{
        ????????expect(plus(1,?1)).toBe(2);
        ????});
        });

        執(zhí)行測試, 結果和之前一致

        執(zhí)行單測時不校驗 ts 類型

        有時你可能會希望不校驗 ts 類型, 僅執(zhí)行代碼測試, 比如需要在 CI 中將類型校驗和單元測試分為兩個任務 在 jest.config.js 中添加如下內容

        globals:?{
        ????'ts-jest':?{
        ????????isolatedModules:?true,
        ????},
        }

        測試 React 組件

        安裝 react 依賴 yarn add react react-dom 和聲明 yarn add -D @types/react安裝 react 測試庫 yarn add -D @testing-library/react @testing-library/jest-dom

        添加 typescript 配置文件 tsconfig.json

        {
        ????"compilerOptions":?{
        ????????"target":?"es2018",
        ????????"strict":?true,
        ????????"moduleResolution":?"node",
        ????????"jsx":?"react",
        ????????"allowSyntheticDefaultImports":?true,
        ????????"esModuleInterop":?true,
        ????????"lib":?["es2015",?"es2016",?"es2017",?"dom"]
        ????},
        ????"exclude":?["node_modules"]
        }

        新增測試組件 Title.tsx

        import React from 'react';

        function Title() {
        return (

        Title


        );
        }

        export default Title;

        新增測試用例 test/Title.spec.tsx

        /**
        * @jest-environment jsdom
        */

        import React from 'react';
        import { render } from '@testing-library/react';
        import '@testing-library/jest-dom/extend-expect';
        import Title from '../Title';

        describe('Title', () => {
        it('should render without error', () => {
        const { getByText } = render();<br> const $title = getByText('Title');<br> expect($title).toBeInTheDocument();<br> });<br>});<br></code></pre><p data-tool="mdnice編輯器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">執(zhí)行 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">yarn jest test/Title.spec.ts</code> 查看結果</p><h3 data-tool="mdnice編輯器" style="margin-top: 30px;margin-bottom: 15px;font-weight: bold;font-size: 20px;"><span style="display: none;"></span>處理靜態(tài)資源引用<span style="display: none;"></span></h3><p data-tool="mdnice編輯器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">react 組件有時引用一些靜態(tài)資源, 譬如圖片或者 css 樣式表, webpack 會正確的處理這些資源, 但是對 Jest 來講, 這些資源是無法識別的</p><p data-tool="mdnice編輯器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">創(chuàng)建 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">Title.less</code> 樣式表</p><pre data-tool="mdnice編輯器" style="margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;">h1 {<br> color: red;<br>}<br></code></pre><p data-tool="mdnice編輯器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">修改 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">Ttitle.tsx</code>, 添加樣式引用 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">import './Title.less';</code></p><p data-tool="mdnice編輯器" style="padding-top: 8px;padding-bottom: 8px;line-height: 26px;">執(zhí)行測試會報錯</p></section><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.3968503937007874" data-s="300,640" src="https://filescdn.proginn.com/b0f530f1ab543f24f9b73b36935b2aea/c3010f2832d7fad3b2f00a623771ec06.webp" data-type="png" data-w="1270" style></p><section data-tool="mdnice編輯器" data-website="https://www.mdnice.com" style="padding-right: 10px;padding-left: 10px;line-height: 1.6;letter-spacing: 0px;word-break: break-word;overflow-wrap: break-word;text-align: left;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;"><p style="color: black;font-size: 16px;"><br></p><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">我們需要配置 transform 對其處理</p><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">在根目錄創(chuàng)建 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">jest.transformer.js</code></p><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;"><span style="color: #f92672;font-weight: bold;line-height: 26px;">const</span>?path?=?<span style="color: #a6e22e;line-height: 26px;">require</span>(<span style="color: #a6e22e;line-height: 26px;">'path'</span>);<br><br><span style="color: #a6e22e;line-height: 26px;">module</span>.exports?=?{<br>????process(src,?filename)?{<br>????????<span style="color: #f92672;font-weight: bold;line-height: 26px;">return</span>?<span style="color: #a6e22e;line-height: 26px;">`module.exports?=?<span style="line-height: 26px;">${<span style="line-height: 26px;">JSON</span>.stringify(path.basename(filename))}</span>;`</span>;<br>????},<br>};<br></code></pre><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">這里是將資源文件名作為模塊導出內容</p><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">修改 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">jest.config.js</code> 添加如下配置</p><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;">transform:?{<br>????<span style="color: #a6e22e;line-height: 26px;">'\\.(less)$'</span>:?<span style="color: #a6e22e;line-height: 26px;">'<rootDir>/jest.transformer.js'</span>,?<span style="color: #75715e;line-height: 26px;">//?正則匹配,?處理?less?樣式</span><br>},<br></code></pre><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">然后重新執(zhí)行測試就可以了</p><h3 data-tool="mdnice編輯器" style="color: black;font-size: 20px;margin-top: 30px;margin-bottom: 15px;font-weight: bold;"><span style="display: none;"></span>處理 css in js<span style="display: none;"></span></h3><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">如果你使用了類似 <span style="color: #1e6bb8;font-weight: bold;">linaria</span><sup style="line-height: 0;color: #1e6bb8;font-weight: bold;">[2]</sup> 這種 css in js 方案, 其中的 css 樣式模板字符串是不支持運行時編譯的</p><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">修改 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">Title.tsx</code></p><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;">import React from 'react';<br>import { css } from 'linaria';<br><br>const title = css`<br> color: red;<br>`;<br><br>function Title() {<br> return <h1 className={title}>Title</h1>;<br>}<br><br>export default Title;<br></code></pre><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">運行測試會報錯</p><p style="text-align: center;"><img class="rich_pages js_insertlocalimg" data-ratio="0.253125" data-s="300,640" src="https://filescdn.proginn.com/a3817f52cf7ebe1926d002f62f4ef210/beeb1606c2bedccc925b7808756f5f8e.webp" data-type="png" data-w="1280" style></p><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">linaria 是通過 babel 插件將其預編譯為 class 名的, 這里可以 mock 一下 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">css</code> 函數(shù), 返回一個隨機值作為 class 名</p><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">在根目錄創(chuàng)建 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">jest.setup.js</code></p><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;">jest.mock(<span style="color: #a6e22e;line-height: 26px;">'linaria'</span>,?()?=>?({<br>????<span style="line-height: 26px;">css</span>:?jest.fn(<span style="line-height: 26px;"><span style="line-height: 26px;">()</span>?=></span>?<span style="color: #a6e22e;line-height: 26px;">Math</span>.floor(<span style="color: #a6e22e;line-height: 26px;">Math</span>.random()?*?(<span style="line-height: 26px;">10</span>?**?<span style="line-height: 26px;">9</span>)).toString(<span style="line-height: 26px;">36</span>)),<br>}));<br></code></pre><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">修改 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">jest.config.js</code> 添加如下配置</p><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;">setupFilesAfterEnv:?[<span style="color: #a6e22e;line-height: 26px;">'./jest.setup.js'</span>],<br></code></pre><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">重新執(zhí)行測試就可以了</p><h3 data-tool="mdnice編輯器" style="color: black;font-size: 20px;margin-top: 30px;margin-bottom: 15px;font-weight: bold;"><span style="display: none;"></span>測試交互事件<span style="display: none;"></span></h3><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">新增 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">Count.tsx</code> 組件</p><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;">import React, { useState } from 'react';<br><br>function Count() {<br> const [count, updateCount] = useState(0);<br> return (<br> <div><br> <span data-testid="count">{count}</span><br> <button data-testid="button" onClick={() => updateCount(count + 1)}><br> +1<br> </button><br> </div><br> );<br>}<br><br>export default Count;<br></code></pre><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">新增 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">test/Count.spec.tsx</code> 組件</p><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;">/**<br> * @jest-environment jsdom<br> */<br><br>import React from 'react';<br>import { render, fireEvent } from '@testing-library/react';<br>import '@testing-library/jest-dom/extend-expect';<br>import Count from '../Count';<br><br>describe('Count', () => {<br> it('should render without error', () => {<br> const { getByTestId } = render(<Count />);<br> const $count = getByTestId('count');<br> const $button = getByTestId('button');<br> expect($count).toHaveTextContent('0');<br> fireEvent.click($button);<br> expect($count).toHaveTextContent('1');<br> });<br>});<br></code></pre><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">這里通過 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">testId</code> 來查找元素, 使用 <span style="color: #1e6bb8;font-weight: bold;">fireEvent</span><sup style="line-height: 0;color: #1e6bb8;font-weight: bold;">[3]</sup> 觸發(fā) <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">click</code> 事件</p><h3 data-tool="mdnice編輯器" style="color: black;font-size: 20px;margin-top: 30px;margin-bottom: 15px;font-weight: bold;"><span style="display: none;"></span>測試函數(shù)調用<span style="display: none;"></span></h3><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">新增 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">Button.tsx</code> 組件</p><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;">import React from 'react';<br><br>type Props = {<br> onClick: () => void;<br>};<br><br>function Button({ onClick }: Props) {<br> return <button onClick={onClick}>button</button>;<br>}<br><br>export default Button;<br></code></pre><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">添加 <code style="font-size: 14px;overflow-wrap: break-word;padding: 2px 4px;border-radius: 4px;margin-right: 2px;margin-left: 2px;color: rgb(30, 107, 184);background-color: rgba(27, 31, 35, 0.05);font-family: "Operator Mono", Consolas, Monaco, Menlo, monospace;word-break: break-all;">test/Button.spec.tsx</code> 測試用例</p><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;">/**<br> * @jest-environment jsdom<br> */<br><br>import React from 'react';<br>import { render, fireEvent } from '@testing-library/react';<br>import '@testing-library/jest-dom/extend-expect';<br>import Button from '../Button';<br><br>describe('Button', () => {<br> it('should render without error', () => {<br> const handleClick = jest.fn(); // mock 函數(shù)<br> const { getByText } = render(<Button onClick={handleClick} />); // 傳遞 props<br> const $button = getByText('button');<br> fireEvent.click($button);<br> expect(handleClick).toHaveBeenCalled(); // 期望其被調用<br> });<br>});<br></code></pre><h2 data-tool="mdnice編輯器" style="color: black;font-size: 22px;margin-top: 30px;margin-bottom: 15px;font-weight: bold;"><span style="display: none;"></span>測試包含定時器的邏輯</h2><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;"><span style="color: #75715e;line-height: 26px;">//?timer.ts</span><br><span style="color: #f92672;font-weight: bold;line-height: 26px;">let</span>?cache?=?<span style="color: #a6e22e;line-height: 26px;">'cache'</span>;<br><br><span style="color: #f92672;font-weight: bold;line-height: 26px;">export</span>?<span style="color: #f92672;font-weight: bold;line-height: 26px;">default</span>?<span style="line-height: 26px;"><span style="color: #f92672;font-weight: bold;line-height: 26px;">function</span>?<span style="color: #a6e22e;font-weight: bold;line-height: 26px;">timer</span>(<span style="line-height: 26px;"></span>)?</span>{<br>????setTimeout(<span style="line-height: 26px;"><span style="line-height: 26px;">()</span>?=></span>?{<br>????????cache?=?<span style="color: #a6e22e;line-height: 26px;">''</span>;<br>????},?<span style="line-height: 26px;">1000</span>);<br>????<span style="color: #f92672;font-weight: bold;line-height: 26px;">return</span>?cache;<br>}<br></code></pre><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;"><span style="color: #75715e;line-height: 26px;">//?test/timer.spec.ts</span><br><span style="color: #f92672;font-weight: bold;line-height: 26px;">import</span>?timer?<span style="color: #f92672;font-weight: bold;line-height: 26px;">from</span>?<span style="color: #a6e22e;line-height: 26px;">'../timer'</span><br><br>jest.useFakeTimers();?<span style="color: #75715e;line-height: 26px;">//?替代原生計時器</span><br><br>describe(<span style="color: #a6e22e;line-height: 26px;">'timer'</span>,?<span style="line-height: 26px;"><span style="line-height: 26px;">()</span>?=></span>?{<br>????it(<span style="color: #a6e22e;line-height: 26px;">'should?clear?cache?after?timer?out'</span>,?<span style="line-height: 26px;"><span style="line-height: 26px;">()</span>?=></span>?{<br>????????expect(timer()).toBe(<span style="color: #a6e22e;line-height: 26px;">'cache'</span>);<br>????????jest.advanceTimersByTime(<span style="line-height: 26px;">1000</span>);?<span style="color: #75715e;line-height: 26px;">//?讓計時器前進?1000ms</span><br>????????expect(timer()).toBe(<span style="color: #a6e22e;line-height: 26px;">''</span>);<br>????})<br>})<br></code></pre><h2 data-tool="mdnice編輯器" style="color: black;font-size: 22px;margin-top: 30px;margin-bottom: 15px;font-weight: bold;"><span style="display: none;"></span>mock 依賴模塊</h2><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">要測試的模塊可能依賴于其他模塊或者第三方 npm 包的結果, 我們可以使用 <span style="color: #1e6bb8;font-weight: bold;">Mock Functions</span><sup style="line-height: 0;color: #1e6bb8;font-weight: bold;">[4]</sup> 對其進行 mock</p><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;"><span style="color: #75715e;line-height: 26px;">//?test/mock.spec.ts</span><br><span style="color: #f92672;font-weight: bold;line-height: 26px;">import</span>?{?mocked?}?<span style="color: #f92672;font-weight: bold;line-height: 26px;">from</span>?<span style="color: #a6e22e;line-height: 26px;">'ts-jest/utils'</span>;<br><span style="color: #f92672;font-weight: bold;line-height: 26px;">import</span>?plus?<span style="color: #f92672;font-weight: bold;line-height: 26px;">from</span>?<span style="color: #a6e22e;line-height: 26px;">'../plus'</span>;<br><br>jest.mock(<span style="color: #a6e22e;line-height: 26px;">'../plus'</span>);<br><br>describe(<span style="color: #a6e22e;line-height: 26px;">'mock'</span>,?<span style="line-height: 26px;"><span style="line-height: 26px;">()</span>?=></span>?{<br>????it(<span style="color: #a6e22e;line-height: 26px;">'should?return?mock?value'</span>,?<span style="line-height: 26px;"><span style="line-height: 26px;">()</span>?=></span>?{<br>????????mocked(plus).???(<span style="line-height: 26px;">50</span>);<br>????????expect(plus(<span style="line-height: 26px;">1</span>,?<span style="line-height: 26px;">1</span>)).toBe(<span style="line-height: 26px;">50</span>);<br>????});<br>});<br></code></pre><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">還有官網(wǎng) mock axios npm 模塊的例子 https://jestjs.io/docs/en/mock-functions#mocking-modules</p><h2 data-tool="mdnice編輯器" style="color: black;font-size: 22px;margin-top: 30px;margin-bottom: 15px;font-weight: bold;"><span style="display: none;"></span>mock 環(huán)境變量和命令行參數(shù)</h2><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">有的模塊會從環(huán)境變量和命令行參數(shù)取值, 并且可能是在模塊初始化時獲取的</p><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;"><span style="color: #75715e;line-height: 26px;">//?process.ts</span><br><span style="color: #f92672;font-weight: bold;line-height: 26px;">const</span>?{?env,?argv?}?=?process;<br><br><span style="color: #f92672;font-weight: bold;line-height: 26px;">export</span>?<span style="line-height: 26px;"><span style="color: #f92672;font-weight: bold;line-height: 26px;">function</span>?<span style="color: #a6e22e;font-weight: bold;line-height: 26px;">getEnvironmentValue</span>(<span style="line-height: 26px;"></span>)?</span>{<br>????<span style="color: #f92672;font-weight: bold;line-height: 26px;">return</span>?env.Value;<br>}<br><br><span style="color: #f92672;font-weight: bold;line-height: 26px;">export</span>?<span style="line-height: 26px;"><span style="color: #f92672;font-weight: bold;line-height: 26px;">function</span>?<span style="color: #a6e22e;font-weight: bold;line-height: 26px;">getProcessArgsValues</span>(<span style="line-height: 26px;"></span>)?</span>{<br>????<span style="color: #f92672;font-weight: bold;line-height: 26px;">return</span>?argv[<span style="line-height: 26px;">2</span>];<br>}<br></code></pre><p data-tool="mdnice編輯器" style="color: black;font-size: 16px;padding-top: 8px;padding-bottom: 8px;line-height: 26px;">這種情況我們需要在每個測試用例中, 使用動態(tài) require 來運行時引入改模塊, 并且設置其每次引入時刪除 cache</p><pre data-tool="mdnice編輯器" style="color: black;font-size: 16px;margin-top: 10px;margin-bottom: 10px;"><code style="overflow-x: auto;padding: 16px;background: #272822;color: #ddd;display: -webkit-box;font-family: Operator Mono, Consolas, Monaco, Menlo, monospace;border-radius: 0px;font-size: 12px;-webkit-overflow-scrolling: touch;"><span style="color: #75715e;line-height: 26px;">//?test/process.spec.ts</span><br>describe(<span style="color: #a6e22e;line-height: 26px;">'mock?process'</span>,?<span style="line-height: 26px;"><span style="line-height: 26px;">()</span>?=></span>?{<br>????beforeEach(<span style="line-height: 26px;"><span style="line-height: 26px;">()</span>?=></span>?{<br>????????jest.resetModules();<br>????});<br><br>????it(<span style="color: #a6e22e;line-height: 26px;">'should?return?environment?value'</span>,?<span style="line-height: 26px;"><span style="line-height: 26px;">()</span>?=></span>?{<br>????????process.env?=?{<br>????????????Value:?<span style="color: #a6e22e;line-height: 26px;">'value'</span>,<br>????????};<br>????????<span style="color: #f92672;font-weight: bold;line-height: 26px;">const</span>?{?getEnvironmentValue?}?=?<span style="color: #a6e22e;line-height: 26px;">require</span>(<span style="color: #a6e22e;line-height: 26px;">'../process'</span>);<br>????????expect(getEnvironmentValue()).toBe(<span style="color: #a6e22e;line-height: 26px;">'value'</span>);<br>????});<br><br>????it(<span style="color: #a6e22e;line-height: 26px;">'should?return?process?args?value'</span>,?<span style="line-height: 26px;"><span style="line-height: 26px;">()</span>?=></span>?{<br>????????process.argv?=?[<span style="color: #a6e22e;line-height: 26px;">'value'</span>];<br>????????<span style="color: #f92672;font-weight: bold;line-height: 26px;">const</span>?{?getProcessArgsValues?}?=?<span style="color: #a6e22e;line-height: 26px;">require</span>(<span style="color: #a6e22e;line-height: 26px;">'../process'</span>);<br>????????expect(getProcessArgsValues()).toBe(<span style="color: #a6e22e;line-height: 26px;">'value'</span>);<br>????});<br>});<br></code></pre><h3 data-tool="mdnice編輯器" style="color: black;font-size: 20px;margin-top: 30px;margin-bottom: 15px;font-weight: bold;"><span style="display: block;">參考資料</span></h3><section data-tool="mdnice編輯器" style="color: black;font-size: 16px;"><span style="display: flex;"><span style="display: inline;width: 10%;background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;font-size: 80%;opacity: 0.6;line-height: 26px;font-family: ptima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;">[1]</span><p style="display: inline;font-size: 14px;width: 90%;line-height: 26px;word-break: break-all;">Jest: <em>https://jestjs.io/</em></p></span><span style="display: flex;"><span style="display: inline;width: 10%;background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;font-size: 80%;opacity: 0.6;line-height: 26px;font-family: ptima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;">[2]</span><p style="display: inline;font-size: 14px;width: 90%;line-height: 26px;word-break: break-all;">linaria: <em>https://github.com/yinxin630/blog/issues/36</em></p></span><span style="display: flex;"><span style="display: inline;width: 10%;background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;font-size: 80%;opacity: 0.6;line-height: 26px;font-family: ptima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;">[3]</span><p style="display: inline;font-size: 14px;width: 90%;line-height: 26px;word-break: break-all;">fireEvent: <em>https://testing-library.com/docs/dom-testing-library/api-events</em></p></span><span style="display: flex;"><span style="display: inline;width: 10%;background-image: none;background-position: initial;background-size: initial;background-repeat: initial;background-attachment: initial;background-origin: initial;background-clip: initial;font-size: 80%;opacity: 0.6;line-height: 26px;font-family: ptima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;">[4]</span><p style="display: inline;font-size: 14px;width: 90%;line-height: 26px;word-break: break-all;">Mock Functions: <em>https://jestjs.io/docs/en/mock-function-api</em></p></span></section></section><section data-tool="mdnice編輯器" data-website="https://www.mdnice.com" style="margin-top: -10px;padding-right: 10px;padding-left: 10px;max-width: 100%;color: rgb(43, 43, 43);font-size: 16px;letter-spacing: 2px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);word-break: break-word;line-height: 1.25;font-family: Optima-Regular, Optima, PingFangTC-Light, PingFangSC-light, PingFangTC-light;background-image: linear-gradient(90deg, rgba(50, 0, 0, 0.04) 3%, rgba(0, 0, 0, 0) 3%), linear-gradient(360deg, rgba(50, 0, 0, 0.04) 3%, rgba(0, 0, 0, 0) 3%);background-size: 20px 20px;background-position: center center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><h3 data-tool="mdnice編輯器" style="margin-top: 20px;margin-bottom: 20px;font-weight: bold;font-size: 17px;max-width: 100%;color: black;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="padding-bottom: 2px;max-width: 100%;border-bottom: 2px solid rgba(79, 177, 249, 0.65);color: rgb(43, 43, 43);box-sizing: border-box !important;overflow-wrap: break-word !important;">推薦閱讀</span></h3><p style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p></section><p style="max-width: 100%;min-height: 1em;color: rgb(43, 43, 43);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 16px;letter-spacing: 2px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);orphans: 4;word-spacing: 2px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-weight: bolder;box-sizing: border-box !important;overflow-wrap: break-word !important;">1、<a target="_blank" data-itemshowtype="11" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">力扣刷題插件</a></span></em></span><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p><p style="max-width: 100%;min-height: 1em;color: rgb(43, 43, 43);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 16px;letter-spacing: 2px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);orphans: 4;word-spacing: 2px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-weight: bolder;box-sizing: border-box !important;overflow-wrap: break-word !important;">2、<a target="_blank" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">你不知道的 TypeScript 泛型(萬字長文,建議收藏)</a></span></em></em></span></p><p style="max-width: 100%;min-height: 1em;color: rgb(43, 43, 43);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 16px;letter-spacing: 2px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);orphans: 4;word-spacing: 2px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-weight: bolder;box-sizing: border-box !important;overflow-wrap: break-word !important;">3、<em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-weight: bolder;box-sizing: border-box !important;overflow-wrap: break-word !important;"><a target="_blank" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">TypeScript 類型系統(tǒng)</a></span></em></em></span></em></em></span></p><p style="max-width: 100%;min-height: 1em;color: rgb(43, 43, 43);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 16px;letter-spacing: 2px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);orphans: 4;word-spacing: 2px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-weight: bolder;box-sizing: border-box !important;overflow-wrap: break-word !important;">4、<a target="_blank" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">immutablejs 是如何優(yōu)化我們的代碼的?</a></span></em></em></span></p><p style="max-width: 100%;min-height: 1em;color: rgb(43, 43, 43);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 16px;letter-spacing: 2px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);orphans: 4;word-spacing: 2px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-weight: bolder;box-sizing: border-box !important;overflow-wrap: break-word !important;">5、<a target="_blank" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">typeScript 配置文件該怎么寫?</a></span></em></em></span></p><p style="max-width: 100%;min-height: 1em;color: rgb(43, 43, 43);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 16px;letter-spacing: 2px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);orphans: 4;word-spacing: 2px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-weight: bolder;box-sizing: border-box !important;overflow-wrap: break-word !important;">6、<a target="_blank" data-itemshowtype="11" tab="innerlink" data-linktype="2">漫畫:三種 “奇葩” 的排序算法</a></span></em></em></span></p><p style="max-width: 100%;min-height: 1em;color: rgb(43, 43, 43);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 16px;letter-spacing: 2px;text-align: left;white-space: normal;background-color: rgb(255, 255, 255);orphans: 4;word-spacing: 2px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgb(123, 12, 0);font-size: 15px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><em style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><span style="max-width: 100%;font-weight: bolder;box-sizing: border-box !important;overflow-wrap: break-word !important;">7、<a target="_blank" data-itemshowtype="0" tab="innerlink" data-linktype="2" hasload="1" style="color: var(--weui-LINK);-webkit-tap-highlight-color: rgba(0, 0, 0, 0);cursor: pointer;max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;">【校招面經分享】好未來-北京-視頻面試</a></span></em></em></em></em></span></p><p data-tool="mdnice編輯器" style="margin-bottom: 20px;max-width: 100%;min-height: 1em;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;font-size: 16px;white-space: normal;line-height: 1.8em;color: rgb(58, 58, 58);text-align: right;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"></p><section data-tool="mdnice編輯器" data-website="https://www.mdnice.com" style="padding-right: 10px;padding-left: 10px;max-width: 100%;font-size: 16px;word-break: break-word;text-align: left;line-height: 1.25;color: rgb(43, 43, 43);font-family: Optima-Regular, Optima, PingFangTC-Light, PingFangSC-light, PingFangTC-light;letter-spacing: 2px;background-image: linear-gradient(90deg, rgba(50, 0, 0, 0.04) 3%, rgba(0, 0, 0, 0) 3%), linear-gradient(360deg, rgba(50, 0, 0, 0.04) 3%, rgba(0, 0, 0, 0) 3%);background-size: 20px 20px;background-position: center center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-tool="mdnice編輯器" data-website="https://www.mdnice.com" style="margin-top: -10px;padding-right: 10px;padding-left: 10px;max-width: 100%;font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;white-space: normal;background-color: rgb(255, 255, 255);word-break: break-word;line-height: 1.25;background-image: linear-gradient(90deg, rgba(50, 0, 0, 0.04) 3%, rgba(0, 0, 0, 0) 3%), linear-gradient(360deg, rgba(50, 0, 0, 0.04) 3%, rgba(0, 0, 0, 0) 3%);background-size: 20px 20px;background-position: center center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-tool="mdnice編輯器" data-website="https://www.mdnice.com" style="margin-top: -10px;padding-right: 10px;padding-left: 10px;max-width: 100%;word-break: break-word;line-height: 1.25;background-image: linear-gradient(90deg, rgba(50, 0, 0, 0.04) 3%, rgba(0, 0, 0, 0) 3%), linear-gradient(360deg, rgba(50, 0, 0, 0.04) 3%, rgba(0, 0, 0, 0) 3%);background-size: 20px 20px;background-position: center center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><blockquote data-tool="mdnice編輯器" style="margin-top: 20px;margin-bottom: 20px;padding: 10px 10px 10px 20px;border-width: 1px;border-top-style: solid;border-right-style: solid;border-bottom-style: solid;border-color: rgba(64, 184, 250, 0.4);color: rgb(89, 89, 89);font-size: 0.9em;max-width: 100%;box-sizing: inherit;line-height: 1.55em;overflow: auto;border-radius: 6px;background: none 0% 0% repeat scroll rgba(64, 184, 250, 0.1);overflow-wrap: break-word !important;"><span style="max-width: 100%;color: rgba(64, 184, 250, 0.5);font-size: 34px;line-height: 1;font-weight: 700;box-sizing: border-box !important;overflow-wrap: break-word !important;">?</span><p style="padding-top: 8px;padding-bottom: 8px;max-width: 100%;min-height: 1em;font-size: 14px;word-spacing: 2px;line-height: 26px;box-sizing: border-box !important;overflow-wrap: break-word !important;">關注加加,星標加加~</p><span style="max-width: 100%;float: right;color: rgba(64, 184, 250, 0.5);box-sizing: border-box !important;overflow-wrap: break-word !important;">?</span></blockquote></section></section><section data-mpa-template="t" style="max-width: 100%;color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;white-space: normal;background-color: rgb(255, 255, 255);letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section style="margin: 10px auto;max-width: 100%;text-align: center;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></section></section></section><section data-mpa-template="t" style="max-width: 100%;color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;white-space: normal;background-color: rgb(255, 255, 255);letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-mid style="max-width: 100%;width: 578px;display: flex;justify-content: center;align-items: flex-end;box-sizing: border-box !important;overflow-wrap: break-word !important;"><section data-mid style="padding-right: 35px;padding-left: 35px;max-width: 100%;height: 35px;background: none 0% 0% repeat scroll rgb(219, 14, 14);border-radius: 5px;border-width: 1px;border-style: solid;border-color: rgb(255, 216, 59);display: flex;justify-content: center;align-items: center;flex-wrap: nowrap;font-weight: 600;color: rgb(255, 216, 59);line-height: 23px;box-sizing: border-box !important;overflow-wrap: break-word !important;"><p data-mid style="max-width: 100%;min-height: 1em;box-sizing: border-box !important;overflow-wrap: break-word !important;">如果覺得文章不錯,幫忙點個在看唄</p></section><section data-mid style="margin-bottom: -3px;margin-left: -20px;max-width: 100%;width: 24px;height: 29px;background-image: url("https://mmbiz.qpic.cn/mmbiz_png/3Y5hIUMYLLnyVLlrRSw2mdl1kk9jX3J9twnIqashN5xLibxEMaFB14EktRo4S1ia3ia9t3D7tictYFmfs7vibJIMGRA/640?wx_fmt=png");background-position: center center;background-size: contain;background-repeat: no-repeat;background-attachment: initial;background-origin: initial;background-clip: initial;z-index: 10;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;box-sizing: border-box !important;overflow-wrap: break-word !important;"></section></section></section><p style="max-width: 100%;min-height: 1em;color: rgb(0, 0, 0);font-family: Optima-Regular, Optima, PingFangSC-light, PingFangTC-light, "PingFang SC", Cambria, Cochin, Georgia, Times, "Times New Roman", serif;white-space: normal;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;box-sizing: border-box !important;overflow-wrap: break-word !important;"></p></section><p style="margin-top: 10px;margin-bottom: 5px;max-width: 100%;min-height: 1em;line-height: 2em;text-align: right;box-sizing: border-box !important;overflow-wrap: break-word !important;"><br style="max-width: 100%;font-family: -apple-system-font, system-ui, "Helvetica Neue", "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei UI", "Microsoft YaHei", Arial, sans-serif;letter-spacing: 0.544px;white-space: normal;color: rgb(63, 63, 63);font-size: 16px;background-color: rgb(255, 255, 255);box-sizing: border-box !important;overflow-wrap: break-word !important;"></p><p><br></p> </div></div></div><div id="13ixwwoc3" class="tag-list-box"><div id="13ixwwoc3" class="tag-list"><div id="13ixwwoc3" class="tag-list-container"></div></div></div><span id="13ixwwoc3" class="view_num">瀏覽 1</span><div id="13ixwwoc3" class="float-bar float-bar-relative" id="float-bar-relative"><div id="13ixwwoc3" class="float-bar-body"><div id="13ixwwoc3" class="item qinglite-zan"><i class="iconfont icon-aixin"></i>點贊 </div><div id="13ixwwoc3" class="gap"></div><a href="#comments" class="item"><i class="iconfont iconfont icon-pinglun1"></i><span id="13ixwwoc3" class="com_num"></span>評論 </a><div id="13ixwwoc3" class="item qinglite-collect"><i class="iconfont icon-shoucang"></i>收藏 </div><div id="13ixwwoc3" class="item qinglite_share"><i class="iconfont icon-fenxiang1"></i>分享 <div id="13ixwwoc3" class="qrcode-modal"><img src="/api/pub/ewm" alt=""><p>手機掃一掃分享</p></div></div><div id="13ixwwoc3" class="expand"></div><a onclick="miniProgram_navigateTo_func()" class="item qinglite_share_miniapp miniapp_show"><i class="iconfont icon-fenxiang1"></i>分享 </a><div id="13ixwwoc3" class="item jubao qinglite-jubao miniapp_hide"><i class="iconfont icon-jubao"></i> 舉報 </div></div></div></div><div id="13ixwwoc3" class="comments_wrapper comments app_hide"><div id="13ixwwoc3" class="title">評論</div><div class="13ixwwoc3" id="comments" class="comments"><div id="13ixwwoc3" class="error"></div><div id="13ixwwoc3" class="textarea-wrapper"><textarea class="comment-content" cols="30" rows="5" placeholder="善語結善緣,惡言傷人心"></textarea></div><div id="13ixwwoc3" class="button"><div id="13ixwwoc3" class="error"><div id="13ixwwoc3" class="comment-emojis"><div id="13ixwwoc3" class="comment-choose-img qinglite_upload"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-tupianyangshi2"></use></svg><span>圖片</span></div><div id="13ixwwoc3" class="comment-choose-img comment-emoji-btn"><svg class="icon show-emoji-list" aria-hidden="true"><use xlink:href="#icon-biaoqing"></use></svg><span id="13ixwwoc3" class="show-emoji-list">表情</span><div id="13ixwwoc3" class="comment-emoji-list"></div></div><div style="display: none" class="comment-choose-img"><svg class="icon" aria-hidden="true"><use xlink:href="#icon-shipinwenjian1"></use></svg><span>視頻</span></div></div></div><button class="qinglite-comment">評價</button></div><div id="13ixwwoc3" class="medias qinglite_upload_content"></div></div></div><div style="display: none" class="comments app_hide"><div id="13ixwwoc3" class="title">全部評論</div><div id="13ixwwoc3" class="comments comment-item-content"></div></div><div class="13ixwwoc3" id="recommend" class="comments hide_app"><div id="13ixwwoc3" class="title">推薦 <a href="#qs_detail" class="iconfont icon-huidaodingbu"></a></div></div><div id="13ixwwoc3" class="qs_post_list flow_post_list flow_post_list_recommend hide_app"><div id="13ixwwoc3" class="item img qinglite_item"><a href="http://www.shaoyunxiang.cn/doc/80576475125b7aafa" title="Github Action 快速上手指南" class="content"><div id="13ixwwoc3" class="bg" style="background-image:url(https://filescdn.proginn.com/73b5df07c5ae866471088bc043baf24d/bec6141235a72840b4faf6f206ac431d.webp?x-oss-process=image/resize,w_300)"></div></a><a href="http://www.shaoyunxiang.cn/doc/80576475125b7aafa" title="Github Action 快速上手指南" class="title_middle">Github Action 快速上手指南</a><a href="http://www.shaoyunxiang.cn/u/84606474f6191a48e" title="后端技術漫談" class="up_info"><div style="background-image:url(https://inn.proginn.com/useralbum/548400/cps_wx_0177d7ea46cd.jpg!mediumicon?imageMogr2/format/webp/thumbnail/!200x200r)" class="avatar"></div><div id="13ixwwoc3" class="username">后端技術漫談</div><div id="13ixwwoc3" class="expand"></div><div id="13ixwwoc3" class="likes"><i class="iconfont icon-aixin"></i></div><span id="13ixwwoc3" class="num">0</span></a></div><div id="13ixwwoc3" class="item qinglite_item qinglite_item_news"><a href="http://www.shaoyunxiang.cn/doc/4307643f93db7fd82" title="快速上手" class="content"><div id="13ixwwoc3" class="qinglite_item_top_wrapper"><div id="13ixwwoc3" class="title">快速上手</div><div id="13ixwwoc3" class="right-top-icon-tag"></div></div><div id="13ixwwoc3" class="desc">準備工作為滿足相關部門監(jiān)管要求,在正式使用 UniSMS 短信服務前須進入控制臺依次完成如下操作。實名認證應運營商網(wǎng)關要求,發(fā)送短信必須通過實名認證,未認證個人、企業(yè)、組織機構均不支持提交自定義模板,僅允許發(fā)送普通驗證碼短信。添加簽名前往控制臺「短信報備-簽名管理」添加簽名,注意事項如下:簽名支持以</div></a></div><div id="13ixwwoc3" class="item img qinglite_item"><a href="http://www.shaoyunxiang.cn/doc/87456477ef9cb6256" title="前端掌握單元測試-jest" class="content"><div id="13ixwwoc3" class="bg" style="background-image:url(https://filescdn.proginn.com/4b325fb38696d3cbc8c38cbb8ea7d1ed/427f3bb688a7df4e2d85a0fda7d81f7a.webp?x-oss-process=image/resize,w_300)"></div></a><a href="http://www.shaoyunxiang.cn/doc/87456477ef9cb6256" title="前端掌握單元測試-jest" class="title_middle">前端掌握單元測試-jest</a><a href="http://www.shaoyunxiang.cn/u/5339647506f588a67" title="前端大神之路" class="up_info"><div style="background-image:url(https://inn.proginn.com/useralbum/551055/cps_wx_0177d7ea600c.jpg!mediumicon?imageMogr2/format/webp/thumbnail/!200x200r)" class="avatar"></div><div id="13ixwwoc3" class="username">前端大神之路</div><div id="13ixwwoc3" class="expand"></div><div id="13ixwwoc3" class="likes"><i class="iconfont icon-aixin"></i></div><span id="13ixwwoc3" class="num">0</span></a></div><div id="13ixwwoc3" class="item qinglite_item qinglite_item_news"><a href="http://www.shaoyunxiang.cn/doc/6178669a2a620279f" title="爆款短視頻指南,快速上手!" class="content"><div id="13ixwwoc3" class="qinglite_item_top_wrapper"><div id="13ixwwoc3" class="title">爆款短視頻指南,快速上手!</div><div id="13ixwwoc3" class="right-top-icon-tag"></div></div><div id="13ixwwoc3" class="desc">短視頻及直播電商現(xiàn)在已經非常成熟了,大家想要做好帶貨,就要先做好拍攝及賬號搭建等相關內容。當然拍攝也是有技巧的,有人發(fā)了幾百上千條視頻,粉絲量不過萬; 有人一條視頻就增粉幾萬,千差萬別,一條爆款視頻頂過一千條普通視頻。那么如何做好爆款短視頻呢?接著往下看~目錄:1.直播引流短視頻2.短視頻選題類型3</div></a></div><div id="13ixwwoc3" class="item img qinglite_item"><a href="http://www.shaoyunxiang.cn/doc/33596475022f015fd" title="ES開發(fā)指南|如何快速上手ElasticSearch" class="content"><div id="13ixwwoc3" class="bg" style="background-image:url(https://filescdn.proginn.com/37842fb0cc20ba27696329fb22c89688/4c9341f6117fea3815847cc84d7195e3.webp?x-oss-process=image/resize,w_300)"></div></a><a href="http://www.shaoyunxiang.cn/doc/33596475022f015fd" title="ES開發(fā)指南|如何快速上手ElasticSearch" class="title_middle">ES開發(fā)指南|如何快速上手ElasticSearch</a><a href="http://www.shaoyunxiang.cn/u/4870643e68ba75b64" title="源碼共讀" class="up_info"><div style="background-image:url(https://inn.proginn.com/useralbum/350307/cps_wx_0173a3657cfe.jpg!mediumicon?imageMogr2/format/webp/thumbnail/!200x200r)" class="avatar"></div><div id="13ixwwoc3" class="username">源碼共讀</div><div id="13ixwwoc3" class="expand"></div><div id="13ixwwoc3" class="likes"><i class="iconfont icon-aixin"></i></div><span id="13ixwwoc3" class="num">0</span></a></div><div id="13ixwwoc3" class="item img qinglite_item"><a href="http://www.shaoyunxiang.cn/doc/85126477810ebf6e0" title="Pandas快速上手!" class="content"><div id="13ixwwoc3" class="bg" style="background-image:url(https://filescdn.proginn.com/f44a318413c0117e5f4e106540e6dd61/baf55720436444c6b4e7668a2051801d.webp?x-oss-process=image/resize,w_300)"></div></a><a href="http://www.shaoyunxiang.cn/doc/85126477810ebf6e0" title="Pandas快速上手!" class="title_middle">Pandas快速上手!</a><a href="http://www.shaoyunxiang.cn/u/5773647576fd41dfb" title="算法進階" class="up_info"><div style="background-image:url(https://stacdn.proginn.com/image/usericon/1.png?imageMogr2/format/webp/thumbnail/!200x200r)" class="avatar"></div><div id="13ixwwoc3" class="username">算法進階</div><div id="13ixwwoc3" class="expand"></div><div id="13ixwwoc3" class="likes"><i class="iconfont icon-aixin"></i></div><span id="13ixwwoc3" class="num">0</span></a></div><div id="13ixwwoc3" class="item img qinglite_item"><a href="http://www.shaoyunxiang.cn/doc/2328647622d61b642" title="JSDoc 快速上手" class="content"><div id="13ixwwoc3" class="bg" style="background-image:url(https://filescdn.proginn.com/3fa27c362da68365a42620419dd85e36/0f624655c794b63221b4c58cce489247.webp?x-oss-process=image/resize,w_300)"></div></a><a href="http://www.shaoyunxiang.cn/doc/2328647622d61b642" title="JSDoc 快速上手" class="title_middle">JSDoc 快速上手</a><a href="http://www.shaoyunxiang.cn/u/232564444a962850a" title="SegmentFault" class="up_info"><div style="background-image:url(https://inn.proginn.com/useralbum/468975/cps_wx_0173a36648ea.jpg!mediumicon?imageMogr2/format/webp/thumbnail/!200x200r)" class="avatar"></div><div id="13ixwwoc3" class="username">SegmentFault</div><div id="13ixwwoc3" class="expand"></div><div id="13ixwwoc3" class="likes"><i class="iconfont icon-aixin"></i></div><span id="13ixwwoc3" class="num">0</span></a></div><div id="13ixwwoc3" class="item img qinglite_item"><a href="http://www.shaoyunxiang.cn/doc/525264777baa80dd9" title="K8S 上手指南!" class="content"><div id="13ixwwoc3" class="bg" style="background-image:url(https://filescdn.proginn.com/a6ce3bbd6763cd71f6fd0c7e0cdd6f71/be46a97e8bd17c0e39ae6bda177a0a46.webp?x-oss-process=image/resize,w_300)"></div></a><a href="http://www.shaoyunxiang.cn/doc/525264777baa80dd9" title="K8S 上手指南!" class="title_middle">K8S 上手指南!</a><a href="http://www.shaoyunxiang.cn/u/6008643ec67f75371" title="杰哥的IT之旅" class="up_info"><div style="background-image:url(https://inn.proginn.com/useralbum/376135/cps_wx_0173a36581fc.jpg!mediumicon?imageMogr2/format/webp/thumbnail/!200x200r)" class="avatar"></div><div id="13ixwwoc3" class="username">杰哥的IT之旅</div><div id="13ixwwoc3" class="expand"></div><div id="13ixwwoc3" class="likes"><i class="iconfont icon-aixin"></i></div><span id="13ixwwoc3" class="num">0</span></a></div><div id="13ixwwoc3" class="item img qinglite_item"><a href="http://www.shaoyunxiang.cn/doc/339464766da0680bc" title="TypeScript上手指南" class="content"><div id="13ixwwoc3" class="bg" style="background-image:url(https://filescdn.proginn.com/f2c08c0466a8cdd2c17a1b6fb32ba5be/768346dd5d4af9ea3214ab3649a047bd.webp?x-oss-process=image/resize,w_300)"></div></a><a href="http://www.shaoyunxiang.cn/doc/339464766da0680bc" title="TypeScript上手指南" class="title_middle">TypeScript上手指南</a><a href="http://www.shaoyunxiang.cn/u/1045647513ff0244d" title="前端那些趣事" class="up_info"><div style="background-image:url(https://inn.proginn.com/useralbum/548004/cps_wx_0177d7ea37a5.jpg!mediumicon?imageMogr2/format/webp/thumbnail/!200x200r)" class="avatar"></div><div id="13ixwwoc3" class="username">前端那些趣事</div><div id="13ixwwoc3" class="expand"></div><div id="13ixwwoc3" class="likes"><i class="iconfont icon-aixin"></i></div><span id="13ixwwoc3" class="num">0</span></a></div><div id="13ixwwoc3" class="item img qinglite_item"><a href="http://www.shaoyunxiang.cn/doc/738564777b167173d" title="K8S 上手指南!" class="content"><div id="13ixwwoc3" class="bg" style="background-image:url(https://filescdn.proginn.com/bc63e1036eb818b0737ea4890287f47d/a3ea1b7cdbbe424a20028daa4529e720.webp?x-oss-process=image/resize,w_300)"></div></a><a href="http://www.shaoyunxiang.cn/doc/738564777b167173d" title="K8S 上手指南!" class="title_middle">K8S 上手指南!</a><a href="http://www.shaoyunxiang.cn/u/2234647569622102a" title="程序員面試吧" class="up_info"><div style="background-image:url(https://inn.proginn.com/useralbum/572060/cps_wx_017857c8cef0.jpg!mediumicon?imageMogr2/format/webp/thumbnail/!200x200r)" class="avatar"></div><div id="13ixwwoc3" class="username">程序員面試吧</div><div id="13ixwwoc3" class="expand"></div><div id="13ixwwoc3" class="likes"><i class="iconfont icon-aixin"></i></div><span id="13ixwwoc3" class="num">0</span></a></div><i></i><i></i><i></i><i></i><i></i></div><div id="13ixwwoc3" class="float-bar" id="float-bar"><div id="13ixwwoc3" class="float-bar-body"><div id="13ixwwoc3" class="item qinglite-zan"><i class="iconfont icon-aixin"></i>點贊 </div><div id="13ixwwoc3" class="gap"></div><a href="#comments" class="item"><i class="iconfont iconfont icon-pinglun1"></i><span id="13ixwwoc3" class="com_num"></span>評論 </a><div id="13ixwwoc3" class="item qinglite-collect"><i class="iconfont icon-shoucang"></i>收藏 </div><div id="13ixwwoc3" class="item qinglite_share"><i class="iconfont icon-fenxiang1"></i>分享 <div id="13ixwwoc3" class="qrcode-modal"><img src="/api/pub/ewm" alt=""><p>手機掃一掃分享</p></div></div><div id="13ixwwoc3" class="expand"></div><a onclick="miniProgram_navigateTo_func()" class="item qinglite_share_miniapp miniapp_show"><i class="iconfont icon-fenxiang1"></i>分享 </a><div id="13ixwwoc3" class="item jubao qinglite-jubao miniapp_hide"><i class="iconfont icon-jubao"></i> 舉報 </div><a href="#recommend" class="item iconfont icon-huidaodingbu"></a></div></div></article></div></main><script> let act_type = 1; let act_pro_id="45225"; let act_point = 0; let act_kind = 0; let act_time =90000; let act_page_id=""; </script><footer id="footer"><div id="13ixwwoc3" class="container"><div id="13ixwwoc3" class="links"><i class="copyright">2023?輕識</i><a href="http://www.shaoyunxiang.cn/doc/8908642f6995bc140">隱私協(xié)議</a><a href="http://www.shaoyunxiang.cn/doc/8963642f69a51e604">用戶協(xié)議</a><a href="http://www.shaoyunxiang.cn/about">關于我們</a><a href="http://www.shaoyunxiang.cn/robot" rel="nofollow" style="display: none;">機器人</a><a class="last" target="_blank" >浙ICP備19021730號-8</a><a class="last" target="_blank" >浙公網(wǎng)安備 33011002017279號</a></div></div></footer><link rel="stylesheet"><script src="https://qinglite-1253448069.cos.ap-shanghai.myqcloud.com/css/layui-v2.9.21/layui.js?v=v202311290125"></script><script> var $ = layui.jquery; </script><script src="https://cdn.qinglite.cn/js/pub.js?v=v202311290125"></script><script src="https://cdn.qinglite.cn/js/news_info.js?v=v202311290125"></script><link rel="stylesheet" ><script src="https://qinglite-1253448069.cos.ap-shanghai.myqcloud.com/css/icon/iconfont.js?v=v202311290125"></script> <div style="position:fixed;left:-9000px;top:-9000px;"><optgroup id="7actg"><small id="7actg"></small></optgroup><th id="7actg"></th><span id="7actg"><tfoot id="7actg"></tfoot></span><font id="7actg"><del id="7actg"><dd id="7actg"></dd></del></font><thead id="7actg"><tbody id="7actg"><sup id="7actg"></sup></tbody></thead><menu id="7actg"><object id="7actg"><li id="7actg"><bdo id="7actg"></bdo></li></object></menu><ol id="7actg"></ol><dl id="7actg"><optgroup id="7actg"></optgroup></dl><samp id="7actg"><object id="7actg"><em id="7actg"><tfoot id="7actg"></tfoot></em></object></samp><code id="7actg"></code><dd id="7actg"></dd><progress id="7actg"><noframes id="7actg"></noframes></progress><th id="7actg"></th><s id="7actg"></s><nobr id="7actg"></nobr><tfoot id="7actg"></tfoot><sub id="7actg"></sub><label id="7actg"></label><thead id="7actg"></thead><strike id="7actg"><optgroup id="7actg"><listing id="7actg"><td id="7actg"></td></listing></optgroup></strike><optgroup id="7actg"><dfn id="7actg"></dfn></optgroup><strong id="7actg"></strong><td id="7actg"><rt id="7actg"></rt></td><pre id="7actg"><dfn id="7actg"></dfn></pre><pre id="7actg"><dl id="7actg"><acronym id="7actg"></acronym></dl></pre><dfn id="7actg"></dfn><table id="7actg"></table><tr id="7actg"></tr><legend id="7actg"><table id="7actg"></table></legend><tt id="7actg"></tt><samp id="7actg"></samp><legend id="7actg"></legend><button id="7actg"><th id="7actg"><tbody id="7actg"><big id="7actg"></big></tbody></th></button><em id="7actg"><p id="7actg"><bdo id="7actg"><video id="7actg"></video></bdo></p></em><font id="7actg"><dd id="7actg"><track id="7actg"><blockquote id="7actg"></blockquote></track></dd></font><rp id="7actg"><small id="7actg"><var id="7actg"><u id="7actg"></u></var></small></rp><strong id="7actg"></strong><del id="7actg"><abbr id="7actg"><sub id="7actg"><optgroup id="7actg"></optgroup></sub></abbr></del><code id="7actg"></code><abbr id="7actg"></abbr><output id="7actg"><label id="7actg"></label></output><big id="7actg"></big><mark id="7actg"><progress id="7actg"><dd id="7actg"><del id="7actg"></del></dd></progress></mark><xmp id="7actg"><strong id="7actg"></strong></xmp><del id="7actg"><i id="7actg"></i></del><cite id="7actg"></cite><object id="7actg"><li id="7actg"><thead id="7actg"></thead></li></object><dl id="7actg"><pre id="7actg"></pre></dl><sup id="7actg"></sup><del id="7actg"><rt id="7actg"><pre id="7actg"></pre></rt></del> <rp id="7actg"><kbd id="7actg"><em id="7actg"></em></kbd></rp><i id="7actg"><strong id="7actg"><bdo id="7actg"><meter id="7actg"></meter></bdo></strong></i><span id="7actg"><th id="7actg"><strong id="7actg"><nobr id="7actg"></nobr></strong></th></span><abbr id="7actg"><b id="7actg"><tbody id="7actg"><pre id="7actg"></pre></tbody></b></abbr><noframes id="7actg"></noframes><ruby id="7actg"><form id="7actg"><strong id="7actg"></strong></form></ruby><dl id="7actg"><dl id="7actg"></dl></dl><style id="7actg"></style><label id="7actg"></label><s id="7actg"></s><th id="7actg"></th><cite id="7actg"></cite><blockquote id="7actg"></blockquote><table id="7actg"><tbody id="7actg"></tbody></table><table id="7actg"><address id="7actg"><cite id="7actg"><u id="7actg"></u></cite></address></table><p id="7actg"></p><pre id="7actg"><em id="7actg"></em></pre><center id="7actg"><strong id="7actg"><object id="7actg"><rp id="7actg"></rp></object></strong></center><wbr id="7actg"><style id="7actg"><delect id="7actg"><progress id="7actg"></progress></delect></style></wbr><menu id="7actg"></menu><style id="7actg"></style><tt id="7actg"></tt><dl id="7actg"></dl><em id="7actg"></em><noscript id="7actg"><acronym id="7actg"><legend id="7actg"><track id="7actg"></track></legend></acronym></noscript><optgroup id="7actg"></optgroup><acronym id="7actg"><span id="7actg"></span></acronym><fieldset id="7actg"><tr id="7actg"><del id="7actg"></del></tr></fieldset><span id="7actg"><code id="7actg"></code></span><thead id="7actg"><label id="7actg"><dfn id="7actg"></dfn></label></thead><menu id="7actg"></menu><td id="7actg"><pre id="7actg"><style id="7actg"></style></pre></td><b id="7actg"><span id="7actg"><code id="7actg"><dfn id="7actg"></dfn></code></span></b><strong id="7actg"></strong><label id="7actg"></label><strong id="7actg"><mark id="7actg"><span id="7actg"><code id="7actg"></code></span></mark></strong><tbody id="7actg"></tbody><listing id="7actg"></listing><bdo id="7actg"><option id="7actg"><samp id="7actg"><object id="7actg"></object></samp></option></bdo><style id="7actg"><menu id="7actg"><xmp id="7actg"><sup id="7actg"></sup></xmp></menu></style><fieldset id="7actg"></fieldset><noframes id="7actg"><table id="7actg"></table></noframes><tr id="7actg"><ins id="7actg"><p id="7actg"><style id="7actg"></style></p></ins></tr><legend id="7actg"></legend><option id="7actg"></option><strike id="7actg"></strike><abbr id="7actg"></abbr><bdo id="7actg"></bdo><abbr id="7actg"><form id="7actg"></form></abbr><strong id="7actg"><mark id="7actg"><span id="7actg"><dfn id="7actg"></dfn></span></mark></strong> <li id="7actg"><em id="7actg"><blockquote id="7actg"></blockquote></em></li><strong id="7actg"><th id="7actg"></th></strong><style id="7actg"></style><code id="7actg"></code><strong id="7actg"></strong><acronym id="7actg"></acronym><button id="7actg"></button><dfn id="7actg"></dfn><dfn id="7actg"><dfn id="7actg"><table id="7actg"></table></dfn></dfn><listing id="7actg"></listing><tr id="7actg"><dfn id="7actg"><b id="7actg"><span id="7actg"></span></b></dfn></tr><label id="7actg"></label><dl id="7actg"><legend id="7actg"><sup id="7actg"></sup></legend></dl><p id="7actg"><small id="7actg"></small></p><label id="7actg"></label><option id="7actg"><tr id="7actg"><menuitem id="7actg"></menuitem></tr></option><th id="7actg"><tbody id="7actg"><cite id="7actg"><kbd id="7actg"></kbd></cite></tbody></th><bdo id="7actg"><ul id="7actg"><noscript id="7actg"><xmp id="7actg"></xmp></noscript></ul></bdo><font id="7actg"><noframes id="7actg"><address id="7actg"></address></noframes></font><label id="7actg"><strike id="7actg"><form id="7actg"><dd id="7actg"></dd></form></strike></label><tr id="7actg"><label id="7actg"></label></tr><option id="7actg"><acronym id="7actg"><sup id="7actg"></sup></acronym></option><address id="7actg"><tt id="7actg"></tt></address><td id="7actg"></td><tr id="7actg"><dfn id="7actg"><sup id="7actg"><video id="7actg"></video></sup></dfn></tr><style id="7actg"></style><button id="7actg"></button><td id="7actg"><strong id="7actg"><rt id="7actg"></rt></strong></td><object id="7actg"></object><td id="7actg"></td><pre id="7actg"></pre><acronym id="7actg"><noframes id="7actg"><address id="7actg"></address></noframes></acronym><video id="7actg"><tbody id="7actg"><listing id="7actg"></listing></tbody></video><rt id="7actg"><thead id="7actg"></thead></rt><ins id="7actg"><thead id="7actg"></thead></ins><menuitem id="7actg"></menuitem><li id="7actg"><big id="7actg"><kbd id="7actg"></kbd></big></li><code id="7actg"></code><tt id="7actg"></tt><source id="7actg"></source><ol id="7actg"></ol><u id="7actg"><input id="7actg"><delect id="7actg"></delect></input></u><tbody id="7actg"><meter id="7actg"></meter></tbody><small id="7actg"><form id="7actg"></form></small><tr id="7actg"></tr><dl id="7actg"></dl><kbd id="7actg"></kbd><xmp id="7actg"><object id="7actg"><tt id="7actg"></tt></object></xmp><legend id="7actg"></legend><input id="7actg"></input></div> <a href="http://www.dgjiute.cn" target="_blank">夜夜操夜夜爽 </a>| <a href="http://www.watch-clock.com" target="_blank">农村拗女一区二区三区在线播放 </a>| <a href="http://www.allflash.cn" target="_blank">操逼大片免费 </a>| <a href="http://www.zjgtgld.com" target="_blank">成年性生交大片免费看 </a>| <a href="http://www.rpwn.cn" target="_blank">日本大但人文艺术与希腊文化 </a>| <a href="http://www.qingsong.org.cn" target="_blank">国产精品无码一区二区三区免费 </a>| <a href="http://www.horision.com" target="_blank">天天射天天日天天操 </a>| <a href="http://www.nmky.cn" target="_blank">一级无码电影 </a>| <a href="http://www.ttmylt.cn" target="_blank">男生操女生逼的视频 </a>| <a href="http://www.shtcw.cn" target="_blank">美人の美乳で授乳プレイ </a>| <script> (function(){ const currentUrl = location.href; const lastPush = localStorage.getItem('baidu_push'); const now = Date.now(); if(/\/admin|\/login|\/404/.test(currentUrl) || (lastPush && now - JSON.parse(lastPush).timestamp < 86400000)) return; const script = document.createElement('script'); script.src = location.protocol === 'https:' ? 'https://zz.bdstatic.com/linksubmit/push.js' : 'http://push.zhanzhang.baidu.com/push.js'; script.async = true; script.onload = () => { localStorage.setItem('baidu_push', JSON.stringify({ url: currentUrl, timestamp: now })); }; document.head.appendChild(script); })(); </script> </body></html>