yukke色々

プログラムとかお絵描きとかするエンジニア

自動テストを実施していない会社の管理職の見解とその背景

概要

TDDが提唱されて長い。が、会社では未だにすべてのテストを自動で行っている。

Excelエビデンスを貼るのに飽きてきたため、上司に手動テストをやり続ける意味を聞いてみた。
大分前に下書きで温めていた内容だけど、今後になんか役立つカモしれないので、まとめる。

前提条件

  • 単体テスト結合テスト、総合テストを行っており、その全てを手作業で行う。
  • 試験方案(試験の手順が書いてある)にチェックをつけたり、Excelにスクショを貼り付けたりする。
  • 単体テストでは、ステップ実行してif分岐やswitch分岐を網羅しているかを確認し、印刷したソースコードにマーカーを引く。
  • 自動テストをやろうとした動きは今までにあったらしい。
  • オンプレミスで動作しているシステムが殆どのため、CD/CIは無い。
  • テストはソースを書いたプログラマが行う。

上司の考え

「昔から手動だし、委託先にも同じように指示している」

弊社では少なくとも20年以上前から手動でのテストを行っていたらしい。
開発作業を外部委託することもあるが、その際にも委託先に手動テストをお願いしているとのこと。
色々な要因が作用して、自動テストの導入に至ることが無かった。

「手動で行うことで、プログラマが自分のソースに責任感を持つようになる」

軽く手動テストの概要を書くと、以下のような感じ。

  1. コードを書いた人間が、IDEでステップ実行をしながら、カバレッジ(網羅性)を見ていく。
  2. 並行して、印刷したソースコードに一行一行マーカーを引いて確認する。

もちろんこのテストに入る前にコードレビューを通しているが、テスト中にバグが発覚する事も頻繁にある。
その場合はまた修正した内容をレビューして反映してテストをやり直す。
さすがに時間がかかるので、慣れていない私は「えー」と思っていた…。

「テストコードを書くコストについて、顧客が納得しない。説明できない。」

これは何となく想像がつく。
テストコードを書く予算を見積もったとして、お客様に説明する必要がある場面。

「今まで手動でやっていたテストを自動でやりますよ。テストコード書くのでその分のお金を下さいね。」

などと説明して、お客様に納得させるのが難しいとのこと。
特に、親会社などと十数年以上の付き合いがあり、開発や保守のやり方も固定化されている場合は、こういうのが多いのかな。と感じる。
今までと違うやり方ということに対して拒否感を示すことが予想される。

「人の目で確認した方が確実で、結局は手動テストに落ち着くと思う」

この言葉を聞いた辺りから、社内で自動テストを推進するのは無理かもしれないと思った。
人による確認は限界がある。
同じテストを手動で10回ほど人にさせるのと、自動で実行するのでは、どう考えても人にさせる方が不安だと思う。何より作業者は疲れる。

「テストコードの品質はどうやって担保するのか分からない」

説明の中で、製品コードの品質をテストコードで担保することは理解して貰えたものの、テストコードの品質をどうやって担保するのか聞かれた。
正直ここは悩みどころです。おそらくコードレビューをやるしかないのでしょうが。

私はどうしたか

既存のシステムに自動テストを導入するのはあきらめた

以下の理由や上司の考えから、既存のシステムに自動テストを導入するのはやめた。

  • 既存のシステムに自動テストを導入するのは上司から上記理由で拒否される可能性がある。
    • 既存のコードはテストコードが書きづらい。
    • 既存のコード量が膨大すぎてテストコードどころの話ではない。
    • 得られる利益が無い。

新規のシステムを開発する際に自動テストを書くようにした

  • 新規システムだと、顧客への説明が比較的楽になる。
    • 既存テストをコネコネするよりもコストは少なくて済むから。
    • あと、「手動だと今後のリリースにかかる時間が増えますよ。」と言ってしまえるから。

どうやって上司を説得するか

以下のことを適宜説明すればよいと思う。

  • 作って終わりのシステムではなく、育てていくのであれば、素早く検証できるテストコードが必要であること。
  • 手動テストはミスが起きる可能性が量と時間とともに増加する。
  • ソフトウェアにおけるテストは、自動テストがデファクトスタンダードであること。

