Posts for: #2022/02

Mockito を触ってみた

0時に寝て4時に起きて6時に起きた。6時過ぎに slack でインフラ担当者から作業の報告があってその対応してた。

Mockito のモック作成

Spring 5 WebClient のテストコードを書いてみた。Mockito というモックライブラリを使っているのをみかけたのでそれを使うことにした。当初は WebClient そのもののモックを用意して、どんなメソッドを呼び出しても Null オブジェクトのように無視すればいいんじゃないかと思ってたんだけど、Mockito はそういう用途に使うものではなく、それぞれのメソッドごとにモックを返すような設定ができる。次のような WebClient のメソッドチェーンでリクエストするようなモックを考える。

var response = this.client
        .get()
        .uri(uriBuilder -> uriBuilder
                .path(path)
                .queryParam("param", param)
                .build())
        .retrieve()
        .bodyToMono(MyResponse.class)
        .block();

他にもっとよいやり方があるかもしれないけど、私がよくわかってなくてこんなやり方しかできなかった。最終的には block() を呼び出したときに任意のレスポンスを取得できればよいのだけど、メソッド単位にモックを呼び出していかないと型チェックやら実行時エラーやらで意図したようにテストできなかった。これだけをみたらメソッドチェーンのモック作りは面倒にみえる。Mockito がどうやってこれを実現しているのかわからないけど、すごい仕組みだなとは思った。

    @MockBean
    WebClient client;
    @Mock
    WebClient.RequestHeadersUriSpec requestHeadersUriSpec;
    @Mock
    WebClient.RequestHeadersSpec requestHeadersSpec;
    @Mock
    WebClient.ResponseSpec responseSpec;
    @Mock
    Mono<MyResponse> mono;

    private void mockWebClientMethodChain(MyResponse response) {
        Mockito.when(client.get()).thenReturn(requestHeadersUriSpec);
        Mockito.when(requestHeadersUriSpec.uri((Function<UriBuilder, URI>) Mockito.any())).thenReturn(requestHeadersSpec);
        Mockito.when(requestHeadersSpec.retrieve()).thenReturn(responseSpec);
        Mockito.when(responseSpec.bodyToMono(MyResponse.class)).thenReturn(mono);
        Mockito.when(mono.block()).thenReturn(response);
    }

ふりかえりとプランニング

1時に寝て3時過ぎに起きて6時半に起きた。

ふりかえり

今日はスクラムのふりかえりとプランニングの日。1週間が終わり始まる。ふりかえりをしていて、2週連続でスプリントゴールが未達になって、原因を追求する空気になって、最終的にはリーダーを糾弾するみたいな雰囲気になった。昔の私だったら論理的に問題を掘り起こそうとがんばったかもしれないけど、いまはもう歳をとってスラムダンクの安西先生みたいになったのか、もしくは外部パートナーとしてのお手伝いだから真剣ではないのか、その両方かもしれないが、一歩引いたところからできなかったもんしゃーないんちゃう?みたいな心境で見守っていた。うまくできない人や状況に「なぜできなかった?」みたいに迫ると「努力が足りなかった」とか「もっとがんばります」みたいなやり取りしかならないので不毛にみえる。経営者のくせにこんなことを言うと怒られるかもしれないが、仕事なんてやりたい人やできる人が楽しめるように好き勝手やって、そうじゃない人は最低限やるとか、邪魔しないように配慮するとか、もうそれでいいんじゃないとか思ったりもしている。もう人類は会社の半分ぐらいの社員が遊んでても暮らしていけるぐらいの生産性を手に入れたと思うよ。半分は言い過ぎか。いずれにしても私はもう無理なく自分のペースで働きたいと思うようになった感じ。

backlog の管理者権限

