データ抽出のテストにはモブプログラミングを使うといいかも #MobProgramming

モブプログラミングとは?

この記事では複数人で行われるプログラミングの意です。

ペアプロの延長線上だと考えて下さい。

正確な定義とは異なるかもしれません。

参考までに以前書いた記事です。

su-kun1899.hatenablog.com

データ抽出のテストって?

何らかのデータストアに対して、クエリを発行し、結果を取得するようなUnitTestを想定しています。

MySQLようなRDBMSに、Select文を発行して結果を確認するようなイメージです。

データ抽出のテストの何が問題なの?

データ抽出のテストは実装後のレビューコストが高いです。

データ抽出する処理の実装時に考慮すべきことに例えば下記があると思います。

  • データストアの設計
    • RDBMSでいうER。オブジェクト間のリレーション。仕様的なものも含む
  • データ
    • どんなテーブルに、どんなデータが入っているか
  • クエリの構造
    • JOIN句の類。内部結合か外部結合か。UNIONやソート順などなど
  • パラメータ
    • どんな条件で検索するか。SelectでいうWhere句
  • etc

多くの場合、実装者はこれらを並行で考慮しながらテストを書く必要があります。

そして、主にデータパターンとパラメータの組み合わせでテストの意図が込められていきます。

意図の読み解きが難しい

データパターンやパラメータの場合、コードから意図を読み解くことは一般的に難しいと思います。

レビュワーも当然前述の項目を並行で考えなければならないからです。

ケースは思い浮かんでも、どこで実施しているかを読み解くのは困難です。

DbSetupのようにテストデータの可視性を高めるライブラリもありますが、限界はあります。

そのため、後からコードレビューを行う際に、どうしてもコストが高くなってしまうのです。

なぜモブプログラミングがよいの?

モブプログラミングではリアルタイムでレビューを行います。

そのため、ドライバーが意図を説明しながら、ナビゲーターが意図を理解しながら同時進行で進めることができます。

なので、実装とレビューでフェーズを分ける場合に比べて効率が格段に上がると思います。

僕らはさらに、着手前にチームメンバーで想定されるテストケースの洗い出しをしました。

作業を進めていく中で、実はいらなかったケースなどが出てきたりして、とても効果的だったと思います。

まとめ

性質上、コードから意図の読み取りが難しくなるような場合は、モブプログラミングをおすすめします。

モブプログラミング楽しいですよ、モブプロ。

みんなでテストケースを洗い出すの図

f:id:su-kun1899:20170330005933p:plain

最良の日だったかもしれない #ちら裏 #ポエム

転職して、一年ちょっとが経ったにもかかわらず、モヤモヤしながらもがき苦しんでるわけですが、今日は入社してから一番いい日だったかもしれない。

何があった

とあるモジュールがSVNで構成管理をしているんだけれど、GitHubに移行することになった。

自分は直接関わっていないんだけれど、部署の中では比較的Git/GitHubに慣れているということで、その会議に呼ばれた。

アジェンダとしては主にプルリクのレビュー運用・ルールについて。

その会議で、モデレータしてたメンバーと僕は同じチームで数ヶ月一緒に開発作業をしていた。

一緒にやっていたプロジェクトは正直直接的な成果を上げていたとはいえなくて、今は別チームになってしまっている状況。

でその人が、プルリクのレビューの議論をしている時にこんなことを言った。

“レビューはコードの正しさを見るだけじゃなくて、それもあるけど、質問とかいろいろなやり取りがあっていいので色んな人に見てもらいたい”

このセリフがとてもうれしくて。

自分は入社してから、チームで開発するということ、一緒に作るということ、ということを伝えたいと思っていて。

届く範囲で、伝え続けてきたつもりで。

チームに何かを与えたか、組織に何かを与えたか、誰かの何かを変えたか、それはわからないけれども。

彼には何かが伝わっていたかもしれない。

一緒に開発してた期間に意味はあったのかもしれない。

今の会社に僕の存在価値があるかどうかは分からないけど、少なくとも僕にとっては意味のある何かが、ここでも少しはできたと初めて実感できたよ。

ネストしたオブジェクトでAutoMappingを使う #mybatis

MybatisのネストしたresultMapの自動マッピングはデフォルトPARTIALになっている。