あとは、自動テストの導入について課題と認識している方が他にいる場合、
組織に自動テストをやる文化を根付かせるにはどうしたらいいかを一緒に考えるのが大事だと感じた。
小さい範囲でテストコードを書いてみて、結果を上長に見せて良い反応を貰えたら、少しづつ範囲を広げていくのが安全なのかなあ。

AWS EC2のインスタンスタイプを初出の年毎にまとめた

概要

2022年12月時点での情報です。

あまりにもインスタンスタイプが多いので、各インスタンスタイプのざっくりした用途と、各シリーズの最新インスタンスタイプを知っておくために作った。

元となる情報は、AWS公式やAWS社員のブログとかからかき集めた。 インスタンスタイプの名称については、既に沢山の情報があるので「今更解説することもないかな」と思う。

Google Spread Sheetにまとめたよ

Excelに貼りたいとか有ればこちらからどうぞ。

https://docs.google.com/spreadsheets/d/1NYh0cfzQyUze3PSGxi79g6YR2rJLYx2tq2jF7rfDGFE/edit?usp=sharing

世代表

西暦 用途 初出 2006 2007 2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022
Mシリーズ 汎用 2006 m1 m2 m3 m4 m5 m5d, m5a m5ad, m5dn, m5n, m6g, m6gd m5zn m6i, m6a
Cシリーズ コンピューティング最適 2008 c1 cc1 cc2 cr1, c3 c4 c5 c5d, c5n c6g, c6gd c5a, c6gn c6i c7g, c7gn
Tシリーズ 汎用 2010 t1 t2 t3 t3a t4g
Hシリーズ ストレージ最適 2012 hi1, hs1 h1
Gシリーズ 高速コンピューティング 2013 g2 g3 g3s g4, g4dn g4ad g5, g5g
Iシリーズ ストレージ最適 2013 i2 i3 i3en i4i
Rシリーズ メモリ最適 2014 r3 r4 r5, r5d, r5a r5ad, r5dn, r5n, r6g, r6gd r5b r6i r6a
Dシリーズ ストレージ最適 2015 d2 d3, d3en
Xシリーズ メモリ最適 2016 x1 x1e x2gd x2idn, x2iedn, x2iezn
Pシリーズ 高速コンピューティング 2016 p2 p3 p3dn p4
Fシリーズ 高速コンピューティング 2016 f1
Zシリーズ メモリ最適 2018 z1d
U-TBシリーズ メモリ最適 2018 u-6tb1, u-9tb1, u-12tb1 u-18tb1, u-24tb1
Aシリーズ 汎用 2018 a1
INFシリーズ 高速コンピューティング 2019 inf1 inf2
MACシリーズ 汎用 2020 mac1
Imシリーズ ストレージ最適 2021 Im4gn
Isシリーズ ストレージ最適 2021 Is4gen
DLシリーズ 高速コンピューティング 2021 dl1
Trnシリーズ 高速コンピューティング 2021 trn1
VTシリーズ 高速コンピューティング 2021 vt1
HPCシリーズ コンピューティング最適 2022 hpc6a, hpc7g

参考

AWSのチーフエバンジェリストをしているJeff Barr氏のブログ。常に更新している訳ではなさそう。 EC2 Instance History

上記ブログの最後の方に別のページへのリンクが有った。

PS – The EC2 Instance Timeline shows this data in another way. Be sure to check it out!

AWS EC2 instance timeline

こっちはGitHubで管理されているようで、Nicolas Rollierさんが更新しているらしい。 json形式でデータを取得することが出来る。整形してみると良いかもしれない。

ASP.NET Coreで作成したAPIをBlazorから呼び出す

個人開発でBlazorを扱っている最中。

サーバ側(Blazor Server)からデータを取得するためのAPIを作成して、クライアント側(Blazor Web Assembly)から作成したAPIを呼び出して画面に表示してみた。

メモのようなもの。


使用したもの

.NET 6.0
Microsoft.AspNetCore.Components.WebAssembly 6.0.8 Microsoft.AspNetCore.Components.WebAssembly.DevServer 6.0.8 Microsoft.AspNetCore.Components.WebAssembly.Server 6.0.8 Microsoft.EntityFrameworkCore 6.0.8 Microsoft.EntityFrameworkCore.Sqlite 6.0.8 Microsoft.EntityFrameworkCore.Tools 6.0.8