お手伝い先で backlog を課題管理システムに使っている。私は課題管理システムのスペシャリストとして、ああしたい、こうしたいといくつも注文を付けて、チームの開発やワークフローを改善している。これまでは管理者権限がなかったのでもっている人に依頼するしかなかったけど、そろそろ私の相手をするのが面倒くさくなってきたのか、私にも backlog の設定を変更する管理者権限をもらえた。さっそくカスタム属性をいくつか作って実験的な検証をしていた。カスタム属性は backlog のフリープランでは使えない機能なので、お手伝い先の実地で用途や振る舞いを検証するしかない。同じプロジェクトでも種別ごとにカスタム属性の設定有無を切り分けられる機能があって、この機能は他の課題管理システムでみたことがない実用的で珍しい機能だと思った。チケットに PR とコミットのカスタム属性を追加して、github actions でコミットや PR のタイミングでそれらの属性に URL を追加すれば github 連携もできそうな気がしてきたところ。週末に時間があったら作ってみる。

担々麺がおいしい

0時に寝て4時に起きて6時半に起きた。今回のスプリントは1つの機能拡張のチケットに専念していてとても疲れた。

担々麺

オフィスの近くに 珠しっぴん という坦々麺専門店ができているのに気付いた。半年ぐらい前にオープンしたらしい。あまり通らない場所だったせいか、全然気付いてなくて試しに入ってみたら私の好みの味でとてもおいしかった。食わず嫌いだったのか何なのか、昨年ぐらいまで担々麺はほとんど食べたことなかったんだけど、近所においしい担々麺のお店がいくつかできて、担々麺そのものも好きになってきた。新しい担々麺のお店をみかけるととりあえず入ってみるようになった。

珠辛担々麺

汁なし担々麺

取材商法というビジネス

1時半に寝て5時半に起きた。いよいよ眠れなくなった感じだな。

取材商法の営業

会社の問い合わせのメールアドレスに取材させてほしいといった問い合わせが届いた。うちみたいな無名の零細会社になんの前触れもなく届く問い合わせの大半は営業に関するもの。

※撮影・インタビュー記事の掲載にあたりまして、費用等は一切発生しませんので、ご安心くださいませ。

WEBにて、お写真と記事でご紹介させていただきたいと考えております。

こんな感じで取材の費用はいりませんと言っている。記事広告と取材商法(タレントインタビュー)で雑誌掲載の効果は? によると、取材は無料かもしれないが、メディアや雑誌といった媒体に掲載するのに料金を請求するらしい。まさにこの記事で書かれている会社からのメールだ。取材して記事ができてしまうとサンクコストが気になって掲載料を支払ってしまうような心理を利用しているのだと推測する。

いろんなビジネスがあるなぁと世の中の勉強になった。

java のコードレビューサービス

22時に寝て0時に起きて5時に起きて7時に起きた。なんか体調が微妙。

リファクタリングのチケット作成

これまでは業務に関係しないところの機能拡張をしていたので新規にコードを書くことが多かった。いま業務の開発にも着手し始め、その過程で既存のコードを読むことも多くなった。私からみたらコードの品質が著しく低くて、ただ動いているだけで堅牢でもないし、設計の意図も伝わらないコードが多い。そういうのを自分が変更するときに少しずつ出来る範囲でリファクタリングしたりしている。今日もコードを読んでいて enum の扱いについてチケットを作成した。

前に手伝っていた会社の契約を終了するときに java のコードレビューだけなんらかの契約で依頼できないかという話しはあった。そのときは別件のお仕事が火の車だったので断ってしまった。いまお手伝いしている java のコードをみても、java に慣れていない開発者の書く java のコードはたいていひどい。なぜひどくなるかというと、java は言語仕様が複雑で難しいからだと思う。java の経験が少ないと Effective Java を読んでも理解できないぐらいには java の設計は難しい。その結果として java で開発しているのに設計を練っておらず「動けばいい」コードが散見される。java で開発するなら「これ以外に動かない」コードを書いた方がよいと私は考えている。その意図が伝わるからドキュメントなんか読まなくても「動かすにはこう書けばいい」とわかる。さらにインターフェースが明確であれば、責務や拡張方法も明示的になる。

前から考えてはいたけど、sier や内製始めたばかりの事業会社向けに java のコードレビューのサービスを提供することも考えている。私1人だとたくさん受けられないし、コードレビューサービスのようなものは会社の信頼関係の方が重要なのでビジネスにするのはちょっと難しいかもなぁ。

