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
77
最近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
190
Other Decks in Programming
See All in Programming
Building AI with AI
inesmontani
PRO
1
260
例外処理を理解して、設計段階からエラーを見つけやすく、起こりにくく #phpconfuk
kajitack
12
6.4k
Eloquentを使ってどこまでコードの治安を保てるのか?を新人が考察してみた
itokoh0405
0
3.2k
OSS開発者の憂鬱
yusukebe
12
5.9k
手軽に積ん読を増やすには?/読みたい本と付き合うには?
o0h
PRO
1
110
歴史から学ぶ「Why PHP?」 PHPを書く理由を改めて理解する / Learning from History: “Why PHP?” Rediscovering the Reasons for Writing PHP
seike460
PRO
0
160
Vueで学ぶデータ構造入門 リンクリストとキューでリアクティビティを捉える / Vue Data Structures: Linked Lists and Queues for Reactivity
konkarin
1
340
CSC509 Lecture 11
javiergs
PRO
0
310
AWS CDKの推しポイントN選
akihisaikeda
1
160
Reactive Thinking with Signals and the new Resource API
manfredsteyer
PRO
0
110
生成AIを活用したリファクタリング実践 ~コードスメルをなくすためのアプローチ
raedion
0
120
Level up your Gemini CLI - D&D Style!
palladius
1
110
Featured
See All Featured
Making the Leap to Tech Lead
cromwellryan
135
9.6k
The Web Performance Landscape in 2024 [PerfNow 2024]
tammyeverts
11
940
Imperfection Machines: The Place of Print at Facebook
scottboms
269
13k
Automating Front-end Workflow
addyosmani
1371
200k
We Have a Design System, Now What?
morganepeng
54
7.9k
Typedesign – Prime Four
hannesfritz
42
2.9k
Context Engineering - Making Every Token Count
addyosmani
9
410
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
34
2.5k
Music & Morning Musume
bryan
46
7k
Side Projects
sachag
455
43k
Being A Developer After 40
akosma
91
590k
Improving Core Web Vitals using Speculation Rules API
sergeychernyshev
21
1.3k
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をラップして使う実装
ありがとうございました!