プロジェクトの構成

  1. プロジェクト名.Client.csproj
  2. プロジェクト名.Server.csproj
  3. プロジェクト名.Shared.csproj

Clientでは画面の表示とAPIの呼び出しを行う。HTMLとか書くところ。

ServerにはAPIを作成する。今回はREAD(GETメソッド)のみ。開発が進めば他のメソッドのAPIも作成すると思う。(希望)

Sharedには、ClientとServerで共有するデータクラスを作成する。

イメージとしては、こういう感じ。

データの流れのイメージ

Sharedは、その名の通りServerとClientで共有して使用するクラスを配置する。

今回は、①EntityFramework Coreで使用するEntityとして使用しているのと、②クライアント側で受け取ったJSON形式のデータをデシリアライズするのに使用している。


データモデルの用意

以下はSharedに配置したデータモデルの一部です。

namespace プロジェクト名.Shared.Entities;

public class MUser
{
    [Key]
    [Column(Order = 1, TypeName = "varchar(15)")]
    public string UserId { get; set; }

    [Column(Order = 2, TypeName = "varchar(50)")]
    public string Name { get; set; }

    [Column(Order = 3, TypeName = "varchar(128)")]
    public string MailAddress { get; set; }
}

APIの用意

次に、Server側にAPIを作成しておく。

「全ユーザーの情報を取得できるAPI」と、「指定したidのユーザーの情報を取得できるAPI」の2つを用意した。

using Microsoft.AspNetCore.Mvc;
using プロジェクト名.Server.EntityFrameworkCore;
using プロジェクト名.Shared.Entities;

namespace プロジェクト名.Server.Controllers;
    
[Route("api/[controller]")]
[ApiController]
public class UsersController : ControllerBase
{
    private readonly ExampleDbContext context;

    public UsersController(ExampleDbContext context)
    {
        this.context = context;
    }

    /// <summary>
    /// 全ユーザーリストを取得する
    /// </summary>
    /// <returns>全てのユーザーのJSONデータ</returns>
    [HttpGet]
    public ActionResult<IEnumerable<MUser>> Get()
    {
        return context.Users;
    }

    /// <summary>
    /// 特定のユーザーIDを持つユーザーを取得する
    /// </summary>
    /// <param name="userId">ユーザーID</param>
    /// <returns>ユーザーIDが一致したユーザーのJSONデータ</returns>
    [HttpGet("{id}")]
    public ActionResult<MUser> Get(string id)
    {
        return context.Users.Find(id);
    }
}

DbContextの用意

EntityFrameworkでDB(SQLite)とやり取りするために、Server側にDbContextクラスを継承したクラスを作成します。

この辺りは割とドキュメントが転がっているので楽に記述できる。

namespace プロジェクト名.Server.EntityFrameworkCore;

public class ExampleDbContext : DbContext
{
    public ExampleDbContext(DbContextOptions<ExampleDbContext> options)
        : base(options)
    {
    }

    public DbSet<MUser> Users { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<MUser>().ToTable("m_user");
    }
}

あと、Blazor ServerにサービスとしてExampleDbContextを追加する必要があるので、「Program.cs」内の適当なところに以下のコードを追加する。

以下のコードでは、サービスを追加すると同時に接続文字列を設定ファイルから取得している

builder.Services.AddDbContext<ExampleDbContext>(options
    => options.UseSqlite(connectionString: builder.Configuration.GetConnectionString("ExampleDbContext")));

APIの呼び出し

Client側の任意のrazorページに、データを表示する部分と、APIを呼び出すコードを書く。

@inject HttpClient Http // Http要求を使えるようにする

<h4>ユーザー一覧</h4>

@*ループで全ユーザを表示*@
@foreach (MUser user in users)
{
    <p>ユーザー名:@user.Name</p>
    <p>@@@user.UserId</p>
    <p>メールアドレス:@user.MailAddress</p>
}

@code { 
    private MUser[]? users; // デシリアライズ後のデータを入れておくトコ
    // private MUser? user;  // ユーザーIDを指定するときはこう

    [Parameter]
    public string userId { get; set; } // パラメータ格納用の変数として使用する。

    // APIを呼び出すコード
    protected override async Task OnInitializedAsync()
    {
        users = await Http.GetFromJsonAsync<MUser>("api/users/"); // 全ユーザーを取得

        // ユーザーIDを指定するとき
        // user = await Http.GetFromJsonAsync<MUser>("api/users/" + userId); 
    }
}
  • GetFromJsonAsync()は、APIの呼び出しと、JSON形式の戻り値のデシリアライズを、合わせてやってくれる優れモノ。エライネ

  • <MUser>という風にクラスを指定すれば、指定したクラスにデシリアライズする。

  • OnInitializedAsync()は、razorページが初期化されたときに呼び出されるメソッド。この場合、ページが初期化されたときにAPIを呼び出して、変数usersに結果を保持している。