見積もりのまとめ

先日 見積もりについて考察した 。もともとは社内向けに書こうと書き始めたが、内容の大半は社内に閉じたものではなかったので一般論の記事として書き直した。最終的には1万文字ぐらい書いた。

mysql のデータ移行

23時に寝て2時前に起きて5時に起きて8時に起きた。あんまり眠れなくなってきた。

もくもく会

【三宮.dev】もくもく会 に参加した。もともとオフラインの予定だったけど、オミクロン株の流行でオンラインに変更された。

お仕事である開発環境の構築をしていて docker-compose を使って mysql の環境構築や共有の開発環境にある db2 に接続するために clpplus のインストール方法などを wiki にまとめてた。コンテナにある mysqldump や mysql コマンドを使ってこんな風にデータ移行もできた。

共有の開発環境からデータをエクスポート。

$ docker-compose exec -T mydb mysqldump -h $DB_HOST -C --set-gtid-purged=OFF --skip-triggers $DB > dump.sql

ローカルの mysql にデータをインポート。

$ docker-compose exec -T mydb mysql -h localhost -u root -proot $DB < dump.sql

ストレッチ

いつもは11時からなんやけど、今日は17時40分からだった。カレンダーの予定を変更し忘れてて11時に行って間違えた。今週は2日間ぐらいストレッチしたかな。今日の開脚幅は開始前164cmで、ストレッチ後168cmだった。いつも時間帯が違うので数値も変わる。今日は右太ももの内転筋や内側やらがすごく張ってた。あまり調子はよくない。

docker の勉強

0時に寝て2時過ぎに起きて5時に起きて6時に起きた。珍しく3回ぐらい起きた。

docker のマルチステージビルド

これまで docker を使った開発を主導してこなかったので私はあまり docker についての知識をもっていない。いま k8s クラスターで java アプリケーションの運用をしていて、リリース作業の改善には docker イメージのビルドも改善する必要性が迫られてきた。いくつかプラクティスの記事を読んでいると マルチステージビルドの利用 を推奨している記事が多い。マルチステージビルドをうまく活用することで、docker イメージサイズの削減と日々の ci やビルド時間の短縮の2つを図れるようにみえる。docker の仕組みを学ぶちょうどよい機会なので主導的な立場でこの改善に着手しようと考えている。

オフィス内覧

オフィスの引っ越し調査のために エリンサーブ に行ってきた。駅近でもなく市街でもなくちょっと辺鄙な海外沿いにあるせいか、他のレンタルオフィスと比べて全体的に広さに対する家賃は安く設定されている。案内をしてくれた代表の方が「狭い部屋で働かせたくない」といった想いを話されていたので、意図的に窮屈なスペースにならないように広めに設計されているらしい。

オープンスペースでそれぞれの席が別会社という作りは斬新な考えとも言えるし、お互いの信頼関係で成り立っているとも言える。例えば、パソコンのモニターや資料とか、近くを通ったらみえてしまうわけだし。そういったセキュリティも考慮して、一見さんのドロップインには対応していないという。利用者はお互いに面識のある一定の信頼関係を築ける人たちで構成されているらしい。なにか審査があるのかどうかわからないが、人間関係が苦手な人には向かないスペースにもみえる。私は1日のうちにテレビ会議を何度もやるのでオープンスペースだと顧客の情報を守る義務があるのと、そうじゃなくても周りにも迷惑がかかるので、1日のうちの何度も場所を変えてテレビ会議できる部屋に移動しないといけない。それがボトルネックだなと思えた。個室もいくつかみせてもらって、2人向けの窓のある個室があってよさそうにみえた。そこはテレビ会議しても問題ないとのこと。家賃も予算にあうものだった。

Dタイプ(3F)

  • 月額利用料: 66,000円

Eタイプ(3F)

  • デスクは2つ
  • 月額利用料: 76,000円

いまは他の会社が借りている状態だけど、空きが出たら教えてもらえるようにお願いして帰ってきた。

スクラムの窮屈さ

0時に寝て5時に起きてちょっとだらだらして7時ぐらいにはオフィスにいた。

スプリントの期間とプランニング

