跳转到主要内容< / div >
版本:26.倍

Тестування з допомогою знімків

Тестуваннязвикористаннямзнімків——цедужекориснийінструмент,коливихочетебутипевні、щовашUIнезмінивсянесподівано。

一个典型的快照测试用例呈现一个UI组件,获取一个快照,然后将其与与测试一起存储的参考快照文件进行比较。如果两个快照不匹配,则测试将失败:更改是意外的,或者引用快照需要更新到UI组件的新版本。

Тестування знімками з笑话<一个class="hash-link" href="#тестування-знімками-з-jest" title="#”>#

Аналогічнийпідіхідможебутивикористано,колизаходитьмовапротестування反应компонентів。ЗамістьрендеругрфічногоUI,щоможевимагатизбираннявсьогододатку,виможетевикористатитестовийрендерер,щобшвидкозгенеруватидеревокомпонентів反应,якеможнасеріалізувати。考虑一下这个<一个href="https://github.com/facebook/jest/blob/master/examples/snapshot/__tests__/link.react.test.js" target="_blank" rel="noopener noreferrer">示例测试对于一个<一个href="https://github.com/facebook/jest/blob/master/examples/snapshot/Link.react.js" target="_blank" rel="noopener noreferrer">连接组件:

进口 反应 “反应” ;
进口 渲染器 “react-test-renderer” ;
进口 链接 “. . / Link.react” ;
( 显示正确的 , ( ) = > {
常量 = 渲染器
创建 ( < 链接 页面 = http://www.facebook.com > 脸谱网 链接 > )
toJSON ( ) ;
预计 ( ) toMatchSnapshot ( ) ;
} ) ;

Під час першого запуску цього тесту,笑话створює<一个href="https://github.com/facebook/jest/blob/master/examples/snapshot/__tests__/__snapshots__/link.react.test.js.snap" target="_blank" rel="noopener noreferrer">снепшотфайл, який виглядає наступним чином:

出口 ( 正确显示1 ] =
<一个
className = "正常"
href = " http://www.facebook.com "
onMouseEnter ={[功能]}
onMouseLeave ={[功能]}
>
脸谱网
< / >
;

Знімокповиненбутидоданийдосистемиконролюверсійразомзізмінамикоду、щодозволитьпереглянутийоговпроцесі代码评审。Jestвикористовує<一个href="https://github.com/facebook/jest/tree/master/packages/pretty-format" target="_blank" rel="noopener noreferrer">格式,щобзробитизнімкизручнимидлячитаняпідчас代码复审。在随后的测试运行中,Jest将将呈现的输出与前一个快照进行比较。Якщо вони співпадуть, тест пройде。如果它们不匹配,要么测试运行程序在您的代码中发现了一个bug(在<链接>组件),或者实现已经更改,需要更新快照。

注意:快照直接作用于您呈现的数据-在我们的示例中<链接/ >组件页面道具传给了它。这意味着即使任何其他文件缺少支持(例如,App.js)<链接/ >组件,它仍然会通过测试,因为测试不知道的用法<链接/ >组件,它的作用域仅为Link.react.js。另外,在其他快照测试中使用不同的道具呈现同一个组件不会影响第一个组件,因为这些测试彼此都不知道。

Більшеінформаціїпроте,якпрацюєтестуваннязнімкамиможназнайтив<一个href="//www.ieatrice.com/blog/2016/07/27/jest-14.html" target="_blank" rel="noopener noreferrer">блогпості。Мирекомендуємопрочитати<一个href="http://benmccormick.org/2016/09/19/testing-with-jest-snapshots-first-impressions/" target="_blank" rel="noopener noreferrer">цейблогпост,щобзрозуміти,коливамвартовикористовуватитестуваннязнімками。Ми також рекомендуємо переглянути<一个href="https://egghead.io/lessons/javascript-use-jest-s-snapshot-testing-feature?pl=testing-javascript-with-jest-a36c4074" target="_blank" rel="noopener noreferrer">відеона书生气十足的人про тестування знімками з笑话。

Оновленнязнімків<一个class="hash-link" href="#оновлення-знімків" title="#”>#

Дужепростопомітити,колитестзвикористаннямзнімківпадаєпіслятого,якз”явиласяпомилкавкоді。Колитакетрапляється,простовиправтепомилкуіпереконайтеся,щовашітестизновупроходятьуспішно。Тепердавайтепоговоримопровипадок,колитестзізнімкомпадаєвнаслідокнавмисноїзміникоду。

Такаситуаціяможевиникнути,якщоминавмиснозмінимоадрес,унаякувказуєкомпонент链接знашогоприкладу。

//更新测试用例的链接到不同的地址
( 显示正确的 , ( ) = > {
常量 = 渲染器
创建 ( < 链接 页面 = http://www.instagram.com > Instagram 链接 > )
toJSON ( ) ;
预计 ( ) toMatchSnapshot ( ) ;
} ) ;

В цьому випадку Jest видасть наступний вивід:

Оскількимищойнооновилинашкомпонент,щобвінвказувавнаіншуадрес,улогічноочікуватизмінузнімкацьогокомпонента。Наштестзізнімкомпадає,оскількизнімокдляоновленогокомпонентабільшенеспівпадаєзізбереженимзнімкомдляцьоготеста。

要解决这个问题,我们需要更新我们的快照工件。你可以用一个标志运行Jest,它会告诉它重新生成快照:

笑话——updateSnapshot

Просто прийміть зміни запустивши команду вище。Ви також можете використати еквівалентий параметр- uдляперегенераціїзнімків。Цеперегенеруєзнімкидлявсіхтестів,яківпаличерезнеспівпадіннязнімків。Якбиунасбулитестизізнімками,якіпадаличерезпомилкувкоді、намвартобулобвиправитиціпроблемидоперегенераціїзнімків,щобзапобігтиствореннюзнімківдлянеправильноїповедінки。

Якщовихочетеобмежитисписоктестів,дляякихпотрібноперегенеруватизнімки,виможетевказатипараметр——testNamePattern,щобповторнозаписатизнімкитількидлятестів,яківідповідаютьвказаномушаблону。

Виможетеспробуватицейфункціонал,якщозклонуєте<一个href="https://github.com/facebook/jest/tree/master/examples/snapshot" target="_blank" rel="noopener noreferrer">прикладзізнімками,змінитекомпонент链接ізапустите笑话。

交互式快照模式<一个class="hash-link" href="#interactive-snapshot-mode" title="#”>#

失败的快照也可以在观察模式下交互更新:

一旦您进入交互式快照模式,Jest就会逐一介绍失败的快照测试,并让您有机会检查失败的输出。

从这里,你可以选择更新快照或跳过到下一个:

一旦你完成了,Jest会在返回观看模式之前给你一个总结:

内联快照<一个class="hash-link" href="#inline-snapshots" title="#”>#

内联快照的行为与外部快照相同(.snap文件),除了快照值会自动写回源代码。这意味着您可以获得自动生成快照的好处,而不必切换到外部文件以确保写入正确的值。

内嵌快照由<一个href = " https://prettier.io "target="_blank" rel="noopener noreferrer">更漂亮。要使用内嵌快照,您必须拥有更漂亮安装在您的项目中。在编写测试文件时,您的漂亮配置将受到尊重。

如果你有更漂亮安装在Jest无法找到它的位置,您可以告诉Jest如何使用<一个href="/uk/docs/configuration">“prettierPath”配置属性。

例子:

首先,您编写一个测试,调用.toMatchInlineSnapshot ()无参数:

( 显示正确的 , ( ) = > {
常量 = 渲染器
创建 ( < 链接 页面 = https://prettier.io > 更漂亮 链接 > )
toJSON ( ) ;
预计 ( ) toMatchInlineSnapshot ( ) ;
} ) ;

下次你再运行Jest,并将快照作为参数写入toMatchInlineSnapshot:

( 显示正确的 , ( ) = > {
常量 = 渲染器
创建 ( < 链接 页面 = https://prettier.io > 更漂亮 链接 > )
toJSON ( ) ;
预计 ( ) toMatchInlineSnapshot (
<一个
className = "正常"
href = " https://prettier.io "
onMouseEnter ={[功能]}
onMouseLeave ={[功能]}
>
更漂亮
< / >
) ;
} ) ;

就是这样!你甚至可以用——updateSnapshot或者使用u关键在——看模式。

财产匹配器<一个class="hash-link" href="#property-matchers" title="#”>#

通常在需要快照的对象中会生成一些字段(如id和日期)。如果尝试对这些对象进行快照,它们将强制快照在每次运行时失败:

( “每次都会失败” , ( ) = > {
常量 用户 = {
createdAt : 日期 ( ) ,
id : 数学 地板上 ( 数学 随机 ( ) * 20. ) ,
的名字 : “詹姆斯” ,
} ;
预计 ( 用户 ) toMatchSnapshot ( ) ;
} ) ;
/ /快照
出口 ( 每次都会失败吗 ] =
对象{
“createdAt”:2018 - 05 - 19 t23:36:09.816z
“id”:3,
“名称”:“詹姆斯”,
}
;

对于这些情况,Jest允许为任何属性提供不对称匹配器。这些匹配器在快照写入或测试之前被检查,然后保存到快照文件中,而不是接收到的值:

( '将检查匹配器并通过' , ( ) = > {
常量 用户 = {
createdAt : 日期 ( ) ,
id : 数学 地板上 ( 数学 随机 ( ) * 20. ) ,
的名字 : “詹姆斯” ,
} ;
预计 ( 用户 ) toMatchSnapshot ( {
createdAt : 预计 任何 ( 日期 ) ,
id : 预计 任何 ( 数量 ) ,
} ) ;
} ) ;
/ /快照
出口 ( 将检查匹配器和通过1 ] =
对象{
“createdAt”:任何<日期>,
“id”:任何<数字>,
“名称”:“詹姆斯”,
}
;

任何给定的非匹补器值都将被精确地检查并保存到快照中:

( '将检查值并通过' , ( ) = > {
常量 用户 = {
createdAt : 日期 ( ) ,
的名字 : “键…詹姆斯·邦德” ,
} ;
预计 ( 用户 ) toMatchSnapshot ( {
createdAt : 预计 任何 ( 日期 ) ,
的名字 : “键…詹姆斯·邦德” ,
} ) ;
} ) ;
/ /快照
出口 ( 是否检查值并通过1 ] =
对象{
“createdAt”:任何<日期>,
“名称”:“债券……詹姆斯•邦德”,
}
;

最佳实践<一个class="hash-link" href="#best-practices" title="#”>#

快照是识别应用程序中未预料到的接口变化的神奇工具——无论该接口是API响应、UI、日志还是错误消息。对于任何测试策略,都有一些您应该了解的最佳实践,以及您应该遵循的指导方针,以便有效地使用它们。

1.将快照视为代码<一个class="hash-link" href="#1-treat-snapshots-as-code" title="#”>#

提交快照并将其作为常规代码评审过程的一部分进行评审。这意味着要像对待项目中的任何其他类型的测试或代码一样对待快照。

确保你的快照是可读的,让它们集中,简短,并使用工具加强这些风格的约定。

如前所述,Jest使用<一个href="https://yarnpkg.com/en/package/pretty-format" target="_blank" rel="noopener noreferrer">格式为了使快照具有可读性,但是您可能会发现引入额外的工具很有用,例如<一个href="https://yarnpkg.com/en/package/eslint-plugin-jest" target="_blank" rel="noopener noreferrer">eslint-plugin-jest与它的<一个href="https://github.com/jest-community/eslint-plugin-jest/blob/master/docs/rules/no-large-snapshots.md" target="_blank" rel="noopener noreferrer">no-large-snapshots选项,或<一个href="https://yarnpkg.com/en/package/snapshot-diff" target="_blank" rel="noopener noreferrer">snapshot-diff其组件快照比较功能,以促进提交简短、有重点的断言。

这样做的目的是使在pull请求中检查快照变得更加容易,并克服在测试套件失败时重新生成快照而不是检查失败的根本原因的习惯。

2.测试应该是确定的<一个class="hash-link" href="#2-tests-should-be-deterministic" title="#”>#

Ваші тести повинні бути детерміновані。在未更改的组件上多次运行相同的测试,每次应该产生相同的结果。Вивідповідальнізате,щобвашізнімкиневключаливсебеспецифічнідляконкретноїплатформиабоіншінедетермінованідані。

Наприклад, якщо у вас є компонент<一个href="https://github.com/facebook/jest/blob/master/examples/snapshot/Clock.react.js" target="_blank" rel="noopener noreferrer">时钟,якийвикористовуєDate.now (),тознімок,згенерованийдляцьогокомпонента,будерізнийкожногоразупідчасзапускутеста。在这种情况下我们可以<一个href="/uk/docs/mock-functions">模拟Date.now()方法每次运行测试时返回一个一致的值:

日期 现在 = 开玩笑 fn ( ( ) = > 1482363367071 ) ;

Теперкожногоразу,підчасвиконаннятестузізнімком,Date.now ()повертатиме1482363367071。Цепризведедотого,щознімокбудеоднаковимзавжд,инезалежновідтого,колизапущенийтест。

3.使用描述性快照名称<一个class="hash-link" href="#3-use-descriptive-snapshot-names" title="#”>#

始终努力为快照使用描述性测试和/或快照名称。最好的名称描述预期的快照内容。这使得审查人员在审查期间更容易验证快照,并且任何人都可以在更新之前知道过期的快照是否是正确的行为。

例如,比较:

出口 ( 应该处理一些测试用例 ] = ;
出口 ( 应该处理一些其他的测试用例 ] =
< div >
阿兰·图灵
< / div >
;

:

出口 ( 应该渲染null ] = ;
出口 ( 应该渲染图灵 ] =
< div >
阿兰·图灵
< / div >
;

因为后者准确地描述了输出中所期望的内容,所以当它出错时,可以更清楚地看到:

出口 ( 应该渲染null ] =
< div >
阿兰·图灵
< / div >
;
出口 ( 应该渲染图灵 ] = ;

Частізапитання<一个class="hash-link" href="#часті-запитання" title="#”>#

快照是否在持续集成(CI)系统上自动写入?<一个class="hash-link" href="#are-snapshots-written-automatically-on-continuous-integration-ci-systems" title="#”>#

不,在Jest 20中,当Jest在CI系统中运行时,在没有显式传递的情况下,Jest中的快照不会自动写入——updateSnapshot。Очікується,щовсізнімки——цечастинакоду、якийвиконуєтьсянаCIітому,хочатестизновимизнімкиавтоматичнопроходять,вонинеповинніпроходитинаCI。Мирекомендуємозавждидодавативсізнімкивсистемуконтролюверсій。

Чи потрібно комітити снепшот файли?<一个class="hash-link" href="#чи-потрібно-комітити-снепшот-файли" title="#”>#

,Такусіфайлизізнімкамипотрібнододавативсистемуконтролюверсійразомізмодулями,яківонипокриваютьтаїхнімитестами。它们应该被视为测试的一部分,类似于Jest中的任何其他断言的值。Знімки відображають стан модулів на певний час。Такимчином,колимодулізмінюються,Jestможесказати,якізмінивідбулисяупорівняннізпопередньоюверсією。Вонитакожможутьнадатидодатковийконтекстдля代码评审,завдякичомурев”ювериможутькращезрозумітивнесенізміни。

Чиснепшотестуванняпрацюєтількидля反应компонентів?<一个class="hash-link" href="#чи-снепшо-тестування-працює-тільки-для-react-компонентів" title="#”>#

反应та<一个href="//www.ieatrice.com/uk/docs/tutorial-react-native">反应本地компоненти——цевдаліприкладидлятестуваннязнімками。Однак,знімкиможутьміститибудь——якесеріалізованезначенняіможутьвикористовуватисьбудь(де,деціллюєтестуваннятогочивихіднізначенняправильні。ВрепозиторіїJestєбагатоприкладівтестуваннявиводусамого开玩笑,виводубібліотекиствердженьJestідовгихповідомленьзрізнихчастинкодовоїбази笑话。Перегляньтеприклад<一个href="https://github.com/facebook/jest/blob/master/e2e/__tests__/console.test.ts" target="_blank" rel="noopener noreferrer">знімківконсольноговиводуврепозиторії笑话。

Якарізницяміжтестуваннямзнімкамитавізуальнимрегресивнимтестуванням吗?<一个class="hash-link" href="#яка-різниця-між-тестуванням-знімками-та-візуальним-регресивним-тестуванням" title="#”>#

Тестуваннязнімкамиівізуальнерегресивнетестування——цедварізніспособитестуванняUI,якіслугуютьрізнимцілям。Інструментивізуальногорегресивноготестуванняроблятьзнімкивебсторінокіпорівнюютьрезультатпіксельзапікселем。通过快照,测试值被序列化,存储在文本文件中,并使用diff算法进行比较。Існуютьрізнікомпромісидлярозглядуімиперерахувалипричини,чомутестуваннязнімкамибулостворено,в<一个href="//www.ieatrice.com/blog/2016/07/27/jest-14.html" target="_blank" rel="noopener noreferrer">блозі笑话

快照测试取代单元测试吗?<一个class="hash-link" href="#does-snapshot-testing-replace-unit-testing" title="#”>#

Тестуваннязнімками——целишеоднезбільшніж20тверджень,якінадає笑话。快照测试的目的不是取代现有的单元测试,而是提供额外的价值,使测试变得轻松。Вдеякихсценаріяхтестуваннязнімкамипотенційноможеприбратинеобхідністьюніттестуваннядляконкретногонаборуфункціональності(анприклад反应компонентів),алевониможутьчудовопрацюватиразом。

Якапродуктивністьтестуваннязнімкамистосовношвидкостіірозмірузгенерованихфайлів?<一个class="hash-link" href="#яка-продуктивність-тестування-знімками-стосовно-швидкості-і-розміру-згенерованих-файлів" title="#”>#

Jestбулопереписанозакцентомнашвидкодіюітестуваннязнімкаминевиключення。Оскількизнімкизберігаютьсявтекстовихфайлах,цейспосібтестуванняшвидкийінадійний。Jestгенеруєновийфайлдлякожногофайлузтестами,вякомувикористовуєтьсяматчерtoMatchSnapshot。快照的大小非常小:作为参考,Jest代码基本身中所有快照文件的大小都小于300 KB。

Як вирішувати конфлікти в файлах зі знімками?<一个class="hash-link" href="#як-вирішувати-конфлікти-в-файлах-зі-знімками" title="#”>#

Файлизізнімкамиповиннізавждипредставлятипоточнийстанмодулів,яківонипокривають。因此,如果您正在合并两个分支并在快照文件中遇到冲突,那么您可以手动解决冲突,或者通过运行Jest并检查结果来更新快照文件。

Чиможназастосовуватипринципирозробкичерезтестуваннязтестуваннямзнімками?<一个class="hash-link" href="#чи-можна-застосовувати-принципи-розробки-через-тестування-з-тестуванням-знімками" title="#”>#

Хочаііснуєможливістьписатифайлизнімківвручну、цевсежнедосяжно。快照有助于确定测试涵亚搏取款盖的模块的输出是否发生了更改,而不是在一开始就提供设计代码的指导。

代码覆盖率与快照测试一起工作吗?<一个class="hash-link" href="#does-code-coverage-work-with-snapshot-testing" title="#”>#

是的,和其他测试一样。