こんな感じで表示される。(分かり易いようにCSSを適用しています。)

表示される画面


まとめ

  • 「こんなに簡単にwebページが作成できていいのか…」という感じ。
  • builer.Service辺りはまだあまり良く解ってない。
  • 公式ドキュメントに、ベストプラクティスがチョット載っているので、読んでおきたい。
  • ASP.NET Core MVCよりも簡潔に書ける。
    • あんまりドキュメントが出揃ってない気もする。というかBlazorってあまり名前通って無いのか。
  • 記事内には書いてないけど、今回初めてMigration機能を使用した。メッチャイイ。
  • AWS上に公開する場合、幾らでも弄り甲斐がありそうでワクワクする。

職場のイライラを自宅に持ち帰りたくないねという話

エンジニア職として働いていると、常に勉強をし続けなければならないのは、入社してすぐに理解した。

それと同時に、常に新しい技術が出てくるこの業界で長く過ごしていると、新しい技術を学ぶのに及び腰になる人が多いこともすぐに分かった。

私の周りには、親よりも年が上のエンジニアがうじゃうじゃいる。その人たちの過半数は、新しい技術に対して及び腰であったり、仕事に対して改善意識を持つことに対して億劫になっている人が多い。

これはもう仕方のないことかもしれない。

失敗や挑戦が許されるのは若いうちだけ、とかいう価値観がそうさせているのかしら・・・

 

新入社員は目をキラキラさせながら入社してくるのだが、少しすれば会社の嫌なところが目に付くようになる。私も例に漏れず。

無駄なことだとわかっているにも関わらず、本気で改善に取り組む姿勢が無い。

「再発防止に努める」に始まり、「朝礼で標語の唱和を実施する」に行き当たる国産企業お得意のアレである。

 

つい最近びっくりしたのは、他部署の不具合対応の資料を見ていると、

ソースコードの変更差分(diff)を取得

・取得した変更差分を紙媒体に印刷する

・印刷した紙に上長の承認印を押印する

・押印した紙をスキャンして電子ファイル化

ということを平然とやっていた。ヤバい。

 

私は入社した時から、"めんどくさいな"と思った業務に対して「それってなんでやるんですか?」と聞きながら仕事しているけど、帰ってくる返答に納得できることの方が少なくて辟易する。

20年前から同じことしてるなこの人たち。

Githubの使い方も知っている人の方が少ないし、「VSCode?フリーソフト危なくない?」みたいな人もいた。

数か月前には、会社の上層部が「DX」をやはり持ち出してきた。バズワード化して既に定義が曖昧になっているものを、何も知らない現場の人間に教えようとしても混乱するだけなのに。どうせ外部のコンサルに吹き込まれたのだろう。

おじさんがやっている仕事に対していろんなことが目に付いてしまって、ソワソワしてしまうな。

 

健全に仕事がしたいのに、削られてしまってヨクナイ

イライラしていることが多いので、そういうのを解消する暮らし方をしないとかなりマズいな、と思った。

知らない人に心の中でめちゃくちゃ悪口言ってる

この記事は、noteから移行したものです

 

1日にパスタを2度茹でて 朝と夜にかき込んだ体調の悪い上司はいつも仕事をしているのかしていないのか分からない。私はいつも楽しそうにしている と褒められるが、書いたコードが思った通りに動かないと眉間に皺が寄っている。

1日の内、数十回のビルドを繰り返しても上手くいかないと 家に帰って皿を洗うのがとても難しい。

食後にパスタのソースが皿にこびりつかないように水を注ぐので手一杯。何もない壁をぼんやり見ていることが減った。

鏡を見ながら小躍りしたり、効いているのか分からないストレッチをしているのは楽しい。

 

上司が帰った後の一人の部屋で 画面に悪態をついている時は本当に焦っている。仕事が虫のよう。

