Posts for: #Testing

復調へ向けて休養

今日のバドミントン練習は、みなとのもり公園でジョギング3周 (1.5km) 、縄跳び1234回 (09:08)、メイビス2で壁打ちを10分した。体調崩してたくさん寝ていたのもあって体力が落ちているのもあって普段よりも軽い運動にした。

可用性検証の結果確認

お昼から昨日の可用性検証の結果を確認した。4千エントリーのユーザー/グループ追加/パスワード更新、ユーザー/グループ削除をやると mq によるメッセージにすると2万メッセージの処理が id 連携としては逐次処理となる。id 連携の個々の処理はわりと遅いのですべての処理が完了するまで約半日ほどかかった次第。そのために mq を設けている。その後、気分転換にコードを書こうと軽く mq の queue のエクスポート/インポートのサブコマンドを作った。お昼に2時間ほどお仕事をしてからストレッチへ向かった。

公職選挙法と選挙運動

先週終わった 兵庫県知事選挙 が新たな展開を迎えている。昨日の夜から公職選挙法違反の疑惑が浮上してきた。さいとうさん陣営で広報に関与した PR 会社の社長が、会社の宣伝 (自身の承認欲求?) のためにさいとうさんから選挙における広報全般を「任された」と記事に書いた。これが大炎上となっている。書いた本人に悪意はなく、公職選挙法についてよく知らずに書いてしまったという凡ミスにはみえる。

私も知らなかったから一般人は知らないと思われるが、政治に関する行為には次の2つに大別される。

  • 政治活動
  • 選挙運動

政治活動に対して報酬の支払いをすることは構わないが、選挙運動に対する報酬は公職選挙法で厳密に規定されている。その背景は選挙運動の広報に報酬を支払ってよいならお金持ちは広告をたくさん出して有利になるのは明白なのでそういったことができないように法律で禁止されているとのこと。具体的に払ってよい報酬は次のようなものになる。これ以外の労務は後援会のスタッフがボランティアとして手伝うものらしい。

  • ポスター代/選挙カー代/選挙ビラ代 (税金から支出)
  • ウグイス運動員への報酬
  • 選挙カードライバーへの報酬
  • 労務者への報酬
  • 選挙事務所費用、事務所運用経費、その他経費など

ここで選挙運動というのは、特定の選挙の、特定の候補のための行為を指していて、PR 会社の社長は広報戦略の企画立案や SNS 運用全般を「任された」と書いていることから多くの人がそれはプロの会社が報酬をもらってやっていることだよね?と勘繰っている。もし報酬をもらっていなくてもプロの会社が専門業務をボランティアで手伝うという行為は役務の提供として寄付扱いとなってしまう。政党に対する寄付は構わないが、政治家個人への寄付は禁止されていることから、報酬をもらっていようがボランティアで手伝っていようが、広報全般を「任された」という言葉を鵜呑みにすると、どちらであっても公職選挙法違反では?とかなり旗色が悪いという話しになっている。もしこの疑惑が公職選挙法違反となった場合、さいとうさんの当選は取り消しとなり、県知事選挙がやり直しとなる。もちろん選挙違反なら、さいとうさんは公民権が停止するために立候補できない。

今回の県知事選挙はさいとうさんの告発文書への対応の経緯であったり、立花さんの不当な介入だったり、異常尽くしになっているのでもうひと悶着あっても驚かないのかもしれない。いずれにしても、さいとうさんの百条委員会もまだ継続しているのでこのネタもその議題の1つになるのかもしれない。

ストレッチ

今週は出張の週でほとんど運動できていないので筋肉痛などはない。一方で出張の行き帰りで座っている時間が長かった分の、右腰の張りが強いとトレーナーさんが教えてくれた。あまり自覚症状がなかったが、車に長時間乗ったときや新幹線の移動があるときは大抵そうなる。予定外のタスクが増えていって進捗もよくなくていろいろ疲れていて、トレーナーさんと県知事選挙後の雑談をしたり時事ネタを話したりして気分転換になった。今日の開脚幅は開始前149cmで、ストレッチ後153cmだった。調子がよくない。

