SlideShare uma empresa Scribd logo
1 de 56
Baixar para ler offline
1 <AboutMe
2 name="穴井宏幸"
3 handleName="@pirosikick"
4 titles={[
5 "ヤフー株式会社 第6・7代黒帯(JavaScript)",
6 "リッチラボ株式会社 エンジニア"
7 ]}
8 home="福岡"
9 />
1 <about-me
2 name="穴井宏幸"
3 handle-name="@pirosikick"
4 :titles="[
5 'ヤフー株式会社 第6・7代黒帯(JavaScript)',
6 'リッチラボ株式会社 エンジニア'
7 ]"
8 home="福岡"
9 >






1 // SomeComponent.spec.js
2 import test from 'ava';
3 import sinon from 'sinon';
4 import React from 'react';
5 import Enzyme, { shallow } from 'enzyme';
6 import Adapter from 'enzyme-adapter-react-16';
7
8 import SomeComponent from './SomeComponent';
9
10 // Reactのバージョンによってアダプタを変える
11 // 本来はavaのrequireで設定したほうがよい
12 Enzyme.configure({
13 adapter: new Adapter()
14 });
15
16 test('SomeComponent', t => {
17 // 描画したコンポーネントをラップしたものを返す
18 const wrapper = shallow(<SomeComponent />);
19
20 // ...テストケースを記述する...
21 });
1 // CSSセレクタで探す
2 t.true(wrapper.find('.some-class').exists());
3 // コンポーネント名で探す
4 t.deepEqual(
5 wrapper.find('OtherComponent').at(0).props(),
6 { no: 1 }
7 );
8 // 子要素
9 t.true(wrapper.childAt(1).is('OtherComponent'));
10
11 // propsの再設定
12 const onClick = sinon.spy();
13 wrapper.setProps({ onClick });
14
15 // イベントの再現
16 wrapper.find('.button').simulate('click');
17 t.true(onClick.calledOnce);
1 // someComponent.spec.js
2 import test from 'ava';
3 import { shallow } from '@vue/test-utils';
4
5 import someComponent from './someComponent.vue';
6 import otherComponent from './otherComponent.vue';
7
8 test('someComponent', t => {
9 // 描画したコンポーネントをラップしたものを返す
10 const wrapper = shallow(someComponent, {
11 propsData: {/* props */}
12 });
13
14 // ...テストケースを記述する...
15 });
1 // CSSセレクタで探す
2 t.true(wrapper.find('.some-class').exists());
3 // コンポーネントで探す
4 t.deepEqual(
5 wrapper.findAll(otherComponent).at(0).props(),
6 { no: 1 }
7 );
8 // 子要素
9 // @vut/test-utilsは子要素の取得はできない?
10
11 // コンポーネントが保持している値の更新
12 wrapper.setProps({/* ... */});
13 wrapper.setData({/* ... */});
14
15 // イベントの再現
16 wrapper.find('.button').trigger('click');
17 // コンポーネントが$emit('clicked')したか
18 t.is(wrapper.emitted().clicked.length, 1);