それと朝は 玄関の錠を閉めて ポケットに入れた鍵が冷たいので、握って温めるか手に触れないようにうまく入れておくかばかりに気を使う。急いで家を出た日は、大体靴下にズボンの裾が挟まっていたりリュックが全開になっている。

中途半端であることを認めたくなく 色々頑張ろうとしているため、鏡の前で変な顔を一通りやってみた後にニコニコしていたりする。変な顔で本気を出せば誰にも負けないと思っているから。

なんとかなってほしい事ばかりではある。

普段怒りを露わにしないのは恥ずかしいため。

嫌いなのは咀嚼音と大きな声とゲップと咳とズズズ…と音を立てて飲み物を飲む人 普通に迷惑だし不快な上に当人はなんともない顔をするので無理。好きな人なら別に良いが。

そういう時はやっぱり眉間に皺が寄って 心で悪口を言っている。そんな気持ちにさせたことにすら腹を立てている。10分経つと忘れているものですが。

日一日画面を見つめているので目がギュウギュウする。完璧な日はもうそうそう無いのだろうね。

 

しかし、今日は唐揚げだ‼️

何とかやっている

この記事は、noteから移行したものです

 

なんか 2か月に一度はnoteで文章をまとめておきたくなる習慣になっているらしい 俺は。

2,3か月前にパソコンと一緒に買った無線キーボードはたまに反応しないしたまにチャタリングを起こして少し 文字が打ちにくい。

今年は、年始から散々な目に遭って希望を持てずにいたけど、よい出会いがたくさんあったから 結局いい年になっている。多分今までで一番成長した年かもしれない。近年のおれは、年明けにその年の目標を決めるようになっている。

2021年の目標は、伝えたいと思ったことはその日のうちに伝えることだったと思う。その通りにできた場面が全部じゃないけど7割くらい出来ているんではないかな。年の始めに強く思っていても、寝て起きたら大分忘れているので、紙に書いて部屋に貼っておくのがいいんだろうな多分。このnoteを書き始めるまでは完全に忘れていたので。

今年の二月は友達が出来た。自分が持っていない知識や感性を教えてくれている。高校の放課後みたいなことをずっとしている。

今年の三月から絵を再開した。まだ全然うまくなっていない 時間の使い方が下手だから。やらないといけないこととやりたいこと沢山ある。

今年の四月は絵を描くか友人と遊ぶかしていた。新しい仕事が本格的に動き始めたのでダルかった。でもゴールデンウィークは楽しかった。年内に閉園する遊園地に行った。

今年の五月も絵を描いていた。黒いマットのネイルをするのにハマっていたので、手と足の爪がずっと黒かった。実家の家族に初めて唐揚げを振舞った。

今年の六月はメイドコスとかしてた。隣のうるさい人が引っ越してストレスが少し軽減。相変わらず絵を描いている。

今年の七月に腰の痛みが限界を迎えた 家でも会社でも座っているからです。整骨院に通い始めた 今も通っている。だいぶ楽になった 絵も描いている。

今年の八月には 友達ときれいな海に入ってきれいな山に行った。別の友達が現場職に転職し 肌が焼けて少年兵みたいだった。お盆は祖母の家でバーベキューとお墓参りをした。絵も描いた。

今年の九月のことはあまり覚えていない 絵は描いていた。ジョジョを見た気がする。時間がもったいなくて、毎日頭だけを洗って会社に行った。

今年の十月は友達の依頼で絵を描いた。絵がレベルアップしたのを実感したけど、この辺りから忙しくてあまり描いてない。今まで見たことない人に会った 外に出る機会が増えた。

今年の十一月は恋人ができた 尊敬する人。仕事も忙しくなった。初めてのことが多かったけど楽しんでやっている。ひいおばあちゃんが居なくなってしまったのをきっかけに、何年も顔を合わせていない親戚同士が同じ場所に集まった。

今年の十二月はまた忙しくなりそうだけど年末の空気は大好き。ワクワクする。今年のクリスマスはチーズケーキを作ります 久しぶりに。一昨年の目標が チーズケーキを一人でワンホール食べることだったので、何度か作った経験がある。でもオーブン買わなきゃ作れない ウチはオーブンが無いんだ キャーーーーーー!

今まで年内に年内のことを終わらせた経験がないので今年は早めに動きます 師走だし。

おわり