体調がよくなかったからストレッチを終えて真っ直ぐ家に帰って20時頃から横になって休んでいた。

web api サーバーの可用性検証

今日も体調が悪かったのと22時過ぎまでインフラ検証をしていて疲れていたのでバドミントン練習はおやすみ。

昨日の続き。compose サービスのコンテナネットワーク内で管理している nginx のリバースプロキシの設定を、ホスト os で起動する httpd (apache) に移行して検証していた。基本的にはほとんど同じ設定ができる。nginx よりも httpd の方が細かく設定したり、エラーチェックが厳密だったりの違いがあったぐらい。httpd の設定をするのも久しぶりで chatgpt に聞きながらわからないところを穴埋めしていくようなやり方で検証した。

その検証を完了してから、web api サーバーの可用性検証に取り掛かる。シェルスクリプトで数十から数百リクエストを並行にリクエストして、そのときのサーバーの状態を監視したりしながら、id 連携の処理が正常に動くことを確認する。mongodb のトランザクション導入 により、同じ主キーのドキュメントを並行に更新しようとすると WriteConflict エラーが発生する。これは仕方がない。同じコレクションであってもキーが異なればトランザクションのエラーは発生しないことを確認できた。メモリリークもみられない。web api サーバーの大半は私が設計して開発しているのでこんなレベルで問題にならないはずだが、やはり検証して確認できると安心できる。

カバレッジによるテスト改善のみえる化

昨日は睡眠不足の中、同期飲みで酔っ払ってかなりひどい状態で寝ていた。朝起きて時計の見方を誤って10時過ぎだと勘違いしたぐらいには取り乱していた。今日のバドミントン練習は雨降りでおやすみ。縄跳びをもってきたのに雨降りでできなかった。

プロジェクトの進捗報告

出張したときの月例報告の22回目。前回の進捗報告はこちら

今回の報告内容のメインはテスト改善の成果について共有した。カバレッジを取得できるようになったことでその成果を数値で共有した。マネジメントとしては数値で説明できると説得力があってよい。前フェーズからの要件や仕様変更により、テストが出来ていなかったところのカバレッジの改善が次のようになったと報告できた。わかりやすいし成果も確認しやすい。この数値を算出できるようになったことそのものも今回のテスト改善の成果でもある。

-/api/handler/ldap_management.go  46.8%
+/api/handler/ldap_management.go  77.1%

-/api/handler/ldap_profile.go  50.6%
+/api/handler/ldap_profile.go  79.8%

-/api/handler/ldap_util.go  61.4%
+/api/handler/ldap_util.go  80.4%

あとはバックエンドの開発を私がほとんどやるようになってしまって、その状況そのものがいずれ私がいなくなることや引き継ぎを考慮するとよくない状況になってしまったという懸念も共有した。すぐにいなくなるわけではないが、私がコアな開発をやっていてよいのかどうかの懸念を私自身が抱くようになってきた。これからメンバーへ徐々に引き継ぎしていくためにもテストコードが十分にあって、テストそのものが書きやすくなって、カバレッジでテスト漏れを確認できるようになっていて今後にもつながっていくだろうと報告できた。私自身がプロジェクトで窮屈に感じていた肩の重荷を少し下ろすことができて安心できるようになったと報告した。

テストカバレッジの LT 発表

今日のバドミントン練習はお休み。

LT 会

午後から LT大会 with カメラマン に参加してきた。副業でカメラマンをやろうとしている方が LT 中にプロフィール写真になるようなものを撮ってくれるという。会社紹介などのスライドで使えるかもしれないと思って参加してきた。趣味で4-5年カメラを勉強しているというだけあって、機材や知識も備えていてよかったと思う。LT のネタとして先月お仕事でやっていた go のテスト改善の一環でカバレッジについての紹介をしてきた。サンプルコードは次になる。

