ぴよがち

技術的な話をします。みんなで強くなりましょう。

NXBTの便利スクリプト

環境設定編はこちら piyo-p.hatenablog.com

使い方

sshでラズパイに入り、適当にテキストファイルにマクロを保存して実行するのが良いかと思います。
(おま環かもですが、WebUIは3時間くらいマクロ回したら毎回落ちるため)

# sample.txt にマクロを保存する場合
vim /home/ubuntu/sample.txt
sudo /usr/bin/python3 /usr/local/bin/nxbt macro -c /home/ubuntu/sample.txt -r

スクリプト

無限A連打

LOOP 10000000
  A 0.025S
  0.025S

学校最高大会 2匹以上用

Bボタンで入れ替えダイアログを閉じます。
お金効率を犠牲に、レベル上げができます。

LOOP 100000
  LOOP 3
    A 0.1s
    0.6s
  B 0.1s
  0.6s

円を描いて歩く(タマゴ孵化・なつき上げ)

L_STICK@+000+100 R_STICK@-100+000 600s

無限競り

競りが終わるくらいまでAを連打して、
終わったころにレポートを書いてゲームを終了し、
Switchのホームに戻って日付を変えてゲームを再開します。

競りの人の目の前で開始してください。

LOOP 10000
  A 0.1S
  3S
  A 0.1S
  15S
  LOOP 100
    A 0.1S
    1S
  LOOP 8
    b 0.1S
    1S
  X 0.1S
  2S
  R 0.1S
  2S
  A 0.1S
  5S
  HOME 0.1S
  3S
  X 0.1S
  1S
  A 0.1S
  5S
  DPAD_DOWN 0.1s
  0.5s
  LOOP 5
    DPAD_RIGHT 0.1s
    0.5s
  a 0.1s
  2s
  loop 15
    DPAD_DOWN 0.1s
    0.8s
  DPAD_RIGHT 0.1s
  0.8s
  loop 8
    DPAD_DOWN 0.1s
    0.8s
  a 0.1s
  2s
  loop 2
    DPAD_DOWN 0.1s
    0.5s
  a 0.1s
  1s
  LOOP 2
    DPAD_RIGHT 0.1s
    1s
  DPAD_UP 0.1s
  1s
  loop 3
    DPAD_RIGHT 0.1s
    0.5s
  a 0.1s
  0.5s
  HOME 0.1S
  1S

【NXBT】Raspberry Pi で Switchを自動操作する話(後編)【マクロの文法】

設定方法・使い方については、前編 をご覧ください。

piyo-p.hatenablog.com

以下、後編ではマクロの文法をご紹介します。

マクロの文法

マクロでは、1行に1つのコマンドを書きます。

コマンドには、以下の3種類があります。

1. ボタン・スティックのコマンド
書き方
[操作対象] [秒数]S
書き方の例

以下の例では、Aボタンを押し続け、0.5秒後に離します。

A 0.5S
ボタンの種類

ボタンの種類は、以下の通りです。

Macro Value Control Name
A A ボタン
B B ボタン
X X ボタン
Y Y ボタン
L L ボタン
ZL ZL ボタン
R R ボタン
ZR ZR ボタン
MINUS - ボタン
PLUS + ボタン
DPAD_DOWN 十字キー
DPAD_UP 十字キー
DPAD_RIGHT 十字キー
DPAD_LEFT 十字キー
R_STICK_PRESS 右スティック押し込み
L_STICK_PRESS 左スティック押し込み
HOME Home ボタン
CAPTURE キャプチャボタン
JCL_SR Right Joy-Con SR(詳細不明)
JCL_SL Left Joy-Con SL(詳細不明)
JCR_SR Right Joy-Con SR(詳細不明)
JCR_SL Right Joy-Con SL(詳細不明)

これ以外にも、ジョイスティックを倒したりする操作もできるようです。
GitHub の操作方法ページ を参照してください。

2. 待機コマンド
書き方
[秒数]S
書き方の例

以下の例では、3秒待機します。

3S
3. 繰り返しコマンド
書き方

繰り返し処理を始めたい箇所で LOOP と書き、次の行から繰り返したい内容を、[半角スペース4つ, 半角スペース2つ, tab文字] のいずれかでインデント(字下げ)されたブロックに書きます。

