FactとTheoryの違いについて考える
FactとTheoryは何が違うのか?
具体的にはテストメソッドが引数を持てる/持てない、といった違いがあるが、なぜFactは引数を持てないのか?(なぜTheoryは引数を持てるのか?)について考えた。
Fact
- 事実
- テストコードには、始まりから終わりまで何が起こるか(事実)を記述する。
- ストーリー、シナリオなどと言い換えてもいいかもしれない。
- よって、外部から引数が渡されることはない(Factの中で完結する)。
Theory
- 理論
- テストコードには、抽象化された仕組み(理論)を記述する。
- 法則、ルールなどと言い換えてもいいかもしれない。
- よって、外部から引数を渡して理論通りに正しく動くかを検証する。
Theoryの方はテストコード自体がビジネスロジックの性質を持つのではないかと感じた。
ビジネスロジックを個別のクラスとして定義する場合はFactで記述する方が多いのかなと思う。 1つのFact=1つのテストシナリオ、というイメージか。
[Fact] public void MyTest() { var input = ...; var output = service.Method(input); Assert.Equal(...); // ... }
一方で、ステートレスな演算をテストするような場合は、Theoryがよいかもしれない。
public class Point { // ... public static Point operator +(Point a, Point b) => new Point(...); // ... }
上記のような演算をテストしたい場合は
[Fact] public void AddPoint() { Assert.Equal(new Point(...), new Point(...) + new Point(...)); Assert.Equal(new Point(...), new Point(...) + new Point(...)); // ... }
よりも
[Theory] [MemberData(nameof(MyOperatorTestSources))] public void AddPoint(Point a, Point b, Point c) { Assert.Equal(c, a + b); } public static IEnumerable<object[]> MyOperatorTestSources() { yield return new[] { new Point(...), new Point(...), new Point(...) }; yield return new[] { new Point(...), new Point(...), new Point(...) }; // ... }
のほうがテストの意図を適切に表現できていると思う。
いずれにせよテストとして実施すべきことはどちらの属性でも実現できる。
どっちが読みやすいか、書きやすいか、テストケースの管理がしやすいか、というよりは、テストコードの性質・意図を説明する属性(まさに属性)である、と考えるのが適切だと思った。
自分をチームの単一障害点にすると、重要人物であるかのような錯覚が生まれる。
以下のように振る舞うことで、自分がチームの中心人物であるかのような印象を与えることができる。
- 業務知識や運用のボトルネックを自分のところに集中させる。
- ドキュメントを作らない、訊かれたら答える、などにより「〇〇さんに聞かないと分からないこと」を多く作る。
こうすると、周りはみんな何かあったら自分のところに集まってくるので、「自分はチームにとって必要不可欠なんだ」「重要なポジションであるぞ」と思えてくるし、 実際、周りも「あの人はチームの中心人物だ」「あの人がいなくては業務がまわらない」という評価をしがちになる。
でも、そういうチームってどうなんだろう。
特定のサーバ1台のみに業務アプリケーションがデプロイされていて、ローカル(下手すりゃメモリ上だけ)に重要なデータを保持している。
バックアップも冗長化もしていない。
そんなシステム構成をよしとするエンジニアはそうそういないと思うのだけど、チーム構成では割とよくあるように思う。
四の五の言っていられない、何としてものし上がっていかなくてはならない、みたいな場面であれば、確かにそういう戦略もあるんだろうけれども、 自分をチームの単一障害点にすることで人材としての評価を得ようというのは、あまり健全な方法とは言えないんじゃないかな、と私は思う。
とはいえ、「自分がいなくても大丈夫なようにチームを作れる人」が果たして評価されるかっていうと、そういう評価制度を整えるのは難しいよねぇ。
(余談)
サーバに例えるなら、本体がハイスペックであること、処理能力が優れていること、そういった研鑽による交換不可能な強みは評価されるべきものだと思うし、スペックやスキルがオンリーワンであることは素晴らしいことだとも思う。
error NU1101: Unable to find package {MyPackage}. No packages exist with this id in source(s): nuget.org [....sln]
GitHubActionsで.NET Coreアプリケーションをビルドしようとすると、自前のNuGetサーバからパッケージを取得できない。
構成
自前でNuGetパッケージを作成し、nuget.orgではなく自身で管理するサーバに配置して利用している。
[image(気が向いたら描く)]
事象
以下のようなworkflowを作成して、.NETのコードをビルドしようとする。
jobs: build: runs-on: ubuntu-latest steps: - ... - name: Build run: | cd ./src/... # solution directory dotnet build
以下のようなエラーが起こる。
dotnet build ... /home/runner/work/....csproj : error NU1101: Unable to find package {MyPackage}. No packages exist with this id in source(s): nuget.org [/home/runner/work/....sln]
対応
dotnet build
を実行する前に、 dotnet restore
を実行する。
その際、 -s|--source
オプションで自前のNuGetサーバを指定する。
(NuGetサーバのURLは環境変数に設定しておく)
jobs: build: runs-on: ubuntu-latest steps: ... run: | cd ./src/... # solution directory dotnet restore -s https://api.nuget.org/v3/index.json -s ${MY_NUGET_SOURCE} dotnet build env: MY_NUGET_SOURCE: ${{ secrets.MY_NUGET_SOURCE }} # https://mynugetserver/nuget
ハマったところ
以下の対応で解決しなくて、しばらくハマってました。
NuGet CLI ソースコマンド | Microsoft Docs
nuget sources Add -Name "MyServer" -Source \myserver\packages
備考
NuGetサーバに認証をかけた場合は検証していません。
子どもの絵本をTrelloで管理する
構成
リスト
- 持っている絵本
- 現在自宅にある絵本を追加していきます。
- タイトル順に並べています。(重複購入を防ぐために探しやすくする)
- 絵本の表紙をカバー画像にしていますが、スクロールが長くなってきたのでそのうち解除するかもしれません。
- 定期配本予定
- 童話館による定期配本サービスを申し込んでいるので、その予定をリストしています。
- 届いたら、「持っている絵本」リストに移動させます。
- 気になる絵本、欲しい絵本
- 書店やネットで見かけた、良さそうな絵本を追加していきます。
- 買ったら、「持っている絵本」リストに移動させます。
嬉しい点
気になった絵本を記録できるのが嬉しい
Twitterなどでしばしば「この絵本いいぞ」みたいなのが流れてくるので、忘れないようにカード化しています。
書店に行った際に、「そういえばこの間話題になってた絵本って何だっけ」と思った時に確認ができます。
書店で見かけた絵本を安心して購入できるのが嬉しい
「この絵本うちにあったかな」と思った時に確認ができるので、安心して購入できます。
実家から絵本が送られてくるのが嬉しい
実家の親とこのボードを共有しているので、探して買って送ってくれることがあります。いつもありがとうございます。
所感
Trelloの共有機能をうまく利用できていると思います。