終わってから軽く立ち飲み屋で飲んで若い人たちの話しを聞いていた。若い人たちは活気があってやりたいことも多くて、いまの私からみたときのモチベーションの在り方に違いがあるようにも思えた。たまに若い人たちの中に紛れて話しを聞くだけでも自分が失くしたものを気付くきっかけになるようにも思えた。若い人たちはどんどん挑戦してがんばってほしい。

ストレッチ

今日は身体的に疲れているというよりも、開発合宿から続くお仕事のせいか、精神的に疲れていて、2週間ぶりにトレーナーさんと雑談するだけでも気分転換になってよかったと思う。今週はお仕事に集中していてまったく運動していないため、足の張りなどはほとんどなくなっていた。一方でバドミントンの試合をしてこけたときに痛めた腰だけはまだ張りが残っていてなかなか治りきらないことも実感した。今日の開脚幅は開始前149cmで、ストレッチ後155cmだった。

ストレッチを終えてから買いものしてオフィスへ戻って軽く作業していた。

開発合宿前日

今日のバドミントン練習は体育館で1時間ほど練習できた。試合中にまた足と腰を痛めてしまった。無理しないように意識していてもついついシャトルを追いかけてしまう。しばらく試合はやめとこうと思う。

テストコード追加の一区切り

これまでテストの改善をやってきてもっとも仕様が複雑、且つ数量も多い api 群のテストコードを一通り書き終えた。カバレッジを目標の1つにしているので改善していることを数値で確認できる。その過程でいくつかバグをみつけて直すこともできる。区切りとして一通りやり切ったので安心して明日はお休みをとって開発合宿へと行ける。しんどかったけど、やっていれば形になって結果は出てくる。一方で私が実際の開発をやってしまうと自分の時間をどんどん浪費していることにも気付けるようになってきた。自分の時間をどう使うのかをいろいろ考える開発やリファクタリングの機会となった。今回の開発フェーズが終わったらまた振り返りしたい。

体育館でバドミントン

前回の所感 。抽選予約で獲得した平日夜の時間帯。今日は参加者が多くて8人来られた。1面のスペースだとこれ以上の人数はちょっと無理そうに思えた。なにか練習をしてもよかったのだけど、8人もいたらスペースが足りないかなと思ってどう運用していいのかわからなかった。不完全燃焼。最初は3対3でネットを挟んでの打ち合いをしてみたが、スペースが狭いからなんとなく手持ち無沙汰になってしまう。経験者の方から2人チームを作ってローテーションでまわしましょうという提案をもらって2対2で10点先取の試合形式にした。10点取ったら交代でローテーションしていくようにした。このときにチーム編成を簡単に決める手段を準備しておくと、決め方を「決める」の無駄な時間を省ける。前に練習に参加させてもらったチームではトランプのカードを引いていた。これはなにかしらツールを用意しておくとよさそう。

経験者の方にフットワークについて教えてもらった。一歩でどう動くか、腕とラケットを伸ばしてどこまで届くかの距離感を掴むのが大事なように思えた。カラダの近くでシャトルを捉えようとすると動かないといけないが、実際の試合だとシャトルの方が速いのでなかなか動けない。フットワークの重要性が少しわかってきた。

私の場合、下手だから試合形式にするとすぐミスをして試合を止めてしまい、申し訳なさと自身の練習時間も短くなるという2重でネガティブな所感を受ける。なにかしら量をこなせる練習メニューや打ち合いをしていた方が楽しかったりする。中級者なら試合する方が楽しめるのかな?やはり2面ないと別の思考をもつ人たちが一緒に活動するのは難しいのかもしれない。いまの私はスキルアップにつながる練習の量をこなしないという思いがある。また他のチームの練習にも参加して考察してみようと思う。

より良くなって苦しくなる