いまスクラムのスプリントを1週間で運用している。スクラムのスプリントレビューをやっていて、今回のスプリントはスプリントゴールが未達となったという事実がありつつも、ある開発者が本来のスプリント計画にはなかった課題を少し工数を使ってやってしまってたという話題が出た。それはある機能開発の調査の過程でこういうツールがあると業務メンバーの作業効率が上がりそうだとわかって、それをヒアリングしていた開発者が PoC も兼ねてプロトタイプを作っているうちにすぐ運用で使えそうなベータレベルまで作ってしまったという話し。言うても2日ぐらいで作ったと思うのだけど、5日しかないスプリントで2日は40%という大きな工数を占める。スクラムマスターも否定はしなかったけど「スプリントの計画にないタスクに工数を割くのはよくないと、スクラムマスターの立場からはお小言を言わざるを得ない」と言及した。

先日、私も直接はスプリントの計画達成に直接寄与しない リファクタリングに半日を費やした ので、ツールを作ってしまった開発者の気持ちはわかるなと無言で聞いていた。それと同時にスクラムのスプリントは、運用によっては開発者のモチベーションを削ぐことも実感した。やる気の有無で仕事をするのはよくないと一般論では言うけど、実際のところ、人間のモチベーションは制御が難しいのと、知識労働はモチベーションが生産性に大きな影響を与える。開発者のモチベーションが高いときにそのタスクをやるのは理に叶うという側面もある。非開発者は次のプランニングで承認を得て来週のスプリントでやればいいじゃないかと思うかもしれない。でも、違うのだ。いまやってみたいという気持ちが大きいときにいまやるのと来週やるのではモチベーションが異なる可能性がある。この気持ちは開発者にしかわからないと思う。

その開発者がデイリースクラムでツール開発をやることを相談しなかったかの理由も理解できて、合理的に考えたら相談しても承認を得るのは難しいので、黙ってやってしまったのだろうと思う。そして、今回のスプリントのスプリントゴールが未達になったとしても、なにか業務に影響が出るというわけでもないことをメンバーが知っているというのもある。スプリントは全力でやるものだけど、全力でやらなくてゴールが未達になっても、なんら業務に支障がでない事実がスプリントの目的を減衰させている。

そういう業務と実情があっていない現実、ルールに則るとお小言を言わざるを得ない牽制機構、たった2日すら自由に時間を使えない開発者、なんかスクラムって窮屈だなと直観的に感じた。

リリース作業の改善

1時に寝て6時前には起きてた。昨日がんばったから今日は早めにお仕事を切り上げた。

リリース作業を柔軟に、効率的に

以前から認識していた開発の課題にリリース作業のコストが大きいことがあった。具体的には人間が手動で進捗をみながら処理を実行していて、さらに1つずつの処理に数分かかるので順番に実行していくだけでも確認を含めて30分から1時間ぐらいかかる。リリース後に変更したところの動作確認とかを開発者が集まってやってたらだいたい2-3時間はかかる。だらだら?やっているとリリース作業に開発者全員がハドルに入って半日ぐらいやってたりする。最初のうちは雑談しながらリリース作業のやり方がわかってよかったんだけど、何度か繰り返したらこれを毎週やるのは非効率だわと思うようにはなっていた。

そんな開発側の事情もあったんだけど、スクラムマスターからもいまのリリース作業は柔軟性がないみたいな指摘が入って、その改善のチケットが切られた。開発者も全員それは認識していた。改善するならスプリントを1つ使うぐらいの工数がかかるという背景を説明するために、私が「ぼくのかんがえたさいきょうのりりーすさぎょう」を考えていくつかのタスクをチケットに作った。いま GitHub Actions の無料枠におさまるようにリソース制限を運用で調整しているのもあって予算確保できるなら戦略も変わってくる。それらも含めて然るべき改善の道筋を示したい。

テストコードのリファクタリング

0時に寝て6時に起きた。今日は7時半から23時過ぎまで集中してコードを書いてた。最近は19-20時には帰って、晩ご飯食べて、ドラクエタクトやったり漫画読んだりだらだらしている。そんな暇あったら積ん読の本読めって感じだ。

