カテゴリー: Uncategorized

Mermaid記法でドキュメントを書いてgithubで管理する

ドキュメントを管理する上で色んな選択肢がありますが、Mermaid記法というのがあり、図をマークアップのように書けます。Mermaid記法はgithubでサポートされており、図のプレビューに対応しているのでMarkdown記法と組み合わせて使うことでドキュメントが見やすくなります。またMermaid記法のドキュメントを書くときはVSCodeのプラグインがあるので書きながらプレビューを見たりすることが可能です。

図の一例を下記に記載します。

フローチャート
```mermaid
graph TD;
    A-->B;
    B-->C;
    C-->A;
```
シーケンス図
```mermaid
sequenceDiagram
    participant A
    participant B
    A->>B: Attack A to B
    loop defence
      B->>B: defence loop
    end
    B->>A: Attack B to A 
```
Gitグラフ
```mermaid
gitGraph
    commit
    branch develop
    commit
    checkout main
    commit
```
ガントチャート
```mermaid
gantt
dateFormat YYYY-MM-DD
title タイトル
excludes weekdays 2022-12-30

section A section
完了 :done, task1, 2023-01-01, 2023-01-02
作業中 :active,  task2, 2023-01-08, 3d
未来のタスク :  task3, after task2, 2d
```

日付が近すぎると日付が重なって表示される…

クラス図
```mermaid
classDiagram
    classA --|> classB: ラベル
    classA <|--|> classB
    classC *--*   classD
    classE o--o   classF
    classG <-->   clasH
    classI --     classJ
    classK <..>   classL
    classM <|..|> classN
    classO ..     classP
```
ER図
```mermaid
erDiagram
    END_USER ||--o{ PROVIDER : places
    END_USER }|..|{ OBSERVER : uses
```
円グラフ
```mermaid
pie 
    title タイトル
    "nice" : 40
    "bad" : 60
```

これ以外にも図の種類や書き方があるので詳細は公式サイトを見たほうが良さそうです。

https://mermaid.js.org/intro/


[CI] Bitriseの仮想デバイステストで毎回異なるUIテストにタイムアウトで失敗する

Bitrise内で仮想デバイスを起動してUIテストを実行することが可能です。

https://github.com/bitrise-steplib/steps-virtual-device-testing-for-android

Bitriseのワークフローにvirtual device testiong for androidを追加するとandroidTest内に書かれたテストコードが自動で実行されます。内部ではFirebaseTestLabを使っておりそれをBitriseから呼び出しています。

UIテストが充実してくるとタイムアウトでテストが失敗してしまいます。

調べてみるとBitriseのUIテストのデフォルトタイムアウト時間は900秒(15分)に設定されているため、タイムアウトするようです。Bitriseの設定からUIテストの実行時間を最大秒数となる3600秒(60分)を設定すればタイムアウトしなくなります。
Bitrise上のUIテストの実行時間とFirebase上のUIテストの実行時間は異なるので注意してください。今回の設定はFirebase上のUIテストのタイムアウト時間です。Bitrise上だと15分のUIテストは約20分で表示されます。

(ところでなぜデフォルト900秒なのでしょうか…)

答えが分からないものを模索しながら作り続ける世界に我々は突入した。和田卓人氏による「組織に自動テストを根付かせる戦略」

ソフトウエアテストで著名なt_wada氏の発表を4つに分けてpublickeyでまとめられています。4keysにも関わってくる内容なので、とても心に刺さります。

https://publickey1.jp/blog/22/12022.html

LeanとDevOpsの科学もKindleで半額なのでオススメです(2022/10/25まで)

LeanとDevOpsの科学[Accelerate] テクノロジーの戦略的活用が組織変革を加速する impress top gearシリーズ Kindle版

https://amzn.to/3TpFwQz


Architectural Decision Recordsを書いておく

https://adr.github.io

複数人で開発することがモバイルアプリケーションでも増えてきています。コードを実装する上で「ここはどういうルールで実装するべきなのか?」「他の部分では古い設計だけど、新しい設計にしたほうが良いからしてしまおう」など複数人で開発しているとどのようにコードを書くべきか迷う場面が出てきます。そのとき参照すべきドキュメントやルールはチーム内で揃っていますか?現状の設計が古いとしても開発初期段階ではその設計が最善だったかもしれませんし、新しい設計を入れるにしてもチームで意思統一ができていないと設計もバラバラになり、修正やリファクタリングも難しくなります。そういうときのためにArchitectural Decision Recordsを書いておくと後で迷う場面が出てきても「なぜこういう設計になっているんだっけ?」という迷いが生じなくなります。フォーマットは色々ありますが、下記のような内容を書いておくのが良いです。