1 // CustomField.spec.js
2 import ...
3 import CustomField from './CustomField';
4
5 test('render ObjectField', t => {
6 const props = {
7 schema: {
8 type: "array",
9 items: {
10 image: { ... },
11 link: { ... }
12 }
13 },
14 formData: [ ... ]
15 };
16 const wrapper = shallow(<CustomField {...props} />);
17
18 t.true(wrapper.find('ObjectField').exists());
19 });
1 // CustomField.js
2 import ObjectField from 'react-jsonschema-form/...';
3
4 export default function CustomField({
5 schema,
6 formData
7 }) {
8 return <ObjectField />;
9 }
10
1 // アサーションを追加
2 // ObjectFieldに渡すpropsの検証
3 t.deepEqual(
4 wrapper.find('ObjectField').props(),
5 {
6 schema: props.schema.items,
7 formData: props.formData[0]
8 }
9 );
1 // CustomField.js
2 import ObjectField from 'react-jsonschema-form/...';
3
4 export default function CustomField({
5 schema,
6 formData
7 }) {
8 return (
9 <ObjectField
10 schema={schema.items}
11 formData={formData[0]}
12 />
13 );
14 }
1 // CustomField.spec.js
2 // テストケースを追加
3 test(`call onChange with new data
4 if ObjectField is changed`, t => {
5 const props = {
6 schema: { ... },
7 formData: [ ... ],
8 onChange: sinon.spy()
9 };
10 const wrapper = shallow(<CustomField {...props} />);
11
12 // ObjectField is changed
13 wrapper.find('ObjectField').props().onChange({ ... })
14
15 // call onChange with new data
16 t.true(props.onChange.calledOnce);
17 t.deepEqual(props.onChange.args[0], [ ... ]);
18 })
1 // CustomField.js
2 import ObjectField from 'react-jsonschema-form/...';
3
4 export default function CustomField({
5 schema,
6 formData,
7 onChange
8 }) {
9 return (
10 <ObjectField
11 schema={schema.items}
12 formData={formData[0]}
13 onChange={data => {
14 onChange([data, ...formData.slice(1)]);
15 })
16 />
17 );
18 }