LOOP [回数]
    [繰り返したい処理1]
    [繰り返したい処理2]
[繰り返したくない処理]
書き方の例1

以下の例では、「Aボタンを3回1秒ごとに押して、Bボタンを1回押す」処理(4秒1セット)を1時間(900セット)繰り返します。

LOOP 900
    A 0.1S
    0.9S
    A 0.1S
    0.9S
    A 0.1S
    0.9S
    B 0.1S
    0.9S
書き方の例2

LOOP はネストする(入れ子にする)ことができます。
以下の例では、上記と同じ「Aボタンを3回1秒ごとに押して、Bボタンを1回押す」を1時間繰り返すような処理を、2重の LOOP を使って表現しています。*1

LOOP 900
  LOOP 3
    A 0.1S
    0.9S
  B 0.1S
  0.9S

おわりに

誤りなどありましたら、ぜひコメントでご指摘お願いします!

読者の皆様が単純作業から解放され、時間を有効に使う手助けになったなら幸いです。

*1:今回は、「半角スペース2つ」でインデントしてみました。

【NXBT】Raspberry Pi で Switchを自動操作する話(前編)【初期設定・使い方】

突然ですが、皆様は、
「Switch を自動操作して、お金稼ぎやレベリングのような単純な作業をできたらいいなー」
などとお考えではないでしょうか。

Nintendo Switch を自動操作する場合、通常は Arduino Leonardo 互換機などを用いて有線で行う場合が多いでしょう。 *1

今回は、あまり日本語で情報が出回ってなさそうな NXBTRaspberry Pi を用いた、無線(Bluetooth経由)での Switch の自動操作のやり方をご紹介します。

注意書き

本記事の内容により発生したいかなる損害についても、筆者は責任を負いかねます。
また、本記事内容の一部・全部を問わず、内容・画像の無断転用は固くお断りいたします。*2

Arduino と比較したメリット

  • 無線なので置き場所が自由
    • Raspberry Pi と、Switch本体とが離れていても問題ありません。
  • Web経由(自宅のLAN内)でマクロを操作できる
    • 初回セットアップが完了してしまえば、スマホからでも簡単に操作できます。
    • 動作を変更する場合にも、コンパイル作業は必要なし!お手軽!

Arduino と比較したデメリット

必要なもの

  • Bluetooth対応の Raspberry Pi
    • 私は手元にあった Raspberry Pi 3 Model B+ を用いました。
      持っていない人は、秋葉原千石電商あたりで在庫があれば買いましょう。(一応 Amazonでも買えます が、品薄なのもありやや高め。)
      • Raspberry Pi 4 でも同じ手順で動作するはずです。(動作報告求む。)
      • Raspberry Pi Zero 2 W でもいける気がします。(動作報告求む。)
  • MicroSDカード を読み書きできるPC
    • 読み書きできない場合は、外付けのMicroSDアダプタ等を使いましょう。
  • 初期化しても良い MicroSDカード(最低4GB)
  • Raspberry Pi の初期設定用のディスプレイとHDMIケーブル、キーボード、有線lanケーブル
    • ディスプレイは、テレビ等でも可。
    • 有線lanケーブル(インターネット)は、初期設定時のみ必要です。無線lanは設定が面倒なので、頑張りたい人は頑張ってください。

Raspberry Pi にインスト-ルするもの一覧

初期設定の手順

OS(Ubuntu Server 20.04)のダウンロード

NXBTの動作に必要なパッケージがDebian等では利用できなかったりするので、Ubuntuを利用します。
デスクトップ環境は今回は不要なので、Ubuntu Serverを選びました。

Ubuntu 20.04 のダウンロードページ から、Raspberry Pi向けのイメージを「Raspberry Pi Generic (64-bit ARM) preinstalled server image」をクリックしてダウンロードしましょう。

前述の通り、2022年11月時点では Ubuntu 22.04 で NXBT が動作しない点にご注意ください。

ダウンロードしたファイルは圧縮されているので、完了したら展開します。
7-Zip などを使って展開しましょう。