お仕事の区切りが悪くて23時までコードを書いていたので今日のバドミントン練習はお休み。ひたすらテストコードを書いている。テストケースをみて、カバレッジをみて、アプリケーションコードを読んで、テストコードを読んでの繰り返しの日々。時間をかけてきたけれど、ようやく成果が出てきつつある。一番ややこしいところのカバレッジを 50.6% から 80.4% に改善したと報告をあげた。テストデータを細かく管理できるようになったのでカバレッジが上がっているだけでなく、複数設定の違いによる振る舞いの検証も進んでいる。

改善のための改善を繰り返すと苦しくなる

ちょうどいま私がやっていることのしんどさを代弁してくれているような記事をみかけた。

私もいまマネージャーやって、プロダクトの開発全般を改善して、また開発者に戻ってプロダクトのコードを改善して、ここ半年ほど技術的負債になってしまったところを改善しまくってきた。小さい規模ではうまくいったことが規模が大きくなる中での見直しや依存関係によって複雑化したり、自動化をしても自動化のための仕組みは保守しないといけない。改善にはいろいろ面倒くささがついてくる。その割にその成果がみえにくかったり分かりにくかったりする。やっている本人ですら微妙とか思ってしまうことさえあるものの、しかし、それをやらないとさらにひどい状況になるのでやらざるを得ない。

ひどいプロダクトやどうしようもないスタートアップなどはリアーキテクチャをやらないので直せないといった状況になってしまい、保守している人たちが苦労したり、鈍重な開発で苦しんでいるのをみかけたりする。少なくとも私がイニシアティブをとっているプロダクトでそんなことは起きない。常に改善しまくっているから短期でみた機能開発のスループットは高くないかもしれないが、中長期でみた開発を停滞させる要因はまったくない。

この「より良くしているのに、より苦しくなってくる」機序は、基本的に産業資本主義の特徴なのだろうと思っている。
時間軸上の価値体系の差異から価値を取り出す行為を回し続けないといけなくて、効率化して生産性を上げたなら、さらに上げ続けないと価値を取り出せなくなってしまう。

テストがなければそもそもテストの改善や見直しという作業は発生しない。開発したときにテストコードを書くという作業も発生しない。業務量はずっと下がる。もちろんその減った業務量は将来の不具合や鈍重な開発により後払いになるわけだが、いまテストを書いていてもその保守や改善のための作業が既存の開発に付加された形で将来に積み重なっていく。テストがなかった未来とテストがある未来を比較することはできないが、どちらの未来にも手に余る業務量が待ち受けているという展望はそれほど変わらないようにみえる。そこで自身の自己実現や成長といった目的がないのであれば、テストがある未来に得ているはずの利益を資本家が搾取するだけで労働者はなんら変わらないのではないかという気持ちが「改善すればするほど苦しくなっていく」と感じてしまう。

飛行機での出張帰り

夜に神戸に戻ってきてからオフィスに来て、機内でやっていた作業を区切りのよいところまで進めてコミットしたりしていた。その後スーパーへ買いものへ行ったりしていた。今日もバドミントン練習はおやすみ。

ローカルは standalone mongodb

mongodb の レプリケーション 機能を使っていて、replica set の設定が容易なことから bitnami/mongodb というコンテナを使っている。これまで結合テストもレプリケーション機能を設定して実行するようにしていた。結合テストの量が増えてきたのもあって実行時間が徐々に遅くなってきた。いまテストのリファクタリングをしているため、ローカルで検証のために何度も実行する必要がある。コードの品質を上げるためにテストを書きやすくする必要がある。実行時間は短いほどよい。そこでローカルでの実行はレプリケーションを設定しないようにしてみた。さらに go のデータ競合を検知する -race オプションも外してテストを実行してみたところ、この2つの改善で macbook の環境で改善前より45%ほど速くなった。十分な高速化を図れた。

飛行機ルートのふりかえり

8月に大雨で新幹線が止まってしまい 神戸に帰れない状況 に直面した。私はほとんど飛行機に乗ったことがなかったため、新幹線が動かないときの迂回手段として飛行機のルートに慣れておく。普段リュックサックに小さいカッターとマイナスドライバーを携帯している。これらは飛行機の手荷物検査でとめられてしまう。荷物を預けるか、検査場で処分してもらうしかない。前回は ANA で帰ってきたが、今回は スカイマーク の飛行機に乗った。値段が安いから LCC だと思っていたら スカイマークは安くて快適なMCC らしい。ANA に比べたらずっと小さい飛行機だった。