つまり、ネストしたオブジェクトのauto-mappingは効かないということ。

これだといちいちマッピングを定義してやらなきゃいけないのでとてもつらいのだが、設定を変えなくても、個別にresltMapを定義してやることで、auto-mappingを使える。

対象のマッパークラス

public class Company {
  private long id;
  private String name;
  private List<Section> sections; // 部署リスト

  // アクセサは省略
}

public class Section {
  private long id;
  private String name;
  private Member representative; // 代表者

  // アクセサは省略
}

public class Member {
  private long id;
  private String name;

  // アクセサは省略
}

SQLのイメージ

SELECT
    company.id    AS id
  , company.name  AS name
  , section.id    AS section_id
  , section.name  AS section_name
  , member.id     AS representative_id
  , member.name   AS representative_name
FROM
  company
  inner join
  section
    on company.id = section.company_id
  inner join
  member
    on section.representative_id = member.id

これはNG

<resultMap id="companyMap" autoMapping="true" type="Company">
    <id property="id" column="id"/>
    <collection property="sections" autoMapping="true" columnPrefix="section_" ofType="Section">
        <id property="id" column="id"/>
        <association property="representative" columnPrefix="representative_" javaType="Member" autoMapping="true">
            <id property="id" column="id"/>
        </association>
    </collection>
</resultMap>

これはOK

<resultMap id="companyMap" autoMapping="true" type="Company">
    <id property="id" column="id"/>
    <collection property="sections" autoMapping="true" columnPrefix="section_" ofType="Section">
        <id property="id" column="id"/>
        <association property="representative" columnPrefix="representative_" resultMap="memberMap">
    </collection>
</resultMap>
<resultMap id="memberMap" type="Member" autoMapping="true">
    <id property="id" column="id"/>
</resultMap>

SQLと紐付け

<select id="getCompany" resultMap="companyMap">
  <!-- ここにSQLを書く -->
</select>

参考

意見 #ちら裏 #ポエム

自分を信じよう

自分の知識・経験をフル稼働させて出した答えを信じ、大切にしたほうがよい。

他人の方が優秀かもしれないが、自分ではない。

もっとも信頼できるのは自分自身であるべきだ。

自分を疑おう

自分の出した答えを疑ったほうがよい。

世の中には知らないことがたくさんあるし、自分よりも優秀な人もたくさんいる。

なにより、ほとんどの場合正解なんてそもそも存在しないのだ。

よりよい答えを、常に謙虚に探し続けなければならない。

IntelliJ IDEAで括り放題 #intellijidea

職場の同僚に教えてもらったのだが、Surround selection on typing quote or brace を有効にするといいかもしれない。

括弧やクォートで括り放題になる。

括っている文字の置き換えもIDEAさんがいい感じにやってくれる。

どういうことかというと。。

これを。。

f:id:su-kun1899:20170326211259p:plain

こうして。。

f:id:su-kun1899:20170326211331p:plain

違う括り文字を選ぶと。。

f:id:su-kun1899:20170326211406p:plain

こうなるのだ!

設定方法

Editor > General > Smart Keys で、Surround selection on typing quote or brace にチェックを入れるだけ!

f:id:su-kun1899:20170326211528p:plain

モブプログラミングやってみたら最高だった #MobProgramming

今日チームでモブプログラミングを初めてやってみたのだけれど、最高だったのでテンションのままにブログを書く。

きっかけ

ふりかえりでたまたまJoy.Incの話になり、あの会社は全部ペアでやってるらしく、ペアプロしたくなるという話をした。

そうしたら、なんとチームメンバー全員(自分含め3人)がちょうど本を持っており読んでいる、読もうとしているところだった。

ジョイ・インク 役職も部署もない全員主役のマネジメント

メンバー全員ペアプロの経験は殆どないに等しく、全然わからない笑
でも、とにかく試してみようよという話になった。

ただしチームメンバーは3人のためペアが組めない。
そこで、Scrum Gathering で見たモブプログラミングでやってみよう、ということになった。

なお、モブプログラミングについても当然経験はなく、ペアより多い人数の場合はモブと呼ぶ、くらいの理解しか無かった。

2017.scrumgatheringtokyo.org