7-zipをインストールすると、ファイルを右クリックして、
7-Zip展開...OK で展開できるようになるはずです。

OS(Ubuntu Server 20.04)のSDカードへの書き込み

Windowsでは、 Win32DiskImager あたりを使うと書き込めます。

インストールして、
Image File の項目ではさっき展開した Ubuntu のイメージを、
Device の項目では自分のMicroSDカードのドライブを選択します。

両方とも選択したら、下の方の Write ボタンを押せるようになるので、Write を押して書き込みます。

OS・NXBTの初期設定

SDカードへの書き込みが完了したら、Raspberry Pi に差し込んで起動します。

Raspberry Pi に、電源とSDカード、LANケーブル、HDMIケーブルが接続されていることを確認し、起動しましょう。

ディスプレイに文字が出てきたら、うまくいっています。

初回起動時の設定

起動したら、最初にログインとパスワードを求められます。

ユーザ名: ubuntu
パスワード: ubuntu

でログインし、パスワードを自分の好きなものに変えてください。

SSHも設定しておくと、PCから操作できて捗ります。(不要な人は設定不要です。)

sudo apt update
sudo apt install openssh-server -y

# ファイアウォールの許可設定。操作元のコンピュータのローカルIPアドレスのみを許可する方が望ましいです。
sudo sudo ufw allow ssh

Bluetoothドライバと、pipのインストール

Raspberry Pi 用のドライバをインストールしましょう。
ついでに、NXBT のインストールに必要なpipもインストールしておきましょう。

sudo apt update
sudo apt install pi-bluetooth -y
sudo apt install python3-pip -y

サービスの再起動を求められたら、すべて選択して再起動して大丈夫です。

NXBTのインストール

NXBT をインストールします。*4
いくつかの依存パッケージがアップデートされて動かなくなってるっぽいので、手動で入れ直してやる必要があります。

sudo pip3 install nxbt
sudo pip3 install markupsafe==2.0.1 itsdangerous==2.0.1 werkzeug==2.0.3

Webアクセス用のファイアウォール設定

Ubuntuファイアウォールに、Webアクセス用ポートの許可設定を追加します。

sudo ufw allow 8000/tcp

NXBT の Webサーバ の起動

NXBT の Webサーバ を起動する前に、Raspberry PiIPアドレスを確認しておきましょう。

ip a | grep eth0

出力結果の IPアドレス っぽいのが、Raspberry PiIPアドレス です。
私の場合、以下のような結果が表示されたので、192.168.10.110 をメモしておきました。

メモできたら、Webサーバを起動しましょう。

sudo nxbt webapp

起動すると、Raspberry Pi と同一のネットワークに接続している端末からWeb画面にアクセスできるようになります。
手元のPC(操作しづらいですが、wifiに接続したスマホでも可)で、ブラウザからアクセスしてみましょう。

先ほどメモしたIPアドレスを参考に、8000番のポートをブラウザで指定して開きます。
私の場合、http://192.168.11.110:8000 を開きました。

うまくいっていると、上の画像のような画面が表示されます。

コントローラの Switch への接続

Switchを起動し、ホームメニューの コントローラー持ちかた/順番を変える を選択し、接続待機中の画面にしておきます。

この状態で、NXBT のWeb画面のコントローラのアイコンをクリックすると、コントローラとして接続されます。

接続が完了したら、メニューを閉じて操作したいゲームなどを開きます。

自動操作の実行

接続に成功すると、下図のようにWeb画面が切り替わります。

NXBT のWeb画面では、赤枠の Controller Macro に実行したい処理を書くことで自動操作することができます。

1秒ごとに1回Aボタンを押す操作を10回繰り返してみましょう。

LOOP 10
    A 0.1s
    0.9s

と書いて、RUN MACRO ボタンを押すと、実行されます。

後編(文法など)の案内

長くなったので、マクロの文法などは 後編 に書きます。

piyo-p.hatenablog.com

*1: やり方は、このへんを参照: https://note.com/kochatece/n/n301221e14593

*2:公序良俗に反しない媒体からのリンクや、著作権法上の「引用」などに際しては、筆者への連絡は不要ですし、これを妨げる意図はありません。特に営利目的など、この範囲を逸脱する利用を厳に謹んでいただくようお願い申し上げます。