タイムスケジュールは次のようになった。

18:15 (都営浅草線) 五反田 発
18:56 (京急本線) 羽田空港 着
19:45 搭乗開始
19:55 飛行機の座席に着く
20:08 羽田空港の滑走路を発進
20:20 離陸
(機内は暗かった、ラップトップで作業)
21:16 神戸空港の滑走路に着陸
21:22 降機
21:25 空港内の荷物受け取り場に着く
21:30 荷物を受け取り
21:35 (ポートライナー) 神戸空港 発
21:51 (ポートライナー) 貿易センター 着

新幹線だと次のようなタイムスケジュールになる。トータルの時間でみれば新幹線の方が20-30分早いかなといったところ。一方で新幹線だと2時間半、同じ姿勢で座っている必要がある。飛行機だと座っている時間は1時間強。飛行機は搭乗手続きのチェックポイントがいくつかあってそれぞれに細かい待ち時間ができてしまうのが気になる。そのときの体調によってもどちらがよいかは変わってくるかもしれない。来月は行きは飛行機、帰りは新幹線にしてみる。

17:57 (JR) 五反田 発
18:03 (JR) 品川 着
18:19 (新幹線) 品川 発
20:53 (新幹線) 新神戸 着
21:10 (市営地下鉄) 新神戸
21:12 (市営地下鉄) 三宮

出張前日の資料づくり

今日は1日中オフィスにこもって作業と出張準備をしていたのでバドミントン練習はお休み。夕方にお土産として モロゾフのプリンクッキー を購入するために本店へ行ってきた。これも神戸限定らしい。

パッケージ外のディレクトリにあるテストのカバレッジ計測

先日 深夜にバイナリのビルド・起動調査 をしたのに、最終的にはそんなことしなくてもよかった。デフォルトではパッケージ外のディレクトリにあるテストのカバレッジを計測しないことから普通にはできないと考えていた。しかし、調べたら次の SO で解決法をみつけた。結論としては -coverpkg ./... のように go test で実行している結合テストに対してオプションを指定するだけでよかった。

この調査を終えて最終的な makefile の coverage ターゲットは次のようになった。

coverage: lint
	rm -f coverage.*
	go test -tags=integration -race -cover ./... -coverpkg ./... -covermode atomic -coverprofile=coverage.out
	go tool cover -html coverage.out -o coverage.html

この make ターゲットを gitlab ci/cd から実行して coverage.out/coverage.html を自動生成する。coverage.out があるので必要に応じて好みのツールで統計情報を解析すればよい。たとえば nikolaydubina/go-cover-treemap でツリーマップを作るなら次のように実行する。

$ go-cover-treemap -coverprofile coverage.out > treemap.svg

近況報告の資料作り

普段は週末に報告資料を作っているのにもうやる気が無さ過ぎてお仕事を終えてから作っている。今回はネガティブな内容も報告に入れる。過去の経緯などを調査しながら3時間もあれば一通りのアウトラインはできた。明日がマイルストーンの最終日になるため、明日を終えてからでないと細かい数字は決定しない。マイルストーンの issue を調べたら qa テストでみつけた不具合の issue がそれなりに溜まっているようにみえる。本当は次のマイルストーンで5次開発は完了予定だが、もう1つ増やしてもよいかもしれない。いずれにしても12月/1月に本番導入のための準備もある。今の開発フェーズを完了しても次の開発フェーズには入らないのではないかという見通しもある。

テストライブラリの導入

今日のバドミントン練習はエアシャトルでリフティングを25分した。連続最大回数は277回できた。初めてエアシャトルで200回を超えた。しかも夜なのに。やや高めに打ち上げれば安定的にリフティングできるようになってきた。連続回数が増えることはラケットとシャトルの距離感、ラケットコントロールが上達していることの証左でもあるので200回を超えたときは嬉しかった。