https://qiita.com/fuubit/items/dbb22435202acbe48849

  • タイトル(Title)
  • ステータス(Status)
  • 意思決定者
  • コンテキスト(Context)
  • 決定(Decision)
  • 結果(Consequences)

自分も「テストコードを書くためにこういう設計にしたい」と業務で思ったときはADRを書いてミーティングを開く手順を踏むことにしました。全員の意志が同じ方向に向かっているとレビューや会話もスムーズになりますし、新しいメンバーが入ったときもルールを統一して開発に挑めます。


[コードの見通し]関数に分けるということ

プログラミングの勉強で「処理は関数にまとめる」ということが書いてあります。自分も仕事でコードを書くとコードレビューで「処理は関数にまとめてください」とか「コードの見通しが悪いです」とかレビューされます。コード見通し?ってなんのことか最初よくわからなかったです。

例として関数にまとめないコード例は下記になります。内容はとりあえず無視してください。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        DaggerMainActivityComponent.factory()
                .create(this, this)
                .inject(this)
        super.onCreate(savedInstanceState)

        viewBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(viewBinding.root)

        /**
         * 
         * 通知チャネルを作成処理
         * 8行
         *
         */
        /**
         * 
         * ブロードキャストIntent宣言処理
         * 6行
         *
         */
        /**
         * 
         * 広告の初期化処理
         * 2行
         *
         */
        /**
         * 
         * Actionbarの初期化処理
         * 2行
         *
         */
        /**
         * 
         * NavigationDrawerの初期化処理
         * 10行
         *
         */
        /**
         * 
         * InAppUpdates確認処理
         * 7行
         *
         */
        /**
         * 
         * LiveDataを観測する処理
         * 6行
         *
         */
        /**
         * 
         * LiveDataを観測する処理
         * 6行
         *
         */
        /**
         * 
         * 初回起動時の処理
         * 2行
         *
         */
    }
}

こういうコードをそのまま書いている人いませんか?1つの関数に30行も40行も書かれると読む側の人はとても大変です。通常の場合、コードは上から実行されるので実装者もレビュワーもコードは基本的に上から見ていきます。例えばLiveDataを観測する処理にバグが入っているとわかってはいるが、修正をしようとすると上から順番にコードを読むため、40行ほどのコードを読まないといけません。人間の頭の中のメモリは限られているので、目的の場所に素早く到着し、余計な情報は入れないでバグを修正したいです。そのために処理を関数に分けます。

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        DaggerMainActivityComponent.factory()
                .create(this, this)
                .inject(this)
        super.onCreate(savedInstanceState)

        viewBinding = ActivityMainBinding.inflate(layoutInflater)
        setContentView(viewBinding.root)

        createNotificationChannel()
        registerPackageAddedReceiver()
        setupAd()
        setupActionBar()
        setupNavigationDrawer()
        checkInAppUpdates()
        observeViewModel()
        loadIsFirstLaunch()
    }

    private fun createNotificationChannel() {}
    private fun registerPackageAddedReceiver() {}
    private fun setupAd() {}
    private fun setupActionBar() {}
    private fun setupNavigationDrawer() {}
    private fun checkInAppUpdates() {}
    private fun observeViewModel() {}
    private fun loadIsFirstLaunch() {}
}

このコードを上から読んでLiveDataの観測処理に辿り着くには15行ほどのコードを見て、observeViewModel()関数にコードジャンプすれば目的のコードが見れます。このように関数を分けることで目的のコードに辿り着く手間が格段に少なくなります。見るべきファイルが多ければ多いほど関数を分ける意味がボディーブローのようにジワジワ聞いてきます。パッと見てなんのコードが書かれているかわからないコードは見通しが悪いので関数にわけましょう。


オーバーエンジニアリング問題

Gigazineさんで良い記事がありました

引用 : https://gigazine.net/news/20211126-overengineering/

◆オーバーエンジニアリングの影響

「さらに、複雑なコードはテストや修正が困難なので、メンテナンスコストもかさむことになります。」

要するにテストコードやドキュメントが無いプログラムは後世で負債化する可能性が高く、小さい修正のはずが大きな事故になってしまったりします。また修正するときのコストが大きくなってしまい、大した修正でなくても何日もかかったりしてしまいます。

記事内のグラフがとても良くできていて自分が今どのあたりにいるのか自身でわかるのではないでしょうか。

2021年現在のAndroidアプリの開発状況で言うとViewModelが正しく扱えて画面回転に対応できており、最低限ViewModelのテストコードとFragmentのテストコードが無いプロジェクトは負債プロジェクトと言っても差し支えないかなと思います。

別の記事でコードの見通しやシンプルにする方法なども書いていきたいと思います。