どうやったか

  • 小さい会議室を半日確保
    • 大きいディスプレイをひとつつなぐ
    • ドライバーを中央に、ナビゲーター2人が横に付く
  • 最初に実装するフィーチャーに対し、全員でタスクだしをする
    • ソロでやるとしたら何からやるか、みたいな感じで付箋に書き出す
    • 順番に並べて、ドライバーの前に配置する
  • ドライバーの順番をじゃんけんで決めて、タスクに取り掛かっていく
    • ドライバーは「まず〜します」みたいな感じで発言
    • 気になったところあればワイワイガヤガヤ
  • 端末は個別のものを使用、ドライバー交代時にディスプレイを繋ぎなおす感じ
  • 20分~30分を目処に、キリの良いところで交代
    • 交代のタイミングで、git push するので、続きからはじめる
    • 休憩は交代のタイミングで適宜
  • プルリクやコミットは相談しつつ
    • レビューが同時進行なので、作業内容振り返る感じ
    • 皆で最終確認してからmerge
    • CIが通ったらハイタッチ(するくらいの気持ちで)

モブプログラミングの風景

f:id:su-kun1899:20170323221037p:plain

どうだったか

楽しい。

緊張感もあったのだけれど、やってみるととても楽しかった。

ただ、チームメンバー間での信頼関係や、敬意の有無がとても大切になるだろうとは感じた。

集中力が高まる。

協力体制になるので、他のことに気を取られる余裕がそもそもない。

完成度が高まる

これはある程度できあがった成果物ではなく、思考過程も踏まえた上で議論できるので、抜け漏れがなかったり、ブラッシュアップがしやすいからかもしれない。

スピードが上がる(かも)

時間的にはどうだったかという話だと、ソロでもできたかもしれないけど、せいぜいプルリクエストを出すところくらいまでだっただろうという肌感。

レビューしてもらって修正、マージまで同じ量終わらせるのは無理だったと思う。

3人というのがいい。

これはたまたまだったけど、3人というのはとてもいいと思う。

2人だと意見の相違があったときに、対立構造っぽくなってしまう。

また3人より多いと、熟練度がないとどうしても濃度が薄まりやすくなるのではないか。

レビューコストが下がり、質は上がる

例えばデータパターンが必要なテストコードなどは、同時進行だとレビューコストがすごく下がる。

どうしてもコードから意図を汲み取るのが難しいものをリアルタイムで一緒にやると理解が早く、アドバイスの質も上がった。

勉強になる。

他の人の作業を見られるのは、興味深いし刺激にもなる。

単純な成果物の質だけではなく、過程を見られるのは大きい。

どこから書くのか?みたいなこともそうだし、なぜそうするのか?というのも聞ける。

端末が別なのも、個々人で使ってるツールとか知られて、かえって良かったと思う。

難易度高いものに効果が高そう。

完成度の話とも連動するけど、試行錯誤の段階から意見や考えがアウトプットされ、協力体制で作れるのは大きい。

課題みたいなもの

遊びが少ない

集中度が高まって生産性は間違いなく上がると思うんだけど、疲労度は大きい。

また、ちょっと気になってることへの寄り道とかもしづらい。
(時にその寄り道が別のどこかで大きな効果を生むことがあるはず)

毎日1日中ずっと、というのは結構辛いだろうな、と思う。

少なくとも今は。

場所の確保

オフィスによるんだろうけど、自分のところでは数時間まとまった単位で場所を確保するのは難しい。

モブプロを実施する頻度を上げたいと思った時に、壁になるかも。

まとめ

モブプログラミング最高だった。みんなやればいいと思うし、積極的に勧めて行きたい。

メンバーも好感触で、とりあえず週一は固定でやろう、やりたいタスクがあったら適宜でやろうという話になってる。

これが正しいやり方かは分からないし、一回やってみただけで何言ってるんだと思われるんだろうけど、それくらい大きな感動があった。

モブプログラミングいいですよモブプロ。

はやくまたやりたい。

application.ymlの値をJavaアプリケーション側で受け取る #SpringBoot

org.springframework.beans.factory.annotation.Value を使うとよい。

ただし、まとまった単位で管理したいときは @ConfigurationProperties を使うのがよさげ。

@Configuration
public class AppConfig {
    @Value("${spring.datasource.schema}")
    private String schemaName;

    public String getSchemaName() {
        return schemaName;
    }
}

参考

blog.y-yuki.net