世界を動かす技術を、日本語で。

10年前、誰かが2026年の期限を含む「Servo」のテストを書きました。

概要

  • Mastodon のWebアプリ利用時には JavaScript の有効化が必要
  • JavaScriptが無効の場合、 Webアプリ は正常に動作しない
  • 代替として Mastodon公式アプリ の利用が推奨
  • 各プラットフォーム向けに ネイティブアプリ が提供
  • ユーザー体験向上のための案内

Mastodon Webアプリの利用案内

  • Mastodon Webアプリ を利用する場合、 JavaScriptの有効化 が必須
  • ブラウザの 設定画面 からJavaScriptをオンに変更
  • JavaScriptが無効のままでは、 ページ表示や機能 が制限
  • セキュリティや利便性を考慮し、 公式アプリ の利用も選択肢
  • iOS、Android、またはデスクトップ向けの Mastodonネイティブアプリ が利用可能
  • ネイティブアプリは App StoreGoogle Play 等で配信
  • より快適なMastodon体験のための 推奨手順

Hackerたちの意見

クラシック!でも、修正をあまり厳しく評価する前に、これは簡単な修正で、ちゃんとした修正ができるまでの間に十分なものだと思うよ。

この一時的な修正が永久的なものになるシナリオに、1ドル賭けるよ。(まあ、少なくとも100年は永久的だね。)いつか、ファム・ヌウェンがこのテストスイートについて、星系の間で文句を言ってるだろうな。

もちろん、簡単な修正だよ。コードを全く理解していない僕みたいな人でも書けるような解決策だね。(PRの提出者がコードを理解していないとは言ってないけど、理解する必要がないってことだと思う。だから、リスクはないんだ。ただ、今の解決策は問題を隠しちゃってる。もし誰かに問題を解決してもらいたいなら、新しい日付を近い未来に設定して、誰かがイライラするまで放置するかな。それにしても、なんでハードコーディングの日付なの?「今から1週間後」とかにすればいいのに。

いつかは定数の時間を超えることになるよ。宇宙の熱的死後、存在するはずもないシステムでの、信じられないほど短い時間の後に: エラー TIME_TEST FAILURE

2126年にHNに投稿された: 100年前、誰かが2126年に期限があるサーボのテストを書いたんだ。

Y2Kの騒ぎを覚えてる人いる?

そうそう、だから俺はいつも自分の時間定数を退職する年か、もしかしたら死んでる年に設定するんだ。先延ばしにするなら、遠くまで蹴っ飛ばした方がいいよね。

2038問題を避けるためのほとんどのアップデートは、実際には10889年までの先延ばしに過ぎない。もしかしたら、5000年後にはもっと長持ちする何かを見つけてるかもね。

だから、俺はいつも2525年を使ってるんだ。人間がまだ生きてると仮定すれば、俺の問題じゃないし。

PRをざっと見たけど、著者は僕より詳しいと思う。でも、なんで日付をハードコーディングする必要があるの?「今日 + 1年」みたいなことにすればいいのに。

だって、today + 1 year + randomInt(1,42) daysにすべきだよ。テスト値にはいつも少しのランダム性を含めるべきだね。

時計に依存することになるから、あんまり良くないよね。似たような問題があって、俺もその理由でハードコーディングしちゃったことがある。

時間帯や夏時間、月の長さの変動でテストが壊れることが簡単に起こるよね。何年も前に何回か経験したけど、だいたいテストの方が間違ってて、テストしてるコードは正しかった。例えば、この簡単なテストはその落とし穴にハマってる:var expected = start.AddMonths(1); var actual = start.ToLocal().AddMonths(1).ToUtc(); Assert(expected == actual);

面白いね、タイトル見たときは意図的な「強制コードレビュー」かと思ったけど、どうやらそうじゃないみたい。でも、そのアイデアはすごく気に入った!

俺がいたところでも何回かやったことあるけど、難しいんだよね。失敗が短すぎるとただの面倒な作業になっちゃうし、長すぎるとコンテキストを失って、何考えてたか思い出せなくなるリスクがある。全体的には、特定のケースでは一時的なものを強制するのにプラスになってるかな。

いつか、各機能フラグが最大1年先の期限を宣言して、その期限を過ぎたらCIが失敗するような機能フラグシステムを作りたいと思ってた。新しい機能フラグを追加するのは簡単すぎて、削除するのが難しいんだよね。ある日、FFのバックエンドがダウンして、300個のFFが全部falseになったら大変だよ。

SAML SP証明書に10年のタイムボムを仕掛けなきゃいけなかったんだ。AFAIK、他に方法がないからね。それからもう7年経った。IDPに連絡してSAML設定を更新してもらうのが憂鬱だわ。

でも、まだちょっとした手抜きだね。もっといいのは、Goのtesting/synctest[0]パッケージみたいなものを使うこと。これなら、時間が固定で決定論的なバブルの中でテストを書くことができるよ。[0] https://pkg.go.dev/testing/synctest

一般的に、テストデータをリアルな方法で生成する方がハードコーディングするよりも良いことが多いよ(プロパティテストや似たようなものを追加しやすくなるし)。現在の時間を関数の入力にするべきだね(つまり、純粋関数の話)。これをすることで、テストしやすくなるだけじゃなくて、1. 一つのロジックユニットが同じ時間を見ること 2. 不要なnow()の呼び出しを避けること(あまり重要じゃないこともあるけど、気をつけた方がいい)。

これって、他のバグが見逃される原因になるよね。たとえば、うるう年の処理とか。100年を扱うなら、400年の処理もちゃんとしてる?

それって、テストのバグがn年後に本番のバグに変わるだけじゃない?それって逆に悪化してる気がするんだけど!

libfaketimeもこういうテストには便利だよね。ただ、ユニットテストにはあんまり便利じゃない。LD_PRELOADでテストを実行しなきゃいけないから。

freezetime(Python)を結構使ってて、めちゃくちゃ面白いフレークに遭遇したことがある。 - 時々、テストコードが時間が進むことを期待してるのに、 - 時々、コードがクラスをハッシュマップにキャッシュするために保存してて、フリーズ時間のクラスのオーバーライドが効く前にキャッシュが作られちゃうことがある - 時々、クラスをパッチした後にキャッシュが変なことになったり - 時々、シリアライズコードが使われるクラスにすごくこだわったり - 時々、時間が進まなくなるとテストコードがすごく変な挙動をする(freezetime frozen=trueを使うとき)。Seleniumのタイムアウトがクリアされないのは面白かったし - 時々、コードがパッチされてない日付クラスを変なところで取得しちゃったり。楽しい時間だったよ。一番いいのは、時間を気にするものに「今」のパラメータを渡せることだね。

これ、Rust用の見つけたよ: https://github.com/museun/mock_instant

Rubyのtimecopは、こういうテストシナリオにぴったりだよ。 https://github.com/travisjeffery/timecop

PRからのコメント > 深刻な問題ではないけど、曜日が間違ってるよ。例えば、2127年4月18日は金曜日で、日曜日じゃない。覚えておくべき魔法のような日付がたくさんあるね - 2126年(このコメントの後にPRが更新されたと思う)と2177年。それに2028年もどこかにあるよ。

「誰か」お願いだから、Xのあらゆる投稿に「誰か」って書くのをやめて。

これもテストケースの一つを修正したよ。そこにはコメントが付いてたんだ:// これが失敗する頃には、ビーチでピニャコラーダを飲んでるはず。残念ながら、彼はまだ働いてたけど、別の会社でね。