テストライブラリの追加

結合テストを改善するために2つのライブラリを新たに使うよう導入した。

testify は名前だけ知っていたが、実際に使ってみるのは初めて。testify は大きく3つの機能もっている。

  • アサーション
  • テストスィート
  • モック

うちらのチームで使うのはアサーション機能だけになる。モックも将来的に使う可能性はある。アサーションを使うと自分でエラーメッセージを書く手間を省ける。次のようなコードがあった場合、

if expected != actual {
    t.Errorf("expected %d, but got %d", expected, actual)
    return
}

次のようにエラーレポートを testify に委譲できる。このぐらいの利便性でしかないが、テストの規模が大きくなったり、量が増えていけば読み書きのコストを削減できるかもしれない。

if !assert.Equal(expected, actual) {
    return
}

httpexpect はまったく知らなくて初めて使ってみたが、感触がよい。これもデフォルトのエラーレポート機能は testify のアサーション機能を使っているようにみえる。これまでは http リクエストに対して自前のユーティリティ関数と組み合わせて次のようなコードを書いていた。

res, err := doHTTPRequest(body, UserPath, http.MethodGet, "")
if res.StatusCode != http.StatusOK {
    t.Errorf("expected to get %d, but got %d", http.StatusOK, res.StatusCode)
    return
}
var actual entry.User
if err := convertBody(res, &actual); err != nil {
    t.Errorf("failed to convert: %s", err)
    return
}

httpexpect を使うと次のように簡潔に記述できる上にエラーレポートを httpexpect に委譲できる。これはかなりテストコードを読み書きする工数を削減できると思う。

var actual entry.User
e.GET(UserPath).
    WithJSON(map[string]any{ ... }).
    Expect().
    Status(http.StatusOK).
    JSON().
    Decode(&actual)

mongodb のテストデータ管理

今日のバドミントン練習はエアシャトルでリフティングを45分した。連続最大回数は146回できた。調子は悪くなく安定的に30回前後は続くものの、50回を超えたぐらいで失敗してしまう。打ち上げる高さの違いかな?と気付いて少し高めに打ち上げるようにしたら100回を超えた。エアシャトルはラケット面に対して適切な角度でコルクを打たないとあらぬ方向に飛んでいってしまう。高く打ち上げるほど、重力で落ちてくるときにコルクが下を向きやすくなるため、うまくシャトルを打ち上げやすくなる。ラケットコントロールをうまくできれば、エアシャトルをより低い高さでリフティングできるようになるかもしれない。まだ私はそのレベルには満たない。

json からの mongodb にテストデータを追加する

結合テストの改善をしていてテストデータを json で管理したい。これまで go の構造体でテストデータを定義して mongodb の client で insert するといったことをしていた。それも役に立つのだけど、共有のテストデータがどこにあるのか、ソースコードに書いてしまうと時間とともに散らばっていって把握できなくなっていく。テストデータを管理するためのディレクトリを設け、そこに json で記述してどのテスト関数で使うかといったメタ情報も定義できるようにした。次のコードは mongodb に json からデータをインポートするための原理を説明するための疑似コードのようなもの。

go の構造体で定義したテストデータと json で管理するのとどちらがよいかというのは議論の余地はあるし、一概に言えないとは思う。

type testData struct {
	Documents    []bson.Raw `bson:"documents"`
}

func InsertData(
	t *testing.T, client *mongo.Client, b []byte,
) (func()) {
	var data testData
    err := bson.UnmarshalExtJSON(b, false, &data)
	require.NoError(t, err, "failed to get json files: %v", err)

	ctx := context.Background()
	col := client.Database(dbName).Collection("mycollection")
	r, err := col.InsertMany(ctx, docsToInterfaces(data.Documents...))
	require.NoError(t, err, "failed to insert: %v", err)

	return insertResult, func() {
		t.Helper()
	    col := client.Database(dbName).Collection("mycollection")
		for _, id := range r.InsertedIDs {
			filter := bson.D{{Key: "_id", Value: id}}
			if _, err := col.DeleteOne(ctx, filter); err != nil {
				t.Errorf("failed to delete %s: %v", id, err)
				return
			}
		}
	}
}