テストコードのリファクタリング

業務機能の開発をするにあたって、既存のテストコードをみていて、@BeforeEach というテストメソッド単位に呼ばれるメソッドでテストデータの削除と postgresql の sequence のリセット処理をしていた。こんなの共通処理ですべてのテーブルの truncate と sequence のリセット処理をすればいいやんとか思って、いろいろ調べて2つのリファクタリングの PR を作成した。先日 JUnit5 の拡張 を調べたばかりだから、テストの共通化のノウハウが溜まっている。Testcontainers Postgres Module と連携して、postgresql コンテナに接続して sequence のリセット処理を汎用のテスト拡張として実装した。テストを実装する開発者は、次のように @ExtendWith(DatabaseInitializer.class) をアノテーションに付与すれば、自分で sequence のリセット処理を @BeforeEach のメソッドに実装する必要がなくなる。

@SpringBootTest
@Transactional
@ExtendWith(SetupDatabaseContainer.class)
@ExtendWith(DatabaseInitializer.class)
class MyTest {
    ...
}

この作業の過程で spring boot の @Transactional はデフォルトでテストメソッドの実行後にロールバックする機能が提供されていて、いままで @BeforeEach のメソッドで明示的にテーブルのデータを削除する必要はなかったんやと気付いた。じゃあ、なぜ削除するコードを書いてたかと言うと、テストの外部で初期データを作成する仕組みがあるから、初期データを削除する目的でそうしていたことが判明した。そして、一部のコードはそこで作った外部の初期データに依存して実装されていた。テストコードの一部が外部のデータに依存しつつ、テストメソッドでは外部のデータに依存しないように削除のコードが書いてある。書いていて何を言っているのかわからないと思うけど、私も調べてて訳がわからんくて、PR に「いまの状況はかなりややこしい」と前置きしつつ、無駄なコードや仕組みを取り除くための修正を行った。本当は機能開発やらないといけないのにテストコードのリファクタリングするのに大きな時間をかけるわけにはいかないだろうという意図で、半日掛けてリファクタリングして23時過ぎまで作業して、既存のテストコードも含めて全部直した。このリファクタリングで数十のテストケースの約300行ぐらいの初期化コードをなくせた。

確定申告書類の印刷

1時に寝て7時に起きた。

確定申告書類の印刷

最近は遅くても8時、速かったら7時過ぎからお仕事している。ちょうど仕事の谷間で手持ちのタスクを終えてしまっていて、今日から別のタスクに着手する予定が、昨日から障害が発生していたらしく、朝忙しそうだったから11時まで確定申告の作業をしていた。昨日、データ入力は終えていたので総勘定元帳をみながら変な数字になっていないかをチェックしたり、源泉徴収税の還付金の計算があうかどうかを検算したりしていた。あとすでに廃棄した固定資産が残っていることに気付いた。耐用年数が過ぎた固定資産の価値は1円として管理される。これを備忘価格と呼ぶらしい。除却の手続きもした。ついでに 固定資産売却益(損)とは の会計手続きも調べたりしていた。

オフィスのプリンタで一通り書類を印刷した。あとは提出するだけ。昨年から住んでいるところの徒歩圏内に申告できる場所ができて、散歩のついでに確定申告する程度の手間しかかからない。このまま電子申告してもよいのだけど、寄付金控除のための領収書を写真か PDF ファイルなどで取り込む必要があって、それだけ面倒なので放置している。このまま今年も紙で提出してくるかなぁ。

業務システムの開発

twitter のタイムラインで業務システムの開発者は「業務系エンジニア」と呼ぶとか言っている人をみかけた。そっか、私は web エンジニアから業務系エンジニアになったんだー、web アプリケーション開発しているけどな、とか思いながら、今週からいよいよお手伝い先の業務システムの開発に着手する。いままでインフラやサーバーサイドのシステム寄りの保守や機能開発のみをしていた。さっそく DB スキーマの定義やドキュメントの書き方、作業の進め方などを確認していた。ひとまず1週間のスプリントで終えられそうなタスクなのでがんばってやりたい。