*3:家にいらないPCがあれば、それにUbuntuをぶち込んでも多分できると思います。暇な人はやってみてください。

*4:設定すればユーザ権限でもインストールできるらしいので、気になる方はやってみると良いかもです。 /lib/systemd/system/bluetooth.service の ExecStart=/usr/lib/bluetooth/bluetoothd の行を、 ExecStart=/usr/lib/bluetooth/bluetoothd --noplugin=input に書き換えるといけるとか。

急に思い立って、社会人が修士を受けた話(一般受験RTA)

早稲田の情報理工の修士(一般受験)に受かったので、2023年4月から働きながら学生もやることになりました。

出願RTAを含めてまあまあ稀有な体験をしたので、衝動的に大学院に行きたくなった後世の人のためにスケジュール感と注意点を書き残しておきます。

だいたいエンジニア向け。

TL; DR

  • スケジュール感
    • 出願締切の14日前に思い立ったところ、少し余裕を持って出願できました。
      • 少しでも院に行きたいと感じた日に、まずTOEFL の受験を申し込みましょう。受験までに2日から1週間、その後スコアの開示までに4-8日はかかります。
      • できるだけ早く教授に連絡を取り、研究室を見学しに行きましょう。(教授と仲良くなっておくのは非常に重要です。)
    • 専門科目だけであれば、出願後の1ヶ月間に仕事の後で学習すれば何とかなります。
      • 受けてないですが、東大の院は一般教養の数学までやる必要があります。出願前にも1-2ヶ月くらい学習する時間があると良いと思います。
  • 注意点
    • 普段から英語力は身につけておきましょう。
      • 日本国内の大学院を受ける分には90点あればいいので、GitHub などの開発者コミュニティや YouTube あたりで Reading と Listening だけ鍛えてれば大丈夫です。
    • 出願締切の10日前までにはTOEFLを申し込めなかった場合は、その回の受験は難しいです。
      • 多くの場合、社会人枠や冬季受験枠など複数回チャンスがあります。調べましょう。
    • 普段から教授との縁を作れるように、心がけておきましょう。

前提条件

  • 普段の仕事: ソフトウェア開発エンジニア
    • 仕事としては 4年目。高校生くらいから色々作ってました。
    • 普段は Google検索 が主なお仕事。
      • フロントエンドとバックエンドでフルスタック気味にいろんな案件で開発しています。
  • 経済学士(19年卒)
    • GPA は1.67で、だいぶ低いです。
    • 学部で多少 CS 関連の単位を取っており、それらは全てGPA3か4の評価でした。
      • 経済学だけのGPAどんだけ低いんだ...

出願を考え始めた時期と理由

時期:2022年5月末。

そろそろ転職して給料爆上げしたいなと思って探し始めましたが、まともな求人は軒並み CS の学位が Must 条件だったので出願を決意しました。

出願対象の選定

ソフトウェア工学を取り扱っていそうな研究科で、手の届きそうなところを探しました。

検討したのは、以下の2つです。

どちらも6月第1週の締切でかなりギリギリでしたが、最速でTOEFLさえ受ければ間に合う日程でした。

結局、

  • 試験範囲
    • 早稲田の方が一般教養の数学がない分簡単そうだった
  • 教授とのコネ
    • 知り合いの知り合いな教授がいて、取っ掛かりを作りやすかった
  • 卒業の大変さ
    • 働きながら修士の学位を取る予定なので、あまり大変な環境に行くと何年かかるかわからない

の3点の理由で、早稲田に出願することにしました。

日記

2022年5月27日(木) 外国人とおしゃべり

そろそろ転職しようかと思ってLinkedInで連絡してきた方とお話してみましたが、まともそうな求人は軒並み CS の学位が Must 条件でした。

大学院に行きたくなりました。

2022年5月28日(土) 出願を決意

マッチングアプリで出会った人と昼に水族館に行ってきましたが、そんなに好きでもない人間と会って話すより勉強したいと改めて感じたので、お別れして院試に集中できる体制を作りました。