呼び出し側のイメージ。defer で teardown を呼ぶことでテスト完了時に追加したテストデータを削除してくれる。

teardown := mongotest.InsertData(t, mongoClient, b)
defer teardown()

...

bson.Raw として読み込める json データは bson パッケージのユーティリティを使って dump できる。

func dumpAsJSON(value any) {
	b, err := bson.MarshalExtJSON(value, false, false)
	if err != nil {
		slog.Error("failed to marshal as extended JSON", "err", err)
		return
	}
	fmt.Println(string(b))
}

ひとりではできないこと

今日のバドミントン練習はエアシャトルでリフティングを30分した。連続最大回数は80回だが、ほとんどの試行は20回も続かずに失敗してしまう。難しい。

隔週の雑談

顧問のはらさんと隔週の打ち合わせ。今日の議題はこれら。

課題管理と adr の関係の考察

数年前から adr の話題や導入した会社の記事などをみかけるようになった。私はこれまで課題管理をうまくやっていれば adr はそれほど重要ではないとあまり重視してこなかった。しかし、世の中的に認知されて流行っているものはなにかしら意義があるのだろうと最近は少し見直してきているところもある。このスライドによると2017年から流行り始めたらしい。

  • 開発に関する情報を一元管理する、または全文検索ことにビジネスチャンスはある
    • 検索のニーズや要件は多様で言語によっても違い、技術もまだまだ発展的でもあるからずっとビジネスの種になる気はする
    • gitlab issues のコメントの全文検索は有料機能なので slack 通知したチャンネルを全文検索している
      • 課題管理システムのプラグインでテキストをシステム間連携することで検索システムを別途構築できる可能性がある
      • 検索できなくてもデータのアーカイブをするという視点でもビジネスニーズに応える?
  • ベクトル検索 を検索がまだ一般的にはなっていない?
  • wiki と adr の違いの1つとして wiki になにを書いてよいかわからない問題がある
    • 文章を書けるようになるのは経験や習熟を必要とする
    • adr のようなテンプレートがあることで経験の浅い開発者も書きやすくなる狙いはある
    • 課題管理システムの wiki に adr のラッピングをして別機能としてみせるのはよいかもしれない
    • 業務の引き継ぎにも adr は役に立つのではないか?
    • adr 一覧をみたり、そこから検索することで検索効率や精度は上がるという想定
  • 大きい会社でも巨大な課題管理システムと wiki が1つだけあって一元管理しているという噂は聞く
    • ある会社では wiki は誤っている可能性があるから信用するなという教訓があった
      • wiki の情報は更新されていない可能性があるから参考にしながら必ず裏をとって業務をしなさいという話し
    • wiki を編集したら必ずレビューが必要になるプロセス
  • notion のプロジェクト管理の使い勝手はどうか?
    • テンプレートを使ってガントチャートやカンバンを作れる
      • 基本的に自分でカスタマイズできることの良し悪しがある
        • db をどんどん改良できるが、それだけに魔改造してしまう
        • 時間とともに複数人が改良すると保守できなくなっていく懸念がある
      • 中核機能をパッケージ側で提供することは堅牢性を担保する上で重要ではないか
    • タスク管理と wiki がシームレスなところはよい、はらさんは日報を書いてリンクしている
  • 会社のインフラに日々の開発情報を書いていくと退職後に参照できない
    • フリーランスのような働き方をするにはナレッジデータベースをローカルに作りたいという欲求がある
    • 組み込みの課題管理システムにより、自身のナレッジデータベースをローカルに残すという目的はよいかもしれない

仕事は楽しいかね? の考察

まとめを見返しながら、だいたいの項目は理解または支持できる。1つだけ次の項目が私には欠けていることに気付いた。