1 // 実装
2 <Button data-testid="add-btn">追加</Button>
3 <Button data-testid="remove-btn">削除</Button>
4
5 // テスト
6 // セレクタや並び順では変更に弱い
7 // const rmeoveButton = wrapper.find('Button').at(1);
8 // カスタムデータ属性を使う
9 const removeButton
10 = wrapper.find('[data-testid="remove-btn"]');
11
12 // ヘルパーを作っておくと便利
13 const findByTestId = (wrapper, testid) =>
14 wrapper.find(`[data-testid="${testid}"]`);
1 <!--
2 someComponent.vue
3 - otherComponentはslot(子要素)を受け取れる
4 -->
5 <template>
6 <other-component>
7 <div class="slot-contents"></div>
8 </other-component>
9 </template>
1 // someComponent.spec.js
2 // shallowでは子コンポーネントがスタブされる
3 const wrapper = shallow(someComponent);
4 // slotは描画されないので以下は失敗する
5 t.true(wrapper.find('.slot-contents').exists();
6
7 // mountならうまくいく
8 const wrapper = mount(someComponent);
9 t.true(wrapper.find('.slot-contents').exists();
1 <!-- someComponent.vue -->
2 <template>
3 ...
4 <div class="mounted">
5 {{ isMounted ? 'mounted!' : 'not mounted' }}
6 </div>
7 </template>
8 <script>
9 export default {
10 data () {
11 return { isMounted: false }
12 },
13 mounted () {
14 // shallowでも呼ばれる
15 this.isMounted = true
16 }
17 }
18 </script>
1 // someComponent.spec.js
2 // mountedは呼ばれるがtemplateは更新されていない
3 // 以下は全て通る
4 t.true(wrapper.vm.isMounted);
5 t.is(wrapper.find('.mounted').text(), 'not mounted');
6
7 // updateを実行するとtemplateに反映される
8 wrapper.update();
9 t.is(wrapper.find('.mounted').text(), 'mounted!!');














Inside Frontend 2 #insideFE

Mais conteúdo relacionado

Mais procurados

T sql の parse と generator
T sql の parse と generatorT sql の parse と generator
T sql の parse と generatorOda Shinsuke
 
アップルのテンプレートは有害と考えられる
アップルのテンプレートは有害と考えられるアップルのテンプレートは有害と考えられる
アップルのテンプレートは有害と考えられるBrian Gesiak
 
Javaセキュアコーディングセミナー東京第3回演習の解説
Javaセキュアコーディングセミナー東京第3回演習の解説Javaセキュアコーディングセミナー東京第3回演習の解説
Javaセキュアコーディングセミナー東京第3回演習の解説JPCERT Coordination Center
 
Development app-with-elixir
Development app-with-elixirDevelopment app-with-elixir
Development app-with-elixirk1complete
 
オープンソースでExcelレポートプログラミング
オープンソースでExcelレポートプログラミングオープンソースでExcelレポートプログラミング
オープンソースでExcelレポートプログラミングSho Okada
 
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」Tsuyoshi Yamamoto
 
TypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめTypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめYu Nobuoka
 
Laravel勉強会(データベーステスト編)
Laravel勉強会(データベーステスト編)Laravel勉強会(データベーステスト編)
Laravel勉強会(データベーステスト編)AyakaNishiyama
 
xUnit Test Patterns - Chapter19
xUnit Test Patterns - Chapter19xUnit Test Patterns - Chapter19
xUnit Test Patterns - Chapter19Takuto Wada
 
Composable Callbacks & Listeners
Composable Callbacks & ListenersComposable Callbacks & Listeners
Composable Callbacks & ListenersTaisuke Oe
 
Introduction to Continuous Test Runner MakeGood
Introduction to Continuous Test Runner MakeGoodIntroduction to Continuous Test Runner MakeGood
Introduction to Continuous Test Runner MakeGoodAtsuhiro Kubo
 
from old Java to modern Java
from old Java to modern Javafrom old Java to modern Java
from old Java to modern Java心 谷本
 
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Java8 コーディングベストプラクティス and NetBeansのメモリログから...Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Java8 コーディングベストプラクティス and NetBeansのメモリログから...なおき きしだ
 
Java scriptによるテスト駆動開発
Java scriptによるテスト駆動開発Java scriptによるテスト駆動開発
Java scriptによるテスト駆動開発Hidekazu Nakamura
 
CPANの依存モジュールをもう少し正しく検出したい
CPANの依存モジュールをもう少し正しく検出したいCPANの依存モジュールをもう少し正しく検出したい
CPANの依存モジュールをもう少し正しく検出したいcharsbar
 
Javaセキュアコーディングセミナー東京第3回演習
Javaセキュアコーディングセミナー東京第3回演習Javaセキュアコーディングセミナー東京第3回演習
Javaセキュアコーディングセミナー東京第3回演習JPCERT Coordination Center
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門kwatch
 
2017年夏のPerl
2017年夏のPerl2017年夏のPerl
2017年夏のPerlcharsbar
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8y_taka_23
 
Qunit再入門 (Version 1.10.0 編)
Qunit再入門 (Version 1.10.0 編)Qunit再入門 (Version 1.10.0 編)
Qunit再入門 (Version 1.10.0 編)Koji Nakamura
 

Mais procurados (20)

T sql の parse と generator
T sql の parse と generatorT sql の parse と generator
T sql の parse と generator
 
アップルのテンプレートは有害と考えられる
アップルのテンプレートは有害と考えられるアップルのテンプレートは有害と考えられる
アップルのテンプレートは有害と考えられる
 
Javaセキュアコーディングセミナー東京第3回演習の解説
Javaセキュアコーディングセミナー東京第3回演習の解説Javaセキュアコーディングセミナー東京第3回演習の解説
Javaセキュアコーディングセミナー東京第3回演習の解説
 
Development app-with-elixir
Development app-with-elixirDevelopment app-with-elixir
Development app-with-elixir
 
オープンソースでExcelレポートプログラミング
オープンソースでExcelレポートプログラミングオープンソースでExcelレポートプログラミング
オープンソースでExcelレポートプログラミング
 
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
「Grails-1.1を斬る!〜Grails-1.1からのチーム開発〜」
 
TypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめTypeScript 言語処理系ことはじめ
TypeScript 言語処理系ことはじめ
 
Laravel勉強会(データベーステスト編)
Laravel勉強会(データベーステスト編)Laravel勉強会(データベーステスト編)
Laravel勉強会(データベーステスト編)
 
xUnit Test Patterns - Chapter19
xUnit Test Patterns - Chapter19xUnit Test Patterns - Chapter19
xUnit Test Patterns - Chapter19
 
Composable Callbacks & Listeners
Composable Callbacks & ListenersComposable Callbacks & Listeners
Composable Callbacks & Listeners
 
Introduction to Continuous Test Runner MakeGood
Introduction to Continuous Test Runner MakeGoodIntroduction to Continuous Test Runner MakeGood
Introduction to Continuous Test Runner MakeGood
 
from old Java to modern Java
from old Java to modern Javafrom old Java to modern Java
from old Java to modern Java
 
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Java8 コーディングベストプラクティス and NetBeansのメモリログから...Java8 コーディングベストプラクティス and NetBeansのメモリログから...
Java8 コーディングベストプラクティス and NetBeansのメモリログから...
 
Java scriptによるテスト駆動開発
Java scriptによるテスト駆動開発Java scriptによるテスト駆動開発
Java scriptによるテスト駆動開発
 
CPANの依存モジュールをもう少し正しく検出したい
CPANの依存モジュールをもう少し正しく検出したいCPANの依存モジュールをもう少し正しく検出したい
CPANの依存モジュールをもう少し正しく検出したい
 
Javaセキュアコーディングセミナー東京第3回演習
Javaセキュアコーディングセミナー東京第3回演習Javaセキュアコーディングセミナー東京第3回演習
Javaセキュアコーディングセミナー東京第3回演習
 
PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門PHP5.5新機能「ジェネレータ」初心者入門
PHP5.5新機能「ジェネレータ」初心者入門
 
2017年夏のPerl
2017年夏のPerl2017年夏のPerl
2017年夏のPerl
 
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
思ったほど怖くない! Haskell on JVM 超入門 #jjug_ccc #ccc_l8
 
Qunit再入門 (Version 1.10.0 編)
Qunit再入門 (Version 1.10.0 編)Qunit再入門 (Version 1.10.0 編)
Qunit再入門 (Version 1.10.0 編)
 

Semelhante a Inside Frontend 2 #insideFE

React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDEdcubeio
 
Sencha ug3 siesta_share
Sencha ug3 siesta_shareSencha ug3 siesta_share
Sencha ug3 siesta_share久司 中村
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについてtako pons
 
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)Fujio Kojima
 
Neo4j の「データ操作プログラミング」から 「ビジュアライズ」まで
Neo4j の「データ操作プログラミング」から 「ビジュアライズ」までNeo4j の「データ操作プログラミング」から 「ビジュアライズ」まで
Neo4j の「データ操作プログラミング」から 「ビジュアライズ」までKeiichiro Seida
 
Jenkins plugin memo
Jenkins plugin memoJenkins plugin memo
Jenkins plugin memoKiyotaka Oku
 
Angular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overviewAngular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overviewMitsuru Ogawa
 
イマドキの現場で使えるJavaライブラリ事情
イマドキの現場で使えるJavaライブラリ事情イマドキの現場で使えるJavaライブラリ事情
イマドキの現場で使えるJavaライブラリ事情takezoe
 
Android test tutorial
Android test tutorialAndroid test tutorial
Android test tutorialKazuaki Ueda
 
分散ストリーム処理フレームワーク Apache S4
分散ストリーム処理フレームワーク Apache S4分散ストリーム処理フレームワーク Apache S4
分散ストリーム処理フレームワーク Apache S4AdvancedTechNight
 
traceur-compilerで ECMAScript6を体験
traceur-compilerで ECMAScript6を体験traceur-compilerで ECMAScript6を体験
traceur-compilerで ECMAScript6を体験Toshio Ehara
 
From Swing to JavaFX - SwingからJavaFXへのマイグレーションガイド
From Swing to JavaFX  - SwingからJavaFXへのマイグレーションガイドFrom Swing to JavaFX  - SwingからJavaFXへのマイグレーションガイド
From Swing to JavaFX - SwingからJavaFXへのマイグレーションガイドYuichi Sakuraba
 
Ibm worklight デモ環境とサンプルコード
Ibm worklight デモ環境とサンプルコードIbm worklight デモ環境とサンプルコード
Ibm worklight デモ環境とサンプルコードK Kimura
 
勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration勉強会force#4 Chatter Integration
勉強会force#4 Chatter IntegrationKazuki Nakajima
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用Yatabe Terumasa
 
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみたYuki Takei
 
ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9
ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9
ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9Saiki Iijima
 

Semelhante a Inside Frontend 2 #insideFE (20)

React Native GUIDE
React Native GUIDEReact Native GUIDE
React Native GUIDE
 
Java EE8 Report
Java EE8 ReportJava EE8 Report
Java EE8 Report
 
test
testtest
test
 
Sencha ug3 siesta_share
Sencha ug3 siesta_shareSencha ug3 siesta_share
Sencha ug3 siesta_share
 
Apache Torqueについて
Apache TorqueについてApache Torqueについて
Apache Torqueについて
 
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)「Windows 8 ストア アプリ開発 tips」  hokuriku.net vol.11 (2013年1月26日)
「Windows 8 ストア アプリ開発 tips」 hokuriku.net vol.11 (2013年1月26日)
 
