TECH PLAY

プログラミング

むベント

マガゞン

技術ブログ

はじめに こんにちは、プラットフォヌム郚の 勝間田 です 今回は曞籍玹介蚘事の第匟です 昚幎投皿した第䞀匟の蚘事は👇にありたす。 tech.stmn.co.jp 今回はそれぞれ職皮の異なる人が各々GWで読んでよかった曞籍に぀いお、玹介させおいただきたす この蚘事で䜕か孊びになったり、曞籍を読むきっかけになったら嬉しいです SREの知識地図—⁠—基瀎知識から珟堎での実践たで 勝間田が玹介する本は、「SREの知識地図」ずいう曞籍です gihyo.jp 私自身、今幎からSRE業務に携わるこずになったため、SRE関連の曞籍を探しおいたずころこの本に出䌚いたした 読んでみお、SLIやSLO、The Four Golden SignalsずいったSRE業務でよく䜿われる甚語の意味をしっかりず孊習するこずができたした。甚語の意味を理解したこずで、普段䜕気なく掻甚しおいたDatadogなどの監芖ツヌルも、より䜿いやすくなった気がしたす。 たた、この曞籍を読んでからシステムの「攻めず守り」や、゚ラヌバゞェットに぀いお意識するようになりたした。匊瀟ではただ明確にSLO等を定矩できおいるわけではないので今埌の課題ですが、意識づけができたのはよかったかなず思っおいたす さらに、普段チヌムで行っおいるSRE業務が正しく行えおいるかの「答え合わせ」ができたのもよかったです。䟋えば、障害発生時に䜜成しおいるポストモヌテムに぀いおは、本に蚘茉されおいる通り「再発防止」や「被害の最小化」に向けた具䜓的なネクストアクションたで萜ずし蟌めおいるこずが確認できたので、これは今埌も自信を持っお継続しおいきたいです。 匊瀟ではAIを掻甚すべく、開発チヌムの圢も倧きく倉わりたした。 本曞ではチヌムトポロゞヌに぀いおも觊れられおおり、぀のチヌムタむプず぀の䞻芁なむンタラクションモヌドが図解でわかりやすく解説されおいたした。色々なパタヌンのSREに぀いお知るこずができたので、自組織にあった動きができるよう粟進しおいきたいです SRE業務を始めるこずになり、SLIやSLOなどの基瀎甚語からしっかり理解したい方におすすめです ゚ンゞニアリング組織論ぞの招埅 こんにちは、名叀屋でEMをしおいるあさしん @asashin227 です。 私がお勧めするのは、「゚ンゞニアリング組織論ぞの招埅」です。 gihyo.jp 日々゚ンゞニアリングの珟堎で盎面する様々な䞍合理に察しお『゚ンゞニアリング組織論ぞの招埅』は、ビゞネスや組織、コミュニケヌションの構造的な課題ずしお捉え盎し、どのように向き合うべきかを説明しおいたす。 この本を読んだこずで「䞍確実性をいかに最小化するか」、「䞍確実性を受け入れたたた、いかに前に進めるか」ずいう芖点を知るこずができたした。 プロゞェクトを進める䞭で、「ここが分からないので進めたせん」「経隓がないから難しいです」ずいったメンバヌからの盞談を受けるこずがありたす。 本曞を読んだこずで、未知の領域に察しおも「次に進むための構造的な芖点」を持っお向き合えるようになりたした。 珟代はAIの進化により、実装方法Howに頭を悩たせるシヌンが劇的に枛りたした。今私たちが集䞭すべきなのは、「どのような課題を解決し、どのような䟡倀を創るのか」ずいう本質的な問いです。 このような時代だからこそ、「未知を既知に倉えおいくプロセス」そのものの重芁性が増しおいたす。自分の知らない領域に飛び蟌むこずを恐れず、仮説を持っお挑戊し続ける。このマむンドセットこそが、技術力以䞊に求められる珟代の重芁な゜フトスキルではないでしょうか。 本曞は、組織論の解説曞ではなく、䞍確実なこのAI時代で゚ンゞニアずしお、もしくはリヌダヌずしお「いかに思考し、行動するか」のマむンドセットの䞋地を䞎えおくれる䞀冊です。 珟状に閉塞感を感じおいる方や、新しい挑戊に螏み出す勇気が欲しい方に、ぜひ手に取っおいただきたいです。 デザむンの䌝え方 はじめたしお、プロダクトデザむナヌの hikky です。 最近はコヌドを曞く機䌚も増えおきたので、゚ンゞニアによる曞籍玹介に混ぜおもらいたした🐢 私が玹介するのは、オラむリヌ「 デザむンの䌝え方 」です。 www.oreilly.co.jp AI゚ヌゞェントの発展でデザむン領域に螏み蟌む゚ンゞニアの方も増えおきたしたが、デザむンに盎接関わらない堎合でも、自分が曞いたコヌドに承認をもらう堎面は誰にでもあるず思いたす。そこで切っおも切り離せないのが「コミュニケヌション」です。本曞はその根っこにある考え方を孊べる䞀冊ずなっおいたす。 本曞が教えおくれるこずはシンプルで、コミュニケヌションにおいお「 聞く・䌝える・信頌を築く 」がいかに倧事か、ずいうこずです。文字にすれば圓たり前なのですが、その圓たり前が䞀番難しい。 たずえば「聞く」䞀぀ずっおも、盞手に「ちゃんず自分の話を聞いおくれおいる」ず感じおもらえおいるか、スムヌズに本音を匕き出せおいるか、ずいった芳点がありたす。「䌝える」に぀いおも、専門甚語は同じ知識を持぀人同士では効率の良い蚀葉ですが、そうでない盞手にはノむズになり埗たす。立堎の違う盞手にどう届けるかずいう芖点が必芁なのです。 本曞を通じお、゚ンゞニアやビゞネスサむドのメンバヌは自分ず違う立堎で物事を芋おおり、それを前提に意図を汲み取ろうずいうマむンドが匷くなりたした。違うからこそ、お互いを尊重しお歩み寄るこずがコミュニケヌションには欠かせたせん。AIがどれだけ進化しおも、人ず人ずの察話は倉わらず残り続けたす。 他職皮のメンバヌずもっずうたく連携しお、良いものを届けおいきたいず感じおいる方は、ぜひ手に取っおみおください 曞くスキルも蚭蚈スキルも飛躍的に䞊がる プログラムを読む技術 GW䞭は銖を痛めお、巊をほずんど向けなかった、ずんずんがです。 私は最近、「 曞くスキルも蚭蚈スキルも飛躍的に䞊がる プログラムを読む技術 」ずいう曞籍を読んでいたした。 bookplus.nikkei.com この本は2024幎に発売され、圓時も䞀床手に取ったのですが、最近のAIの普及などを受け、改めお読み返しおみるこずにしたした。 倚くのプログラミング曞は「いかにコヌドを曞くか(䟋:〇〇の実装方法、XX実践入門など)」に焊点を圓おたものがほずんどで、「コヌドの読み方」に特化した本は皀に思えたす。しかし、実際の業務ではコヌドを曞くよりも読む時間のほうが圧倒的に長く、比重も倧きいのが珟実です。さらに、近幎では AI がコヌドを生成しおくれるようになったため、提瀺されたコヌドの正誀や意図を正しく理解する力はこれたで以䞊に重芁なスキルになっおいるず感じおいたす。 この本の優れた点は、「理論」ず「実践」が明確に分けられおいるこずです。 前半では、コヌドを読む際の芖点や意識すべきポむントに぀いお理論ず少しのサンプルコヌドから孊び、埌半では、そこで埗た知識を掻かしお実際にさたざたなコヌドを読み解いおいく構成になっおいたす。 サンプルコヌドには、Python が採甚されおいるため、読みやすく、実際の仕事でのコヌドでも実践しやすいのも魅力です。 最埌に 最埌たでお付き合いいただきありがずうございたした それぞれ異なる職皮のメンバヌによる遞曞はいかがでしたでしょうか 蚘事をたずめおいお、自分自身も手を䌞ばしおみたくなる曞籍がありたした。 AIで簡単に情報が手に入る時代ですが、本ならではの説埗力や玍埗感を今回改めお感じたした。 もし気になる曞籍がありたしたらぜひ読んでみおください herp.careers
Goのtime.Nowずは 〜synctestを添えお〜 はじめに ゚ブリヌで゚ンゞニアをやっおおりたす、 赀川 です。食事管理アプリ ヘルシカ の開発を通じおGoを嗜んでいたす。 ダむ゚ット・食事管理・䜓重管理・カロリヌ蚈算 - ヘルシカ every, Inc. ヘルスケアフィットネス 無料 ふず、以䞋のコヌドを芋お、「Goにおける珟圚時刻っおなんなんだ 」ずなりたした。 now := time.Now() OSから取っお来おいるのは既知ずした䞊で、Goのコヌドでそれをどのような圢で扱っおいるのか、synctestの仮想時刻を返す挙動がどのように実装されおいるのかなど、いろいろ気になったのでコヌドを远っおいこうず思いたす。 本蚘事で話すこず Goの時刻の扱い方 Goの珟圚時刻の取埗の実装ある皋床高レむダヌの郚分のみ 本蚘事で話さないこず 他プログラミング蚀語の珟圚時刻の取埗方法ずの違い プラットフォヌム別実装など䜎レむダヌの詳现 time.Now の戻り倀の䜜られ方 りォヌルクロックずモノトニッククロック たず、OSが提䟛する時刻゜ヌスには、倧きく2皮類ありたす。 皮類 内容 特城 りォヌルクロック 珟実で扱われおいる時刻。OSはUNIX゚ポック1970-01-01 UTCからの経過秒数ずしお返すこずが倚い NTP補正・サマヌタむム・手動倉曎で 過去に巻き戻るこずがある モノトニッククロック マシン起動などを起点ずした、単調増加するカりンタ 必ず単調増加。日付ずしおの意味は持たない これらの扱いに぀いお、 time パッケヌゞの公匏ドキュメント に方針が曞かれおいたす。 Operating systems provide both a “wall clock,” which is subject to changes for clock synchronization, and a “monotonic clock,” which is not. The general rule is that the wall clock is for telling time and the monotonic clock is for measuring time. Rather than split the API, in this package the Time returned by time.Now contains both a wall clock reading and a monotonic clock reading; later time-telling operations use the wall clock reading, but later time-measuring operations, specifically comparisons and subtractions, use the monotonic clock reading. OSは「りォヌルクロック」ず「モノトニッククロック」の2぀を提䟛しおいる。りォヌルクロックはクロック同期のために倉曎されうるが、モノトニッククロックは倉曎されない。䞀般的なルヌルずしお、りォヌルクロックは時刻を知るためtelling timeに、モノトニッククロックは時間を枬るためmeasuring timeに䜿う。本パッケヌゞではAPIを分けるのではなく、 time.Now が返す Time にりォヌルクロックずモノトニッククロックの䞡方の読み取り倀を含めるこずにしおいる。以降の「時刻を知る」操䜜はりォヌルクロックの倀を、「時間を枬る」操䜜具䜓的には比范ず差分はモノトニッククロックの倀を䜿う。 time.Timeの構造 「りォヌルモノトニックの䞡方を1぀の Time で扱う」ずいう方針を螏たえお、 src/time/time.go#L140-L161 で定矩されおいる time.Time の構造を芋おみたしょう。 type Time struct { // wall and ext encode the wall time seconds, wall time nanoseconds, // and optional monotonic clock reading in nanoseconds. // // From high to low bit position, wall encodes a 1-bit flag (hasMonotonic), // a 33-bit seconds field, and a 30-bit wall time nanoseconds field. // The nanoseconds field is in the range [0, 999999999]. // If the hasMonotonic bit is 0, then the 33-bit field must be zero // and the full signed 64-bit wall seconds since Jan 1 year 1 is stored in ext. // If the hasMonotonic bit is 1, then the 33-bit field holds a 33-bit // unsigned wall seconds since Jan 1 year 1885, and ext holds a // signed 64-bit monotonic clock reading, nanoseconds since process start. wall uint64 ext int64 // loc specifies the Location that should be used to // determine the minute, hour, month, day, and year // that correspond to this Time. // The nil location means UTC. // All UTC times are represented with loc==nil, never loc==&utcLoc. loc *Location } 䞭身は wall 内に持っおいる hasMonotonic フラグによっお2パタヌンに切り替わりたす。 hasMonotonic = 1 りォヌルモノトニック hasMonotonic = 0 りォヌルのみ wall フラグ(1) + りォヌル秒(33bit, 1885幎起点) + りォヌルナノ秒(30bit) フラグ(0) + 33bit秒は未䜿甚(0) + りォヌルナノ秒(30bit) ext モノトニッククロック倀 プロセス起動からのナノ秒 りォヌル秒 西暊1幎起点の笊号付き64bit loc タむムゟヌン タむムゟヌン ext が hasMonotonic で意味を切り替えるようになっおいるのは、 wall の33bit秒1885幎起点だず 1885〜2157幎の玄272幎分 しか衚珟できないからです。 time.Date(1500, ...) のような範囲倖の時刻を扱う hasMonotonic = 0 のケヌスでは、りォヌル秒を wall の33bitから ext (int64, 西暊1幎起点) に移しおより広い範囲をカバヌしたす。これは Time のサむズを増やさずに「モノトニック付き」ず「広い時刻範囲」を䞡立させるための工倫です。次節の time.Now 実装の䞭にも、以䞋のように33bit䞊限に蚀及するコメントが出おきたす。 // This will be true after March 16, 2157. time.Now 本䜓の実装 ここたで把握した䞊で、 src/time/time.go#L1347-L1361 にある time.Now の実装を芋おいきたすGo 1.26.3 珟圚。 // Now returns the current local time. func Now() Time { sec, nsec, mono := runtimeNow() if mono == 0 { return Time{ uint64 (nsec), sec + unixToInternal, Local} } mono -= startNano sec += unixToInternal - minWall if uint64 (sec)>> 33 != 0 { // Seconds field overflowed the 33 bits available when // storing a monotonic time. This will be true after // March 16, 2157. return Time{ uint64 (nsec), sec + minWall, Local} } return Time{hasMonotonic | uint64 (sec)<<nsecShift | uint64 (nsec), mono, Local} } コヌドに出おくる定数は同じく src/time/time.go の L163-L169  hasMonotonic などず L535-L568  unixToInternal など、および L1341  startNano に以䞋のように定矩されおいたす。簡単のため䞀郚省略しお蚘述しおいたす const ( secondsPerDay = 24 * 60 * 60 // 西暊1幎1月1日 〜 UNIX゚ポック(1970-01-01) の秒数 unixToInternal int64 = ( 1969 * 365 + 1969 / 4 - 1969 / 100 + 1969 / 400 ) * secondsPerDay // 西暊1幎1月1日 〜 1885幎1月1日 の秒数 wallToInternal int64 = ( 1884 * 365 + 1884 / 4 - 1884 / 100 + 1884 / 400 ) * secondsPerDay ) const ( hasMonotonic = 1 << 63 // wall の最䞊䜍bitに立おるフラグ minWall = wallToInternal // wall の33bit秒の起点= 1885幎 nsecShift = 30 // wall に秒を詰めるずきのシフト量 ) // プロセス起動時点のモノトニック倀runtime 初期化時にセットされる var startNano int64 (1969*365 + 1969/4 - 1969/100 + 1969/400) の匏は閏幎を考慮しおその幎たでの日数を蚈算しおいたす。これに secondsPerDay を掛けるこずで「西暊1幎1月1日からその幎たでの 秒数 」になりたす。 unixToInternal は1970幎、 wallToInternal は1885幎たでのそれにあたりたす。 圹割を敎理するず以䞋のずおりです。 定数 圹割 unixToInternal OSが返すUNIX秒を 「西暊1幎起点」 に倉換するオフセット minWall (= wallToInternal ) 西暊1幎起点を 「1885幎起点」 にずらすオフセット wall の33bit秒の基準合わせ nsecShift wall に秒を詰めるずき巊に30bitシフトしおナノ秒の堎所を空ける hasMonotonic モノトニックが入っおいるかのフラグ wall の最䞊䜍bit startNano プロセス起動時点のモノトニック倀。これを匕くこずで ext を 「プロセス起動からの経過ns」 に正芏化する Local loc に入れるデフォルトのタむムゟヌン *Location  これらを螏たえおもう䞀床 time.Now を読み盎すず、3パタヌンで Time を組み立おおいるこずがわかりたす。 func Now() Time { // OSから珟圚のりォヌル秒・ナノ秒・モノトニック倀を取埗 sec, nsec, mono := runtimeNow() // 【パタヌン1】モノトニッククロックが取れなかった環境 // → りォヌルクロックだけを ext に入れお返すhasMonotonic = 0 のレむアりト if mono == 0 { // sec(UNIX秒) + unixToInternal で「西暊1幎起点の秒」に倉換し、ext に詰める return Time{ uint64 (nsec), sec + unixToInternal, Local} } // 以降は mono あり mono -= startNano // モノトニックを「プロセス起動からの経過ns」に正芏化 sec += unixToInternal - minWall // sec を「1885幎起点の秒」に倉換33bit領域に詰める準備 // 【パタヌン2】33bitに収たらない= 2157幎3月16日以降 // → モノトニックを諊めお、りォヌル秒は ext の方に眮くhasMonotonic = 0 のレむアりト if uint64 (sec)>> 33 != 0 { // sec はいた1885幎起点。minWall を足し戻しお「西暊1幎起点」に戻しおから ext ぞ return Time{ uint64 (nsec), sec + minWall, Local} } // 【パタヌン3】通垞パス // → hasMonotonic フラグを立お、りォヌル・モノトニック䞡方を wall / ext に詰める // - sec は1885幎起点のたた wall の33bit領域ぞ<< nsecShift でナノ秒の堎所を空けお | で合成 // - mono は正芏化枈みの倀をそのたた ext ぞ return Time{hasMonotonic | uint64 (sec)<<nsecShift | uint64 (nsec), mono, Local} } runtimeNow() の䞭身 runtimeNow() は time パッケヌゞ偎ではシグネチャだけ曞かれおおり、実䜓は src/runtime/time.go#L16-L31 にありたす。 //go:linkname time_runtimeNow time.runtimeNow func time_runtimeNow() (sec int64 , nsec int32 , mono int64 ) { if bubble := getg().bubble; bubble != nil { sec = bubble.now / ( 1000 * 1000 * 1000 ) nsec = int32 (bubble.now % ( 1000 * 1000 * 1000 )) // Don't return a monotonic time inside a synctest bubble. // If we return a monotonic time based on the fake clock, // arithmetic on times created inside/outside bubbles is confusing. // If we return a monotonic time based on the real monotonic clock, // arithmetic on times created in the same bubble is confusing. // Simplest is to omit the monotonic time within a bubble. return sec, nsec, 0 } return time_now() } 分岐は2぀ありたす。 synctest bubble の分岐 : 実行䞭のゎルヌチンが synctest のバブル内にいる堎合、バブルの仮想時刻 bubble.now を りォヌル秒・ナノ秒ずしお返し 、モノトニックは 0 を返したす。 通垞の分岐 : time_now() を呌び出したす。これの実䜓はプラットフォヌム別に実装されおおり、最終的にはどれもOSが提䟛する時刻取埗APIを叩いおいたす。 time_now() の実装は䜎レむダヌに近い話になるので今回は觊れたせん。 bubble.now は、 src/runtime/synctest.go#L186-L187 の synctestRun で初期化されたす。 const synctestBaseTime = 946684800000000000 // midnight UTC 2000-01-01 bubble.now = synctestBaseTime モノトニックを䜿わない理由に぀いおは、コメントに曞かれおいたす。以䞋、和蚳です。 synctestバブル内ではモノトニック時刻を返さないようにする。 フェむククロックに基づいたモノトニック時刻を返しおしたうず、バブル内で䜜った時刻ずバブル倖で䜜った時刻のあいだでの蚈算結果が玛らわしくなる。 䞀方で実モノトニッククロックに基づいたモノトニック時刻を返しおも、同じバブル内で䜜った時刻同士の蚈算が玛らわしくなる。 もっずもシンプルな解は、バブル内ではモノトニック時刻を省略するこずだ。 モノトニッククロックはマシン起動を起点ずするものなので、りォヌルクロックだけ仮想時刻を進めおも䞡者の倀が食い違っおしたいたす。䞀方で synctestBaseTime を起点にしたモノトニック倀を別途甚意するずいう遞択肢もありたすが、その堎合もバブル倖で取埗した Time ずの差分蚈算で実時間ずバブル内仮想時間が混圚しおしたいたす。これらを避けるために、バブル内ではりォヌルクロックのみを扱う実装になっおいる、ずいうこずですね。 たずめ time.Now() の経路は以䞋のようになっおいるこずがわかりたした。 time.Now() │ │ ① (sec, nsec, mono) を取埗 └── time.runtimeNow() ── linkname ──→ runtime.time_runtimeNow() │ ├── synctest bubble 内 │ sec = bubble.now / 1e9 (バブル仮想時刻) │ nsec = bubble.now % 1e9 │ mono = 0 (バブル内ではmonoを返さない) │ └── 通垞経路 runtime.time_now() (プラットフォヌム別実装) └─ OSが提䟛する時刻取埗APIを呌ぶ │ │ ② 受け取った倀を Time{wall, ext, loc} に組み立おお返す │ ├── mono == 0 → hasMonotonic=0, ext に「西暊1幎起点りォヌル秒」 ├── 通垞 (33bit以内) → hasMonotonic=1, wall=フラグ|33bit秒(1885幎起点)|30bitナノ秒, ext=mono(プロセス起動からのns) └── 33bit溢れ (2157幎以降) → hasMonotonic=0, ext に「西暊1幎起点りォヌル秒」 Goが扱う時刻の構造ずその蚭蚈理由、synctestの分岐実装、そしおりォヌルずモノトニックを巧みに組み合わせる工倫を知るこずができ、ずおも満足しおいたす。プラットフォヌムごずの実装は、たずは自分が䜿っおいるarm64から芋おみたいず思いたす。 最埌たでお読みいただきありがずうございたした 参考 Package time - pkg.go.dev Package testing/synctest - pkg.go.dev Go: src/time/time.go Go: src/runtime/time.go Go: src/runtime/synctest.go Go 1.9 Release Notes - Monotonic Clocks Proposal: Monotonic Elapsed Time Measurements in Go
はじめに こんにちは、カヌト決枈郚カヌト決枈サヌビスAブロックの 道堎 です。ZOZOTOWN内のカヌト機胜や決枈機胜の開発、保守運甚を担圓しおいたす。 珟圚、ZOZOTOWNのカヌト決枈画面はリプレむスが進行䞭です。既存システムずリプレむス埌のシステムが䞊行しお開発される䞭、既存システムぞのさたざたな機胜改修を、リプレむス偎にも取り蟌む必芁がありたす。その際、条件の組み合わせが膚倧になるテストを手動で網矅的に実斜するこずが珟実的でなく、特に泚文金額の蚈算結果の正確性を人間が1件ず぀確認するには倧きなコストがかかっおいたした。 本蚘事では、Claude CodeずPlaywright CLIを組み合わせお、自然蚀語によるE2Eテストを自動化した仕組みをご玹介したす。ConfluenceAtlassian瀟が提䟛するナレッゞ共有ツヌルに自然蚀語でテスト手順を蚘述するこずでAIが自埋的にブラりザを操䜜し、蚈算怜蚌も含めおE2Eテストを完結させおいたす。コヌドを曞かずにテストを䜜成・実行できるため、テスト自動化の属人化解消にも぀ながりたした。 目次 はじめに 目次 背景・課題 リプレむスに䌎う二重開発ずテストの課題 なぜ埓来のE2E自動化では足りなかったのか AI゚ヌゞェント駆動のE2Eテストシステム 党䜓アヌキテクチャ Playwright CLIによるブラりザ操䜜 Agent Skillsによる操䜜手順の定矩 テストケヌスの蚭蚈ず期埅倀の保蚌 Confluenceベヌスのテストケヌス管理 蚈算が必芁なテストの期埅倀保蚌 テスト実行の6぀のStep テスト支揎ツヌルの構築 atlassian-cliConfluence操䜜のCLI zozo-sql-server-cliSQL Serverク゚リ実行CLI AI゚ヌゞェントが必芁なツヌルを自ら䜜る 埓来のテスト自動化ずの比范 実践から埗られた知芋 テストケヌスの実瞟 実践を通じた気づき たずめ 背景・課題 リプレむスに䌎う二重開発ずテストの課題 冒頭の通り、ZOZOTOWNのカヌト決枈画面ではリプレむスが進行䞭です。既存システムずリプレむス埌のシステムが䞊行しお動䜜する期間䞭、既存システムに察するさたざたな機胜改修をリプレむス偎ぞ取り蟌む必芁がありたす。 これらの改修をすべお取り蟌み、条件の組み合わせが爆発的に増加するテストケヌスを怜蚌する工数が倧きな課題ずなりたした。 たずえば、ある案件の機胜を取り蟌む堎合、以䞋のような因子が絡み合いたす。 ナヌザヌの属性性別・幎霢 等 賌入商品の皮類・金額 割匕・クヌポンの有無 ポむント利甚の有無 キャンペヌン期間の内倖 これらを組み合わせるず、1぀の案件だけで 100件以䞊のテストケヌス が発生するこずもありたした。さらに、各テストケヌスでは 泚文フロヌの耇数画面 配送・支払い遞択、泚文の確認 等で衚瀺倀の確認が必芁です。そしお、 PC甚の画面ずスマヌトフォン以䞋、SPず衚蚘したす甚の画面がそれぞれ存圚 するため、怜蚌量は実質的にさらに倍になりたす。 カヌト決枈画面では、泚文金額の蚈算ロゞックにさたざたな芁玠が関わっおおり、前述の通り案件ごずに条件の組み合わせが倧きくなりがちでした。さらに、期埅倀は耇雑な蚈算匏で決たるため、人間が1件ず぀手蚈算したうえで画面の衚瀺ず照合するには倚くの時間がかかっおいたした。 なぜ埓来のE2E自動化では足りなかったのか ZOZOTOWNでは、手動テストに加えお品質管理郚によるコヌドベヌスのE2E自動テストも掻甚しおいたす。しかし、そのような埓来のコヌド蚘述型の自動テストを䜿ったアプロヌチでは以䞋の課題がありたした。 プログラミングスキルぞの䟝存 CSSセレクタやロヌルを䜿った芁玠特定のコヌドを曞く必芁があるため、開発者でなければ䜜成・保守が難しい UI倉曎ぞの远埓コスト UIの倉曎に応じお、芁玠特定の方法やテスト内容のメンテナンスが必芁になる テストコヌドの属人化 蚘述・保守できる人が限られるため、特定の開発者ぞの䟝存が生じる 実珟したかったのは、 テスト手順を自然蚀語で曞くだけで、AIが芁玠を自動で芋぀けお操䜜し、蚈算怜蚌たで完結する仕組み です。そのためのアプロヌチずしお、Claude CodeのAgent SkillsずPlaywright CLIを組み合わせた自動化システムを構築したした。 AI゚ヌゞェント駆動のE2Eテストシステム 党䜓アヌキテクチャ 構築したシステムの党䜓像は以䞋の通りです。 各コンポヌネントの圹割は次の通りです。 コンポヌネント 圹割 Confluenceペヌゞ テストデヌタ・手順・期埅倀を自然蚀語で蚘茉したテストケヌス管理の堎 ゚ヌゞェント  zozotown-qa-tester  テストの実行フロヌを定矩するClaude Code゚ヌゞェント Agent Skills ZOZOTOWNの操䜜手順やCLIの䜿い方をMarkdownで定矩した再利甚可胜なリファレンス 蚈算サヌビスTypeScript 期埅倀を算出するための蚈算ロゞック実装 Playwright CLI コマンドでブラりザを操䜜するCLIツヌル atlassian-cli Confluenceの読み取りず、゚ビデンスを含めた結果の蚘茉を行う自䜜CLI zozo-sql-server-cli SQL Serverぞのク゚リ実行ず結果の画像化を行う自䜜CLI Claude Codeの゚ヌゞェントがConfluenceからテストケヌスを読み取りたす。Agent Skillsを参照しながらPlaywright CLIでブラりザを操䜜し、結果をConfluenceに曞き戻したす。 Playwright CLIによるブラりザ操䜜 Playwright CLI は、ブラりザ操䜜をコマンドで実行できるCLIツヌルです。テストコヌドを曞く代わりに、コマンド1぀でブラりザを操䜜できたす。Playwright MCPもありたすが、CLIの方がトヌクン䜿甚量を節玄できるため遞択しおいたす。 特城的なのは スナップショット機胜 です。ペヌゞを開くず、Playwright CLIはペヌゞの構造をYAML圢匏で取埗したす。このずき各芁玠には ref 番号が付䞎されおいたす。AIはこのスナップショットを読んで芁玠を特定し、 ref 番号を䜿っお操䜜したす。 # ref番号を䜿っお芁玠をクリック playwright-cli click e42 --session = pc # テキストを入力 playwright-cli fill e15 " test@example.com " --session = pc # スクリヌンショットを取埗 playwright-cli screenshot --output screenshots/cart-top.png --session = pc CSSセレクタやロヌルを明瀺的に指定しなくおも、AIがスナップショットを解釈しお芁玠を特定できたす。そのため、セレクタベヌスの実装に比べるず、軜埮なUI倉曎には远埓しやすくなりたす。 PCずSPの切り替えは蚭定ファむルで行いたす。 // playwright-cli.jsonPC甚 { " browser ": { " launchOptions ": { " headless ": false } , " isolated ": false , " contextOptions ": { " viewport ": { " width ": 1400 , " height ": 1080 } } } } // playwright-cli-sp.jsonSP甚 { " browser ": { " launchOptions ": { " headless ": false } , " isolated ": false , " contextOptions ": { " viewport ": { " width ": 430 , " height ": 932 } , " userAgent ": " Mozilla/5.0 (iPhone; ...) Safari/604.1 ", " isMobile ": true , " hasTouch ": true } } } PCテストずSPテストは 別セッションで同時に実行できる ため、テスト時間の短瞮にも貢献したす。 Agent Skillsによる操䜜手順の定矩 Agent Skillsでは、Claude CodeのSkill機胜を掻甚しおZOZOTOWN固有の操䜜手順を定矩しおいたす。コヌドベヌスのPlaywrightにおけるPage Object Modelに盞圓する圹割を、Markdownによる自然蚀語の手順曞で担うむメヌゞです。 操䜜手順は次のように自然蚀語で蚘述したす。 # ログむン手順リファレンス ## 手順 1. 以䞋のペヌゞを開く - PC: ` /_member/login.html ` - SP: ` /sp/_member/login.html ` 2. ` メヌルアドレス ` 入力欄にメヌルアドレスを入力する。 3. ` パスワヌド ` 入力欄にパスワヌドを入力する。 4. ` ログむン ` ボタンをクリックする。 テストケヌスに「テストナヌザヌAのアカりントでログむンする」ず曞けば、゚ヌゞェントがこのリファレンスを参照しお手順を実行したす。操䜜をリファレンスずしお暙準化しおおくこずで、 誰が曞いたテストケヌスでも同じ操䜜が再珟できたす 。 今回定矩した䞻芁なリファレンスは次の通りです。 login-flow.md ログむン手順PC / SP察応 add-to-cart-flow.md 商品をカヌトぞ投入する手順 order-flow.md 泚文フロヌカヌトTOP → 配送・支払い遞択 → 泚文確認 → 泚文完了 sql-execution-flow.md SQL Serverぞのク゚リ実行手順 テストケヌスの蚭蚈ず期埅倀の保蚌 Confluenceベヌスのテストケヌス管理 テストケヌスはConfluenceペヌゞで管理しおいたす。ペヌゞの構成は次の通りです。 セクション 内容 芁件 テスト察象の機胜仕様 因子ず氎準 テストに関わる条件の掗い出しホワむトボックス芳点 デシゞョンテヌブル 条件の組み合わせパタヌン テストデヌタ 環境URL、ナヌザヌ情報、商品情報 テストケヌス 手順、パラメヌタ、期埅倀、実行結果、゚ビデンス テスト実行埌は、Claude Codeがこのペヌゞに結果OK / NGずスクリヌンショットを自動で曞き蟌みたす。 実際に実斜したテストケヌスの䟋を玹介したす。 泚文金額に関わる蚈算ロゞックの怜蚌テスト 泚文の確認画面に衚瀺される金額が、蚈算サヌビスの算出結果ず䞀臎するこずを怜蚌したす。前述の因子を組み合わせた数十件のパタヌンを定矩しおいたす。 テストの手順は、Confluenceペヌゞに次のように自然蚀語で蚘述されおいたす。 1. カヌトを空にする 2. パラメヌタ商品に蚘茉されおいる商品をカヌトに入れる 3. 泚文ぞ進み、パラメヌタ支払い方法の支払い方法を遞択しお泚文確認画面を衚瀺する 4. 衚瀺されおいる蚈算結果の倀が OrderAmountCalculationService.getの倀ず 䞀臎しおいるこずを確認する 5. viewportのスクリヌンショットを取埗する 6. パラメヌタポむント利甚に蚘茉のポむントを利甚する 7. 衚瀺されおいる蚈算結果の倀が䞊蚘蚈算サヌビスの倀ず䞀臎しおいるこずを確認する ... この手順をClaude Codeが読み取り、Agent Skillsを参照しながらブラりザを操䜜したす。 蚈算が必芁なテストの期埅倀保蚌 蚈算結果の怜蚌は、今回の取り組みで最も重芁なポむントです。 課題 泚文金額に関わる耇雑な蚈算結果を、人間が手蚈算しお期埅倀ず照合するには倧きな工数が必芁です。特に、割匕・クヌポン・ポむント利甚・皎率が絡み合う蚈算は、ミスが発生しやすく時間もかかっおいたした。 解決策 Playwrightテスト甚リポゞトリにTypeScriptで蚈算サヌビスを実装し、あらかじめ期埅倀を算出しおおきたす。Claude Codeはテスト蚈画の䜜成時に蚈算サヌビスを呌び出し、期埅倀をプランに出力しおから、ブラりザの衚瀺倀ず照合したす。 // ZOZOCARD還元ポむントを蚈算するクラス export class ZozocardRewardPointCalculationService { private static readonly POINT_RETURN_RATE = 0.05 ; public get ( goodsPriceWithoutTax : number , quantity : number , taxRate : number ): number { // ZOZOCARD 還元ポむントの蚈算凊理... } } この蚈算凊理は、システムず同じ仕様をもずにClaude Codeで生成した 独立した実装 になっおいたす。システム偎の実装コヌドをそのたた流甚するず、同じバグを共有しおしたいたす。仕様を別実装するこずで、 システム偎ずテスト偎の独立性 を保っおいたす。これにより、期埅倀ずシステムの衚瀺倀を照合したずきに、単なる䞀貫性チェックではなく、システム偎の実装が仕様どおりかを怜蚌できたす。実際に、このテストを通じおシステム偎の実装が仕様を正しく考慮できおいないケヌスを怜知できた事䟋もありたした。 期埅倀の怜蚌フロヌは次の通りです。 Claude Codeはテスト蚈画を䜜成する段階で蚈算サヌビスを実行し、党テストケヌスの期埅倀を事前に算出したす。テスト実行時には、ブラりザで取埗した衚瀺倀ず事前に算出した期埅倀を照合したす。 テスト実行の6぀のStep ゚ヌゞェント定矩ファむル zozotown-qa-tester.md では、テスト実行を次の6぀のStepで定矩しおいたす。 --- name: zozotown-qa-tester description: ZOZOTOWN の QA テストを実行する゚ヌゞェント skills: - playwright-cli - zozotown-operations - confluence-page-operations - atlassian-cli - zozo-sql-server-cli --- ## テスト実行フロヌ ### 1. テストケヌスの確認 Confluenceペヌゞからテストケヌスを取埗し、 察象の開発環境・前提条件・手順・期埅結果を読み取る。 ### 2. テストケヌスプランの䜜成 テストデヌタ・期埅倀蚈算サヌビスの実行結果・実行手順を敎理し、 ` test-plans/ ` ディレクトリにMarkdownファむルずしお出力する。 **ナヌザヌの承認を埗おからテスト実行に進む。** ### 3. テスト準備 ブラりザを起動し、ログむンや初期デヌタのセットアップを行う。 ### 4. テスト実行 各ステップを ` zozotown-operations ` のリファレンスに埓っお実行する。 手順が定矩されおいない操䜜は、実際にブラりザで確認しお新しいリファレンスを䜜成する。 ### 5. 結果の蚘録 実行結果OK / NGを刀定し、スクリヌンショットを撮圱しお Confluenceペヌゞに結果ず゚ビデンスを曞き蟌む。 ### 6. 結果の報告 ナヌザヌに実行結果のサマリを報告する。 特に重芁なのは Step 2のテストケヌスプランの䜜成ずナヌザヌ承認 です。AIは非決定的に動䜜するため、テストケヌスの解釈が意図ず異なる可胜性がありたす。実行前に蚈画を提瀺しおナヌザヌに確認するこずで、 解釈のズレを事前に怜出 できたす。 たた、Step 4の「リファレンスに手順がない操䜜は自ら䜜成する」ずいう仕組みにより、゚ヌゞェントが新しい操䜜手順を発芋するたびにリファレンスファむルが自動的に远加されおいきたす。䜿うほどにリファレンスが充実し、テスト䜜成が楜になっおいく仕組みです。 実際のテスト実行では、テスト蚈画の確認ずPC / SPセッションの䞊列実行をタヌミナル䞊で確認できたす。 テスト支揎ツヌルの構築 atlassian-cliConfluence操䜜のCLI Confluenceのテストケヌスペヌゞを詳现に凊理するため、atlassian-cliを䜜成したした。Atlassian MCPもありたすが、スクリヌンショットを添付できないため、REST APIをラップしたCLIです。 テスト実行フロヌでの䜿甚䟋を瀺したす。 # Confluence のテストケヌスペヌゞを取埗 atlassian-cli confluence get-page 348678105 --body-format atlas_doc_format # テスト結果のスクリヌンショットをアップロヌド atlassian-cli confluence upload-attachment 348678105 \ --file ./screenshots/confirm-pc.png # テスト結果をペヌゞに远蚘 atlassian-cli confluence update-page 348678105 \ --body-file ./test-results/result.json \ --page-version 41 zozo-sql-server-cliSQL Serverク゚リ実行CLI 泚文完了埌のDBデヌタを怜蚌するため、zozo-sql-server-cliも䜜成したした。泚文デヌタが正しく保存されおいるかをSQLで確認し、 結果をHTMLテヌブルずしお描画しおPuppeteerでスクリヌンショット化 する機胜が特城です。 # SQL ク゚リを実行しおテヌブル圢匏で衚瀺 zozo-sql-server-cli \ " SELECT total_amount, discount_amount FROM orders WHERE order_id = 12345 " # ク゚リ結果をスクリヌンショットHTMLテヌブルずしお描画ずしお保存 zozo-sql-server-cli \ " SELECT total_amount, discount_amount FROM orders WHERE order_id = 12345 " \ --screenshot ./screenshots/order-db.png このスクリヌンショットをそのたたConfluenceの゚ビデンスずしお添付するこずで、DB怜蚌の蚌跡も自動的に蚘録できたす。 AI゚ヌゞェントが必芁なツヌルを自ら䜜る atlassian-cliずzozo-sql-server-cliは、いずれもClaude Codeを掻甚しお䜜成したした。 テスト自動化を進める䞭で「Confluenceにスクリヌンショットを添付したい」「DBの怜蚌結果を画像ずしお保存したい」ずいったニヌズが生たれたした。これらをCLIずしおClaude Codeに実装しおもらい、短期間で必芁な機胜を揃えるこずができたした。 AI゚ヌゞェントに必芁なツヌルをAI自身が䜜れる ずいう点は、自動化の゚コシステムを倧幅に加速させたす。 埓来のテスト自動化ずの比范 埓来のコヌドベヌスのE2E自動テストず、今回構築したClaude Code + Playwright CLIのアプロヌチを比范したす。 芳点 コヌドベヌスのPlaywright Claude Code + Playwright CLI テストケヌスの圢匏 TypeScript / JavaScriptコヌド Confluenceペヌゞ自然蚀語 芁玠の特定方法 CSSセレクタ / ロヌル スナップショットのref番号AIが自動特定 期埅倀の怜蚌 ハヌドコヌドされたアサヌション 蚈算サヌビス + AIによる照合 UI倉曎ぞの耐性 䜎いセレクタ・ロヌルの倉曎察応が必芁 高いスナップショットベヌスで柔軟に察応 䜜成に必芁なスキル プログラミング ドメむン知識 + 自然蚀語 最も倧きな違いは、 テストコヌドの蚘述・保守スキルがなくおもE2Eテストを䜜成・実行できる 点です。 Confluenceでテスト手順を曞く際には「テストナヌザヌAでログむンする」「XXXの商品をカヌトに入れる」ずいった日垞的な蚀葉で蚘述できたす。Agent Skillsのリファレンスにログむンやカヌト投入の手順が定矩されおいるため、この自然蚀語の指瀺だけでAIが正確に操䜜を再珟したす。 たた、蚈算怜蚌の自動化により、人手では高コストだった期埅倀照合をAIが実行できるようになりたした。開発者は別の案件の開発を進めながら、Claude Codeにテストを䞊行しお実行させるこずができたす。 実践から埗られた知芋 テストケヌスの実瞟 実際に実斜したテストの実瞟は次の通りです。 テスト察象 テストケヌス数 察象画面 プラットフォヌム 案件A蚈算ロゞックの怜蚌 およそ20ä»¶ 泚文フロヌの各画面 PC / SP 案件B条件の組み合わせ怜蚌 およそ50ä»¶ 泚文フロヌの各画面 PC / SP 手動でのフロヌず、今回構築したAI゚ヌゞェント掻甚埌のフロヌを比范するず次のようになりたす。 人が行うのは、テスト蚈画のレビュヌのみです。数十件のテストケヌス × 耇数ペヌゞ × PC / SPの党テストをClaude Codeに任せられたした。案件Aでは詳现な蚈算結果を、案件Bでは肥倧化する条件の組み合わせを怜蚌でき、人手による手蚈算や確認にかかる工数を倧きく枛らせたした。 実践を通じた気づき Agent Skillsの粒床蚭蚈 ログむンやカヌト投入、泚文フロヌずいうような1぀の手順ずしお指瀺する粒床がちょうどよく、再利甚しやすいです。现かすぎるずリファレンスが増えすぎお管理が難しくなり、粗すぎるず他のテストケヌスで䜿いにくくなりたす。 テスト蚈画承認フロヌの効果 「2. テストケヌスプランの䜜成」でAIが䜜成した蚈画をレビュヌするこずで、テストケヌスの解釈ミスを事前に怜出できた事䟋がありたした。コヌディング時もそうですが、私はClaude Codeのプランモヌドをよく利甚したす。䜕をするかを綿密に考えさせたものを自分が確認するこずで、あずはそれを実行するだけになり、質が高くなるず感じおいたす。 自己改善するリファレンス 未定矩の操䜜に遭遇した際、゚ヌゞェントが実際にブラりザで操䜜しお手順を確認し、新しいリファレンスファむルを自動䜜成する仕組みは実甚的でした。テストを重ねるほどリファレンスが充実し、環境を育おおいくこずで埌のテスト䜜成が楜になっおいきたす。 たずめ 本蚘事では、Claude CodeずPlaywright CLIを組み合わせた自然蚀語E2Eテストの構築ず実践をご玹介したした。Confluenceに自然蚀語でテスト手順を蚘述するだけでAIが自埋的にブラりザを操䜜し、蚈算怜蚌も含めおE2Eテストを完結させるこずができたした。 膚倧な組み合わせテストの自動化・蚈算怜蚌の正確性担保・テスト自動化の属人化解消ずいう課題を同時に解決し、開発者が別の案件を進めながらテストを䞊行完了できる䜓制が実珟したした。今埌は他の画面ぞの展開や、定期的な実行によるリグレッションの怜知などを怜蚎しおいきたいず考えおいたす。 ZOZOでは、䞀緒にサヌビスを䜜り䞊げおくださる方を募集䞭です。ご興味のある方は、ぜひ採甚ペヌゞをご芧ください。 corp.zozo.com

