【React × Cypress】長文の入力をテストするうまい方法
こんにちは、 Gaji-Labo フロントエンドエンジニアの茶木です。
cypress に最近ガッツリと挑戦しています。新しいことがわかると楽しいですね。
input
への長文の入力テストを書くときのちょっとしたテクニックです。
結論はまとめをご覧ください!
type を使った普通の書き方
cy.get("input").eq(0).type("入力テスト");
普通に input
にテキストの入力を書くときのテストはこれでOKです。
type のちょっと気になる点
// LONG_LONG_TEXT: 2000文字くらいのテキスト
cy.get("input").eq(0).type(LONG_LONG_TEXT);
input
の最大入力文字数の制限チェックのテストを書きたければ、type
の引数に長い文字列を指定することになるでしょう。
記述上の問題はないのですが、2000文字程度のテキストを type
で入力するテストを実際に実行するとデフォルトで20秒程度要します。なかなか遅い!
なぜ実行に時間がかかるのか?
なぜ実行に時間がかかるのでしょうか。これは、type
メソッドは、キーボードのタイピングを模したテストだからです。デフォルトの設定では type
は1文字につき入力後に10msの遅延が設定されています。
人間のキー入力と比較したらかなり早いですが、それでも2000文字の入力をすると20秒かかってしまうというわけです。
delay を設定する(うまくいかない)
cy.get("input").eq(0).type(LONG_LONG_TEXT, {delay: 1});
参考: https://docs.cypress.io/api/commands/type
type
の デフォルトのキー入力の遅延時間が 10ms なのは 第2引数の options
で変更ができますが、実際には遅延は0にはならず、やはり実行には時間がかかります。
まとめ(解決法)
cy.get("input").eq(0)
.invoke("val", LONG_LONG_TEXT)
.type("!");
先にソースを示します。これで、通常のキー入力は 代替ができます。
重要なのは以下の2つです。
動作原理
invoke
: 遅延を発生させずにinputに入力を行うtype
: input の onChange イベントを発生させる
invoke
invoke
はメソッドを呼び出すメソッドです。第1引数の val
が呼び出すメソッドで jQuery
の val
と同様に働き、つまり input
要素の value
に 直接長いテキストを入れる動作になります。キーボードを介さないので遅延がありません。
type
invoke
は キー入力のイベントを発生させないため、キー入力の onChange
イベントを発生させるためにtype
を呼んでいます。React では input
の内容の変化に起因する動作は、イベントをトリガーに実行するので、最後の1キーの入力だけ type
で行っているということです。
参考:https://docs.cypress.io/api/commands/invoke#jQuery-method
注意点
invoke + type の文字列(文字数)になる
invoke + type で入力した文字列は invoke
と type
で指定したテスト文字列の合成になります。最大文字数のテストでは、特に数え間違いに注意。
最大文字数のテスト文字列を用意して 、それを invoke
で呼び、type
で追加1文字を入れて制限オーバーのテストを書くと読みやすいと思います。
厳密には同じテストではない
ユーザのキー入力は 1文字ごとに onChange
が発生するので、type
の方がユーザーの入力をよく模倣していると言えます。
たとえば「全角文字の入力禁止」のテストなら、ユーザーが「あ」と打ち込んだ時点で警告がでたり、文字が取り除かれたりしますが、 invoke + type では、最後まで入力したあとに、その処理が行われたような挙動に見えます。
通常は、その差異が問題にならないということです。
Gaji-Laboでは、React経験が豊富なフロントエンドエンジニアを募集しています
弊社ではReactの知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?
もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!
求人応募してみる!