Neo4j の「データ操作プログラミング」から 「ビジュアライズ」まで
Neo4j の「データ操作プログラミング」から 「ビジュアライズ」までNeo4j の「データ操作プログラミング」から 「ビジュアライズ」まで
Neo4j の「データ操作プログラミング」から 「ビジュアライズ」まで
 
Jenkins plugin memo
Jenkins plugin memoJenkins plugin memo
Jenkins plugin memo
 
Try Jetpack
Try JetpackTry Jetpack
Try Jetpack
 
Angular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overviewAngular2 rc.1 unit testing overview
Angular2 rc.1 unit testing overview
 
イマドキの現場で使えるJavaライブラリ事情
イマドキの現場で使えるJavaライブラリ事情イマドキの現場で使えるJavaライブラリ事情
イマドキの現場で使えるJavaライブラリ事情
 
Android test tutorial
Android test tutorialAndroid test tutorial
Android test tutorial
 
分散ストリーム処理フレームワーク Apache S4
分散ストリーム処理フレームワーク Apache S4分散ストリーム処理フレームワーク Apache S4
分散ストリーム処理フレームワーク Apache S4
 
traceur-compilerで ECMAScript6を体験
traceur-compilerで ECMAScript6を体験traceur-compilerで ECMAScript6を体験
traceur-compilerで ECMAScript6を体験
 