その日の夜に修士のプロ(3周くらい修士課程をやっているはず)であるところの 多動卿 @mouroutai の家に押しかけさせていただいて、
TOEFL の申し込みと出願候補校の出願・試験スケジュールを確認しました。

ついでに参考書まで借りてきました。圧倒的感謝🙏🙏🙏

5月29日(日)

ねじを買ってきて、明日のTOEFLに備えました。

オンサイト版のTOEFLは1週間後くらいにしか受けられず、出願に間に合わないリスクが高かったので Home Edition で受験しました。翌々日には受けられて神です。

家で試験を受けるには机を片付ける必要がありますが、普段使っている机の上を片付けるのは不可能なので、折りたたみの机を引っ張り出してきました。

すると、ボルトがどこかに行っていたので、買いに行く必要がありました。
調べると、秋葉原の「西川電子部品」さんが色々なネジを取り扱っているとのことだったので、机の脚を1つ持って出かけました。

店員さんに相談すると実際に試しながら5分くらいで完璧なネジを探し当てることができ、無事購入することができました。
価格も1本30円くらいで、想像よりだいぶ安く済みました。

パンクしていた自転車を修理に出し、電車で秋葉原に行きネジを買った後で自転車を回収する完璧な立ち回りができてとても気持ちよかったです。

帰宅してからは、TOEFL公式の模擬テスト を受けて、明日の試験に備えて20時ごろ就寝しました。

5月30日(月) TOEFL受験

いつもの如く9時から仕事なので、朝3時すぎに起きて試験を受けました。

かなり長丁場で色々トラブルはありましたが、何とか完了することができました。

6月2日(木) 研究室見学

先週の土曜日にメールして教授にアポを取っていたので、この日の夕方にゼミを見学させていただきました。

かなり歓迎してもらえて、研究室の皆様とも色々話せてとても楽しかったです。

具体的にどんな研究をしていきたいかの目星もつけることができたので、教授に出願するのでよろしく〜、とメールしておきました。

6月7日(火) 出願

6日の午前中にTOEFLの結果が出たので、余裕を持って7日に出願できました。

勉強がんばりましょう!

6月中頃まで

とりあえず離散数学分野の知識が全然なかったので、参考書を1冊読みました。
多動卿おすすめのこの本はかなりいい感じでした。

www.amazon.co.jp

また、仕事終わってから過去問をぼちぼち解いていきました。

職場では受かった時に便宜を図ってもらえるように、部課長に対して話をしておきました。

最近弊社では、従業員のリカレントを推進している(多分中年層の社員に対してでしょうけれども)こともあり、割とすんなり受け入れてもらうことができました。

6月後半〜7月中頃まで 仕事が忙しい

6月から始まっていた案件がいよいよ忙しくなり、勉強する時間をあまり取れなくなってしまいました。

こういう忙しい時にも頑張る気力が欲しいところですが無いものねだり。。

結局、

  • 試験前週の土日でパワポ作成
  • 7月13日(水)〜15日(金)で過去問4年分を復習

って感じで試験に臨むことになりました。

7月15日 試験1日目

1日目は筆記試験でした。

大問1 の「ハノイの塔」の問題を完答でき、それ以外も割といい感じでした。

電気回路は白紙、論理回路もXORの回路記号がわからなくて変な記号で書いた気がしますが、それ以外は割と人間並の回答を書けました。

かなり上振れした気がします。

7月15日 試験2日目

2日目は面接でした。
担当教授を含めた4人の面接官とお話ししました。

持ってきたパワポで研究計画を説明し、その後質疑応答という流れでした。

プレゼンでは、「開発現場での実務経験を活かした視点!」とか、「業務で鍛えた実装力!」とかでアピールしながら研究計画を話しました。
パワポやプレゼンの構成を考える上では、以下が参考になりました。

研究計画の発表について

質疑応答では、「仕事しながら研究、大丈夫?」みたいな質問をされましたが、「頑張ります!」で押し通しました。

試験が終わった後で、しおん君たちと温泉に行きました。とても気持ちよかったです。

7月29日 合格発表

なんか受かっていました。

上振れ最高!

まとめ