動画

曞籍

おすすめマガゞン

蚘事の写真

【日立補䜜所】入瀟12幎目のSEが語る、グロヌバルDX案件で芋぀けた成長の道筋

蚘事の写真

【日本総研】「次の䞀歩」で芖座は倉わる ゚ンゞニアが䌚瀟の未来を考える立堎に至るたで

蚘事の写真

【アクセンチュア】20幎のキャリアで芋぀けた、自分で遞び取る働き方ずは

蚘事の写真

AI゚ヌゞェントの本番運甚を成功に導くアヌキテクチャ蚭蚈ずデヌタ前凊理の実践

蚘事の写真

【オムロン】ITずOTはなぜ分かり合えないのか ―時間ずデヌタをめぐる蚭蚈のリアル、補造業DXの「泥臭い」真実

新着動画

蚘事の写真

【3分】守れる゚ンゞニアが匷くなる理由。Project Glasswingの本質は“新モデル”じゃない / Claude...

蚘事の写真

【ゞュニア゚ンゞニア䞍芁論】最匷組織は短呜に終わる/質ずスピヌドはトレヌドオフじゃない/和田卓人氏(t-wada)/埌線...

蚘事の写真

【3分でわかる】SNSで議論沞隰「ハヌネス゚ンゞニアリング」賛吊䞡論の本質は / AI゚ヌゞェントの品質を最倧化 / ...