From Swing to JavaFX - SwingからJavaFXへのマイグレーションガイド
From Swing to JavaFX  - SwingからJavaFXへのマイグレーションガイドFrom Swing to JavaFX  - SwingからJavaFXへのマイグレーションガイド
From Swing to JavaFX - SwingからJavaFXへのマイグレーションガイド
 
Ibm worklight デモ環境とサンプルコード
Ibm worklight デモ環境とサンプルコードIbm worklight デモ環境とサンプルコード
Ibm worklight デモ環境とサンプルコード
 
勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用
 
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
 
ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9
ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9
ViewModel テスト難しすぎ問題 by saiki iijima in Android Test Night #9
 

Último

LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイスCRI Japan, Inc.
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Hiroshi Tomioka
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...Toru Tamaki
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Gamesatsushi061452
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。iPride Co., Ltd.
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptxsn679259
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルCRI Japan, Inc.
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsWSO2
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video UnderstandingToru Tamaki
 

Último (11)

LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
Observabilityは従来型の監視と何が違うのか(キンドリルジャパン社内勉強会:2022年10月27日発表)
 
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
論文紹介:Video-GroundingDINO: Towards Open-Vocabulary Spatio-Temporal Video Groun...
 
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
論文紹介: The Surprising Effectiveness of PPO in Cooperative Multi-Agent Games
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
知識ゼロの営業マンでもできた!超速で初心者を脱する、悪魔的学習ステップ3選.pptx
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
Utilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native IntegrationsUtilizing Ballerina for Cloud Native Integrations
Utilizing Ballerina for Cloud Native Integrations
 
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
論文紹介:Selective Structured State-Spaces for Long-Form Video Understanding
 

