Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
最近Goで作っているツールたちを晒します!
Search
Tatsunori Sunagawa
September 23, 2018
Programming
0
76
最近Goで作っているツールたちを晒します!
Gopher道場#3 LT大会での発表資料です。Youtubeのtranscript取得、テストの際のHTTP Serverのモックの方法について話しました。
Tatsunori Sunagawa
September 23, 2018
Tweet
Share
More Decks by Tatsunori Sunagawa
See All by Tatsunori Sunagawa
Google Cloud Spanner FAQ
pchatsu
2
180
Other Decks in Programming
See All in Programming
なぜ「共通化」を考え、失敗を繰り返すのか
rinchoku
1
570
システム成長を止めない!本番無停止テーブル移行の全貌
sakawe_ee
1
140
「ElixirでIoT!!」のこれまでとこれから
takasehideki
0
370
CursorはMCPを使った方が良いぞ
taigakono
1
190
Systèmes distribués, pour le meilleur et pour le pire - BreizhCamp 2025 - Conférence
slecache
0
110
PicoRuby on Rails
makicamel
2
110
LINEヤフー データグループ紹介
lycorp_recruit_jp
0
1k
既存デザインを変更せずにタップ領域を広げる方法
tahia910
1
240
20250628_非エンジニアがバイブコーディングしてみた
ponponmikankan
0
470
コードの90%をAIが書く世界で何が待っているのか / What awaits us in a world where 90% of the code is written by AI
rkaga
47
31k
Cursor AI Agentと伴走する アプリケーションの高速リプレイス
daisuketakeda
1
130
なぜ適用するか、移行して理解するClean Architecture 〜構造を超えて設計を継承する〜 / Why Apply, Migrate and Understand Clean Architecture - Inherit Design Beyond Structure
seike460
PRO
1
700
Featured
See All Featured
jQuery: Nuts, Bolts and Bling
dougneiner
63
7.8k
Chrome DevTools: State of the Union 2024 - Debugging React & Beyond
addyosmani
7
700
Measuring & Analyzing Core Web Vitals
bluesmoon
7
490
Connecting the Dots Between Site Speed, User Experience & Your Business [WebExpo 2025]
tammyeverts
5
220
Producing Creativity
orderedlist
PRO
346
40k
Scaling GitHub
holman
459
140k
Raft: Consensus for Rubyists
vanstee
140
7k
Building Better People: How to give real-time feedback that sticks.
wjessup
367
19k
Building a Modern Day E-commerce SEO Strategy
aleyda
42
7.3k
Code Review Best Practice
trishagee
68
18k
Site-Speed That Sticks
csswizardry
10
660
How to train your dragon (web standard)
notwaldorf
94
6.1k
Transcript
最近Goで作っているツールたちを晒します! @pchatsu 2018/09/19 gopher道場#3 LT大会
自己紹介 @pchatsu(読みはぴーちゃつ) • 言語 ◦ Perl, Ruby, Javaでサーバーサイド、C++でクライアントサイド • 興味
◦ サーバーサイド。GCP (Cloud Spannerが好き)
今回作ったもの • Youtubeの字幕をダウンロードしてくるコマンドラインツール • https://github.com/pchatsu/youtubets これを1動画分まとめて取得!
youtubets • 海外のカンファレンス動画を見る前に、文章で読んでおきたいという動機 • 自動翻訳の字幕には未対応(対応させたい!)
Gopher道場での成長を 入門お題のtail比で見てみる
0 → 5 struct数 男気main.goから脱却することができました
0% → 82.5% テストC0カバレッジ テスト?なにそれいるの?からちゃんとテスト書くマンになりました
tenntennさん、運営の皆様 ありがとうございました!
youtubetsで学んだことをひとつだけ
net/http/httptest • 資料P318あたりにも出ていたhttp通信のテスト用package • 今回はAPI Serverのスタブ化に使った youtubets API Server Request
Response これをすげ替えて、テスト時に固定の レスポンスを返すようにしたい。
net/http/httptest func TestCmd_Run(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter,
r *http.Request) { switch r.URL.String() { case "/timedtext?lang=en&name=test_en&v=test0001": w.Header().Set("content-Type", "text/xml") fmt.Fprintf(w, transcriptXML) return case "/timedtext?lang=en&name=test_en&v=test0003": ... } }, )) defer ts.Close() youtubets.Domain = ts.URL
net/http/httptest func TestCmd_Run(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter,
r *http.Request) { switch r.URL.String() { case "/timedtext?lang=en&name=test_en&v=test0001": w.Header().Set("content-Type", "text/xml") fmt.Fprintf(w, transcriptXML) return case "/timedtext?lang=en&name=test_en&v=test0003": ... } }, )) defer ts.Close() youtubets.Domain = ts.URL HandlerFuncを登録して Serverを立ち上げる
net/http/httptest func TestCmd_Run(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter,
r *http.Request) { switch r.URL.String() { case "/timedtext?lang=en&name=test_en&v=test0001": w.Header().Set("content-Type", "text/xml") fmt.Fprintf(w, transcriptXML) return case "/timedtext?lang=en&name=test_en&v=test0003": ... } }, )) defer ts.Close() youtubets.Domain = ts.URL リクエストが来たURLでハンドリングして、レス ポンスを返す ※transscriptXMLはXML文字列を持っている
net/http/httptest func TestCmd_Run(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter,
r *http.Request) { switch r.URL.String() { case "/timedtext?lang=en&name=test_en&v=test0001": w.Header().Set("content-Type", "text/xml") fmt.Fprintf(w, transcriptXML) return case "/timedtext?lang=en&name=test_en&v=test0003": ... } }, )) defer ts.Close() youtubets.Domain = ts.URL ts.URLのドメインにリクエストするようにする これにより、API Serverを入れ替えられる
net/http/httptest func TestCmd_Run(t *testing.T) { ts := httptest.NewServer(http.HandlerFunc( func(w http.ResponseWriter,
r *http.Request) { switch r.URL.String() { case "/timedtext?lang=en&name=test_en&v=test0001": w.Header().Set("content-Type", "text/xml") fmt.Fprintf(w, transcriptXML) return case "/timedtext?lang=en&name=test_en&v=test0003": ... } }, )) defer ts.Close() youtubets.Domain = ts.URL Getパラメータの順序違ったら 別のURLと認識されるけど大丈夫?
url.Values • URLのクエリパラメータ組み立てに使用 • GoDoc https://godoc.org/net/url#Values • Encode時にクエリパラメータのkey順にして出力してくれるので大丈夫 ◦ Encode
encodes the values into “URL encoded” form ("bar=baz&foo=quux") sorted by key.
作成中のツール • Cloud Spannerのdatabase/sql/driver ◦ https://github.com/pchatsu/go-spanner-driver ◦ 現状、他のDBと互換性を持たせたいニーズはあまりないが、お勉強も兼ねて作っている ◦ まだ実験段階
▪ https://github.com/GoogleCloudPlatform/google-cloud-go/issues/513 にあるように、純 正SDKをラップして使う実装
ありがとうございました!