というわけで、大学院受験 RTA に際しては、

  • 出願で一番日程がシビアなのは英語の試験です。
    • TOEFL iBT Home Edition なら、申し込みの翌々日受験→翌週出願が可能なので、11日前に思い立てば間に合う可能性が高いです。
    • TOEFL受験時の身分証明書はマイナンバーカードでも大丈夫ですが、日本語の文書は確認に手間取るのでパスポートがあるとより良いです。
  • 学習は、意外と何とかなります。
    • 専門科目は、範囲が狭いです。
      • 寄り道も大事。
        • 過去問やった時に漸化式の考え方を思い出しておいたり、ハノイの塔のWebアプリで遊んでいたのが本番でも生きました。
    • 一般教養も、追加で数ヶ月あれば対策できる程度の範囲です。
  • 文系学部卒でGPAが1.6台でも、実務経験がマッチすれば入れてくれます。
    • 実装力は重要だと思います。少なくとも何かしら研究室に貢献してくれそう、と思ってもらえれば入れてもらえる可能性が上がるかと思います。

という感じの気づきを得ることができました。


というわけで、みなさんもぜひ軽率に大学院を受験してみましょう!

ご質問などあれば、いつでもこのブログや Twitter @lagyu_piyo にコメントください。

twitter.com

ご拝読ありがとうございました。

React / Reduxの推奨するテストの書き方の変遷まとめ

ここ数年の、React / Redux でユニットテストよりインテグレーションテストを重視するようになった背景についての日本語の情報が少なかったので書きます。

この記事の内容は、Redux公式ドキュメントの内容とそのコミットログ、またReactコミュニティ Reactiflux のDiscordでの会話などを参考に執筆したものです。

主に参考にしたページ・ディスカッション:

TL; DR:

  • Redux のドキュメントでは、2021年中ごろまでは Redux のロジックや selector を React コンポーネントから分離して 単体でテストすることを公式ドキュメントで標準とされていた。*1
  • 2021年7月以降は、React コンポーネントと可能な限り一体で(「インテグレーション」で)テストすることを推奨している。*2
    • Redux 単体のユニットテストを書いてもいいが、まずはインテグレーションテストでテストできないかを考えるべき、という方針。*3

時期ごとのまとめ

2018年(React Testimg Library(以下、RTL)は2018年3月リリース)ごろまで

  • Reactでのテストは、テストランナー(jest/mocha)+ アサーションライブラリ(chai) + enzyme が主流。

基本的には、コンポーネントShallow Rendering でテストし、Redux や メソッド*4 などのロジックは

Discordさかのぼった感じ、RTLリリース前の時点ではインテグレーションテストは「コストが高く見合わない」という意見が多かったみたいです。*5
また、インテグレーションテストを実装することでユニットテストが不要になるというアイデアに対しては、概して否定的なコメントが寄せられています。*6

RTLリリース後(2018年後半~)

React Testing Library(RTL)は、Reactのインテグレーションテストを実装するためのライブラリです。2018年3月にリリースされました。
RTLにより、インテグレーションテストの実装コストが大きく下がりました。

これにより、Kent C. Doddsさんの提唱する Testing Trophy のインテグレーションテスト・ユニットテスト比を実現しやすくなりました。

kentcdodds.com kentcdodds.com

Redux では、2021年までには*7 ユーザが実際に利用するコンポーネントのUIこそがテスト対象であり、それ以外の Redux (や Hooks) はすべて実装の詳細として扱うのを原則とすべき、と公式ドキュメントでも明記されるようになりました。*8

  • コンポーネントを介さない、純粋なユニットテストを書きたい場合は容易に書くことができます。ただし、本当にそれが必要かを考えてから書いてください。」ドキュメントでは念押しされています。*9
  • RTLのメンテナ達の間では、インテグレーションテストで確かめられる内容をユニットテストで実装することは悪だと考えている人もいます*10 が、Kent C. Dodds さんは必ずしもそういうわけではない*11 みたいです。

2022年時点でのReduxのテスト実装方針

Reduxコミュニティがインテグレーションテストをメインで実装することを推奨しているわけなので、原則インテグレーションテストのみを実装することにすればよいかと思います。
ユニットテストは、複雑で、インテグレーションテストでカバーするのが難しい部分においてのみ適用するのが良いでしょう。