Inside Frontend 2 #insideFE

  • 1.
  • 2. 1 <AboutMe 2 name="穴井宏幸" 3 handleName="@pirosikick" 4 titles={[ 5 "ヤフー株式会社 第6・7代黒帯(JavaScript)", 6 "リッチラボ株式会社 エンジニア" 7 ]} 8 home="福岡" 9 />
  • 3. 1 <about-me 2 name="穴井宏幸" 3 handle-name="@pirosikick" 4 :titles="[ 5 'ヤフー株式会社 第6・7代黒帯(JavaScript)', 6 'リッチラボ株式会社 エンジニア' 7 ]" 8 home="福岡" 9 >
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19. 1 // SomeComponent.spec.js 2 import test from 'ava'; 3 import sinon from 'sinon'; 4 import React from 'react'; 5 import Enzyme, { shallow } from 'enzyme'; 6 import Adapter from 'enzyme-adapter-react-16'; 7 8 import SomeComponent from './SomeComponent'; 9 10 // Reactのバージョンによってアダプタを変える 11 // 本来はavaのrequireで設定したほうがよい 12 Enzyme.configure({ 13 adapter: new Adapter() 14 }); 15 16 test('SomeComponent', t => { 17 // 描画したコンポーネントをラップしたものを返す 18 const wrapper = shallow(<SomeComponent />); 19 20 // ...テストケースを記述する... 21 });
  • 20. 1 // CSSセレクタで探す 2 t.true(wrapper.find('.some-class').exists()); 3 // コンポーネント名で探す 4 t.deepEqual( 5 wrapper.find('OtherComponent').at(0).props(), 6 { no: 1 } 7 ); 8 // 子要素 9 t.true(wrapper.childAt(1).is('OtherComponent')); 10 11 // propsの再設定 12 const onClick = sinon.spy(); 13 wrapper.setProps({ onClick }); 14 15 // イベントの再現 16 wrapper.find('.button').simulate('click'); 17 t.true(onClick.calledOnce);
  • 21. 1 // someComponent.spec.js 2 import test from 'ava'; 3 import { shallow } from '@vue/test-utils'; 4 5 import someComponent from './someComponent.vue'; 6 import otherComponent from './otherComponent.vue'; 7 8 test('someComponent', t => { 9 // 描画したコンポーネントをラップしたものを返す 10 const wrapper = shallow(someComponent, { 11 propsData: {/* props */} 12 }); 13 14 // ...テストケースを記述する... 15 });
  • 22. 1 // CSSセレクタで探す 2 t.true(wrapper.find('.some-class').exists()); 3 // コンポーネントで探す 4 t.deepEqual( 5 wrapper.findAll(otherComponent).at(0).props(), 6 { no: 1 } 7 ); 8 // 子要素 9 // @vut/test-utilsは子要素の取得はできない? 10 11 // コンポーネントが保持している値の更新 12 wrapper.setProps({/* ... */}); 13 wrapper.setData({/* ... */}); 14 15 // イベントの再現 16 wrapper.find('.button').trigger('click'); 17 // コンポーネントが$emit('clicked')したか 18 t.is(wrapper.emitted().clicked.length, 1);
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29. 1 // CustomField.spec.js 2 import ... 3 import CustomField from './CustomField'; 4 5 test('render ObjectField', t => { 6 const props = { 7 schema: { 8 type: "array", 9 items: { 10 image: { ... }, 11 link: { ... } 12 } 13 }, 14 formData: [ ... ] 15 }; 16 const wrapper = shallow(<CustomField {...props} />); 17 18 t.true(wrapper.find('ObjectField').exists()); 19 });
  • 30. 1 // CustomField.js 2 import ObjectField from 'react-jsonschema-form/...'; 3 4 export default function CustomField({ 5 schema, 6 formData 7 }) { 8 return <ObjectField />; 9 } 10
  • 31. 1 // アサーションを追加 2 // ObjectFieldに渡すpropsの検証 3 t.deepEqual( 4 wrapper.find('ObjectField').props(), 5 { 6 schema: props.schema.items, 7 formData: props.formData[0] 8 } 9 );
  • 32. 1 // CustomField.js 2 import ObjectField from 'react-jsonschema-form/...'; 3 4 export default function CustomField({ 5 schema, 6 formData 7 }) { 8 return ( 9 <ObjectField 10 schema={schema.items} 11 formData={formData[0]} 12 /> 13 ); 14 }
  • 33.
  • 34. 1 // CustomField.spec.js 2 // テストケースを追加 3 test(`call onChange with new data 4 if ObjectField is changed`, t => { 5 const props = { 6 schema: { ... }, 7 formData: [ ... ], 8 onChange: sinon.spy() 9 }; 10 const wrapper = shallow(<CustomField {...props} />); 11 12 // ObjectField is changed 13 wrapper.find('ObjectField').props().onChange({ ... }) 14 15 // call onChange with new data 16 t.true(props.onChange.calledOnce); 17 t.deepEqual(props.onChange.args[0], [ ... ]); 18 })
  • 35. 1 // CustomField.js 2 import ObjectField from 'react-jsonschema-form/...'; 3 4 export default function CustomField({ 5 schema, 6 formData, 7 onChange 8 }) { 9 return ( 10 <ObjectField 11 schema={schema.items} 12 formData={formData[0]} 13 onChange={data => { 14 onChange([data, ...formData.slice(1)]); 15 }) 16 /> 17 ); 18 }
  • 37.
  • 38.
  • 39.
  • 41. 1 // 実装 2 <Button data-testid="add-btn">追加</Button> 3 <Button data-testid="remove-btn">削除</Button> 4 5 // テスト 6 // セレクタや並び順では変更に弱い 7 // const rmeoveButton = wrapper.find('Button').at(1); 8 // カスタムデータ属性を使う 9 const removeButton 10 = wrapper.find('[data-testid="remove-btn"]'); 11 12 // ヘルパーを作っておくと便利 13 const findByTestId = (wrapper, testid) => 14 wrapper.find(`[data-testid="${testid}"]`);
  • 42.
  • 43. 1 <!-- 2 someComponent.vue 3 - otherComponentはslot(子要素)を受け取れる 4 --> 5 <template> 6 <other-component> 7 <div class="slot-contents"></div> 8 </other-component> 9 </template> 1 // someComponent.spec.js 2 // shallowでは子コンポーネントがスタブされる 3 const wrapper = shallow(someComponent); 4 // slotは描画されないので以下は失敗する 5 t.true(wrapper.find('.slot-contents').exists(); 6 7 // mountならうまくいく 8 const wrapper = mount(someComponent); 9 t.true(wrapper.find('.slot-contents').exists();
  • 44. 1 <!-- someComponent.vue --> 2 <template> 3 ... 4 <div class="mounted"> 5 {{ isMounted ? 'mounted!' : 'not mounted' }} 6 </div> 7 </template> 8 <script> 9 export default { 10 data () { 11 return { isMounted: false } 12 }, 13 mounted () { 14 // shallowでも呼ばれる 15 this.isMounted = true 16 } 17 } 18 </script>
  • 45. 1 // someComponent.spec.js 2 // mountedは呼ばれるがtemplateは更新されていない 3 // 以下は全て通る 4 t.true(wrapper.vm.isMounted); 5 t.is(wrapper.find('.mounted').text(), 'not mounted'); 6 7 // updateを実行するとtemplateに反映される 8 wrapper.update(); 9 t.is(wrapper.find('.mounted').text(), 'mounted!!');
  • 46.
  • 47.
  • 48.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.