毎日1つ試し続ければ必ず上達や進歩ができる

  • 新しいことを始めると、いまやっていることを継続する時間がなくなったりしないか?
  • プロダクト開発ではがんばってもあまり成果が出ないような時期もある
    • リファクタリングやテスト追加などはまさにそう
    • そういったときも1つでも変化をもたらせれば日々の生活が変わるのか?
  • はらさんのお奨めは梅原さんの 1日ひとつだけ、強くなる。 世界一プロ・ゲーマーの勝ち続ける64の流儀
  • 本書を読んではらさんのよかったところは「試してみることに失敗はない」
    • それまでも試すことはやっていたはずなのに躊躇してしまう理由として失敗したら時間の無駄だと考えてしまっていた
    • 失敗したら嫌だと考えてしまうところがあったが、この考え方があるから vision pro を購入できる
    • やりたいことをすぐやってみるという思考につながった
  • 面倒くさいときもなるべくパソコンを使うようにしてなにかしら調べる
  • 私はオフィスにいれば、家よりはなにかしら作業するモチベーションになる
  • 目標達成や成果をあげるには環境がもっとも大事
    • 個人の感情を信頼しない
      • 人間は面倒だとすぐ怠けてやめてしまう
    • 環境を整えることでワークフローを洗練させて習慣化する
      • 日記になにか書かないといけないから調べものをする
      • 嫌々ながらでもやっているうちに習慣になってくるとワークフローが洗練していく
      • 人間の運用を変えていくなにかは普遍的な価値またはビジネスチャンスがある
    • 調子の悪いときにどうやって早く脱却するかが大事
      • ひとりでは言い訳を作ったり怠けてしまう
      • このときに他人の助けがいるのではないか?
        • 話しを聞いてもらうだけでも前へ進むきっかけになる

go の結合テスト向けカバレッジ計測の考察

以前リリースパーティーで go 1.20 で結合テスト向けのカバレッジ計測の機能が入ったことを聞いていた。次のブログ記事でやり方が紹介されている。

将来的に結合テストを作るときにカバレッジ計測のカスタマイズを施したバイナリを使って api server を起動する仕組みにすればこの機能を使えることに気付いた。

まずは単体テストを実行して任意のディレクトリ (tests/coverage) にカバレッジ計測のための中間データを生成する。

$ mkdir -p tests/coverage
$ go test -cover ./... -covermode atomic -args -test.gocoverdir="$PWD/tests/coverage"
$ go tool covdata textfmt -i=./tests/coverage -o coverage.out

coverage.out がさまざまなツールの入力となる統計情報となる。例えば、このファイルを使って次のようにしてソースコードのヒートマップの html を作成できる。

$ go tool cover -html coverage.out -o coverage.html

nikolaydubina/go-cover-treemap を使うと treemap でカバレッジのヒートマップを確認できる。

$ go-cover-treemap -coverprofile coverage.out > treemap.svg

カバレッジ計測向けのバイナリをビルドする。そのバイナリを起動するときに環境変数 GOCOVERDIR に単体テストのカバレッジの中間データが含まれるディレクトリを指定する。

$ go build -cover -covermode atomic -o bin/api ./cmd/api/...
$ GOCOVERDIR="$PWD/tests/coverage" ./bin/api -verbose

このバイナリを使って起動した api server に対してリクエストを呼び出すことでカバレッジを計測してくれる。結合テストからバイナリ起動した api server に対してリクエストしたときに GOCOVERDIR に中間データが追加されていく。結合テストを完了したら最終的なカバレッジの統計情報を生成する。 

$ go tool covdata textfmt -i=./tests/coverage -o coverage.out

textfmt のヘルプをみたら同じディレクトリじゃなくてもよいみたい。

$ go tool covdata textfmt -help
...
Examples:

  go tool covdata textfmt -i=dir1,dir2 -o=out.txt

  	merges data from input directories dir1+dir2
  	and emits text format into file 'out.txt'