実際のところ、ここ数年のRedux Toolkit (以下、RTK) と RTK Query の発展も、ユニットテストの省略を後押ししてくれているのではないかと思います。

従来フロントエンドのロジックといえば、バックエンドAPIと通信しデータを適切にキャッシュすることでした。
RTK と RTK Query がこのキャッシュ管理のロジックのかなりの部分を吸収してくれるようになった現代フロントエンドでは、ロジックの大部分は自前で実装するものではなく、RTK・RTK Query をビジネス要件に合う形で適切に呼び出すものへと変化してきているように感じられます。

このように薄くなったフロントエンドのロジックに対してユニットテストを書く意味はあまりなく*12、インテグレーションテストとしてコンポーネントを介してビジネス要件を満たすことができているかを確かめることに時間を使うほうがかなり有意義だと私は考えています。

*1:https://github.com/reduxjs/redux/pull/4116

*2:https://redux.js.org/usage/writing-tests

*3:https://redux.js.org/usage/writing-tests#guiding-principles

*4:当時はClass Component全盛期で、Function Componentが使われるようになるには 2019年2月のHooksの実装 を待つ必要があった。

*5:https://discord.com/channels/102860784329052160/105703173393485824/423150735354494986

*6:https://discord.com/channels/102860784329052160/105703173393485824/423143978536402944 ここでの会話の結論: ユニットテストとインテグレーションテストの確認するポイントが異なっており、どちらもあるに越したことはない。

*7:https://github.com/reduxjs/redux/pull/4116

*8:https://redux.js.org/usage/writing-tests

*9:https://redux.js.org/usage/writing-tests#guiding-principles

*10: このIssueのプルリクでは、hookのユニットテストを書くこと自体がやり玉に挙げられている。結局使えなくなった。

*11:どっちでもよさそう です。How to test custom React hooks にあるように、色々考慮した結果ユニットテストにしよう、ってのは全然ありだと思っていそうです。

*12:ビジネス要件に対して「適切に」呼び出していることを確かめたいのに、ユニットテストでは内部実装に対して「適切に」呼び出していることを確認することしかできません。

webpack-dotenv のコンパイル結果の置き換えの挙動

.env ファイルに以下のように設定したとして、

hoge=piyo

こんな感じのスクリプトは、

if (process.env["hoge"] === "piyopiyo") {
  functionFoo();
}
functionBar();

環境変数が定数に置き換えられて、こんな感じでTree Shakingされた状態で出力される。

functionBar();

フロントエンドのテストについて

同僚とフロントエンドのテストをどう扱うべきか議論になったので、考えをまとめるためにメモ。

私の意見としては、原則インテグレーションテストとして、APIと外部サービスだけmockした状態でコンポーネントのテストだけ書くのが一番メンテしやすいんじゃね、って感じです。

React Testing Library / Redux もそのテスト方針を推奨しているし、多分ベストだと思うんだけどなぁ。。

前提

  • React での開発(多分Vueでもほぼ同じかと思います。)
  • Redux (Redux Toolkit) を利用。
  • static な実装のテストには、TypeScriptを利用する想定。

原則

  • インテグレーションテストを旨とするべし
  • プロジェクト内の実装はできる限りmockしない
    • Writing Tests | Redux
    • 認証など、外部通信などが絡むライブラリは必要に応じて mock する。
  • APIとの通信は msw あたりでいい感じに mock する
  • コンポーネントから分離したロジックに関しては、境界値の判定やテストの実装コストの問題もあるため、ユニットテストを併用してもよい。

反論など

  • Testing Pyramid 提唱側の Martin Fowler による、インテグレーション重視の風潮に対する記事

感想

プロジェクトごとに実装方針を変えたりしながらフロントエンドを実装してきましたが、個人的には

  • インテグレーションテストを各コンポーネントに対して(Reduxや内部の関数は原則mockせずに)実装し、テストしづらい項目がある場合のみユニットテストを書く

という方針でいくのが、リファクタリングしやすく実装の妥当性について十分に確信を持てて良い、と現状考えています。

同僚にはユニットテストをもっと重視すべきと主張している人もいるので、また考えが変わったら書こうと思います。